chromadb 3.1.8 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chromadb.d.ts +230 -1
- package/dist/chromadb.legacy-esm.js +293 -3
- package/dist/chromadb.mjs +293 -3
- package/dist/chromadb.mjs.map +1 -1
- package/dist/cjs/chromadb.cjs +300 -3
- package/dist/cjs/chromadb.cjs.map +1 -1
- package/dist/cjs/chromadb.d.cts +230 -1
- package/package.json +6 -6
- package/src/api/sdk.gen.ts +11 -1
- package/src/api/types.gen.ts +70 -0
- package/src/collection.ts +35 -7
- package/src/execution/expression/groupBy.ts +155 -0
- package/src/execution/expression/index.ts +10 -0
- package/src/execution/expression/search.ts +19 -0
- package/src/schema.ts +198 -1
- package/src/types.ts +21 -1
package/dist/chromadb.d.ts
CHANGED
|
@@ -86,6 +86,12 @@ type HnswIndexConfig = {
|
|
|
86
86
|
sync_threshold?: number | null;
|
|
87
87
|
};
|
|
88
88
|
type Include = 'distances' | 'documents' | 'embeddings' | 'metadatas' | 'uris';
|
|
89
|
+
type IndexStatusResponse = {
|
|
90
|
+
num_indexed_ops: number;
|
|
91
|
+
num_unindexed_ops: number;
|
|
92
|
+
op_indexing_progress: number;
|
|
93
|
+
total_ops: number;
|
|
94
|
+
};
|
|
89
95
|
type IntInvertedIndexConfig$1 = {
|
|
90
96
|
[key: string]: never;
|
|
91
97
|
};
|
|
@@ -191,6 +197,10 @@ type Schema$1 = {
|
|
|
191
197
|
keys: {
|
|
192
198
|
[key: string]: ValueTypes$1;
|
|
193
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* ID of the attached function that created this output collection (if applicable)
|
|
202
|
+
*/
|
|
203
|
+
source_attached_function_id?: string | null;
|
|
194
204
|
};
|
|
195
205
|
type SearchPayload = {
|
|
196
206
|
filter?: {
|
|
@@ -199,6 +209,12 @@ type SearchPayload = {
|
|
|
199
209
|
[key: string]: unknown;
|
|
200
210
|
};
|
|
201
211
|
};
|
|
212
|
+
group_by?: {
|
|
213
|
+
aggregate?: {
|
|
214
|
+
[key: string]: unknown;
|
|
215
|
+
};
|
|
216
|
+
keys?: Array<string>;
|
|
217
|
+
};
|
|
202
218
|
limit?: {
|
|
203
219
|
limit?: number;
|
|
204
220
|
offset?: number;
|
|
@@ -356,6 +372,19 @@ type VectorIndexType$1 = {
|
|
|
356
372
|
* User identity information including tenant and database access.
|
|
357
373
|
*/
|
|
358
374
|
type UserIdentity = GetUserIdentityResponse;
|
|
375
|
+
/**
|
|
376
|
+
* Read level controls whether queries read from the write-ahead log (WAL).
|
|
377
|
+
*
|
|
378
|
+
* - INDEX_AND_WAL: Read from both the compacted index and the WAL.
|
|
379
|
+
* All committed writes will be visible. This is the default.
|
|
380
|
+
* - INDEX_ONLY: Read only from the compacted index, skipping the WAL.
|
|
381
|
+
* Recent writes that haven't been compacted may not be visible, but queries are faster.
|
|
382
|
+
*/
|
|
383
|
+
declare const ReadLevel: {
|
|
384
|
+
readonly INDEX_AND_WAL: "index_and_wal";
|
|
385
|
+
readonly INDEX_ONLY: "index_only";
|
|
386
|
+
};
|
|
387
|
+
type ReadLevel = (typeof ReadLevel)[keyof typeof ReadLevel];
|
|
359
388
|
|
|
360
389
|
/**
|
|
361
390
|
* Metadata that can be associated with a collection.
|
|
@@ -557,6 +586,10 @@ declare class QueryResult<TMeta extends Metadata = Metadata> {
|
|
|
557
586
|
*/
|
|
558
587
|
rows(): QueryRowResult<TMeta>[][];
|
|
559
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Re-export IndexStatusResponse type for external use
|
|
591
|
+
*/
|
|
592
|
+
type IndexingStatus = IndexStatusResponse;
|
|
560
593
|
|
|
561
594
|
/**
|
|
562
595
|
* Supported vector space types.
|
|
@@ -843,27 +876,76 @@ declare const Log: (input: RankInput) => RankExpression;
|
|
|
843
876
|
declare const Max: (...inputs: RankInput[]) => RankExpression;
|
|
844
877
|
declare const Min: (...inputs: RankInput[]) => RankExpression;
|
|
845
878
|
|
|
879
|
+
interface MinKJSON {
|
|
880
|
+
keys: string[];
|
|
881
|
+
k: number;
|
|
882
|
+
}
|
|
883
|
+
interface MaxKJSON {
|
|
884
|
+
keys: string[];
|
|
885
|
+
k: number;
|
|
886
|
+
}
|
|
887
|
+
type AggregateJSON = {
|
|
888
|
+
$min_k: MinKJSON;
|
|
889
|
+
} | {
|
|
890
|
+
$max_k: MaxKJSON;
|
|
891
|
+
};
|
|
892
|
+
type AggregateInput = Aggregate | AggregateJSON;
|
|
893
|
+
declare abstract class Aggregate {
|
|
894
|
+
abstract toJSON(): AggregateJSON;
|
|
895
|
+
static from(input: AggregateInput): Aggregate;
|
|
896
|
+
static minK(keys: (Key | string)[], k: number): MinK;
|
|
897
|
+
static maxK(keys: (Key | string)[], k: number): MaxK;
|
|
898
|
+
}
|
|
899
|
+
declare class MinK extends Aggregate {
|
|
900
|
+
readonly keys: Key[];
|
|
901
|
+
readonly k: number;
|
|
902
|
+
constructor(keys: Key[], k: number);
|
|
903
|
+
toJSON(): AggregateJSON;
|
|
904
|
+
}
|
|
905
|
+
declare class MaxK extends Aggregate {
|
|
906
|
+
readonly keys: Key[];
|
|
907
|
+
readonly k: number;
|
|
908
|
+
constructor(keys: Key[], k: number);
|
|
909
|
+
toJSON(): AggregateJSON;
|
|
910
|
+
}
|
|
911
|
+
interface GroupByJSON {
|
|
912
|
+
keys: string[];
|
|
913
|
+
aggregate: AggregateJSON;
|
|
914
|
+
}
|
|
915
|
+
type GroupByInput = GroupBy | GroupByJSON;
|
|
916
|
+
declare class GroupBy {
|
|
917
|
+
readonly keys: Key[];
|
|
918
|
+
readonly aggregate: Aggregate;
|
|
919
|
+
constructor(keys: Key[], aggregate: Aggregate);
|
|
920
|
+
static from(input: GroupByInput | undefined): GroupBy | undefined;
|
|
921
|
+
toJSON(): GroupByJSON;
|
|
922
|
+
}
|
|
923
|
+
|
|
846
924
|
interface SearchInit {
|
|
847
925
|
where?: WhereInput;
|
|
848
926
|
rank?: RankInput;
|
|
927
|
+
groupBy?: GroupByInput;
|
|
849
928
|
limit?: LimitInput;
|
|
850
929
|
select?: SelectInput;
|
|
851
930
|
}
|
|
852
931
|
declare class Search {
|
|
853
932
|
private _where?;
|
|
854
933
|
private _rank?;
|
|
934
|
+
private _groupBy?;
|
|
855
935
|
private _limit;
|
|
856
936
|
private _select;
|
|
857
937
|
constructor(init?: SearchInit);
|
|
858
938
|
private clone;
|
|
859
939
|
where(where?: WhereInput): Search;
|
|
860
940
|
rank(rank?: RankInput): Search;
|
|
941
|
+
groupBy(groupBy?: GroupByInput): Search;
|
|
861
942
|
limit(limit?: LimitInput, offset?: number): Search;
|
|
862
943
|
select(keys?: SelectInput): Search;
|
|
863
944
|
select(...keys: SelectKeyInput[]): Search;
|
|
864
945
|
selectAll(): Search;
|
|
865
946
|
get whereClause(): WhereExpression | undefined;
|
|
866
947
|
get rankExpression(): RankExpression | undefined;
|
|
948
|
+
get groupByConfig(): GroupBy | undefined;
|
|
867
949
|
get limitConfig(): Limit;
|
|
868
950
|
get selectConfig(): Select;
|
|
869
951
|
toPayload(): SearchPayload;
|
|
@@ -891,6 +973,116 @@ declare class SearchResult {
|
|
|
891
973
|
|
|
892
974
|
declare const DOCUMENT_KEY = "#document";
|
|
893
975
|
declare const EMBEDDING_KEY = "#embedding";
|
|
976
|
+
/**
|
|
977
|
+
* Supported cloud providers for customer-managed encryption keys.
|
|
978
|
+
* Currently only Google Cloud Platform (GCP) is supported.
|
|
979
|
+
*/
|
|
980
|
+
declare enum CmekProvider {
|
|
981
|
+
GCP = "gcp"
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Customer-managed encryption key (CMEK) for collection data encryption.
|
|
985
|
+
*
|
|
986
|
+
* CMEK allows you to use your own encryption keys managed by cloud providers'
|
|
987
|
+
* key management services (KMS) instead of default provider-managed keys. This
|
|
988
|
+
* gives you greater control over key lifecycle, access policies, and audit logging.
|
|
989
|
+
*
|
|
990
|
+
* @example
|
|
991
|
+
* ```typescript
|
|
992
|
+
* // Create a CMEK for GCP
|
|
993
|
+
* const cmek = Cmek.gcp(
|
|
994
|
+
* "projects/my-project/locations/us-central1/keyRings/my-ring/cryptoKeys/my-key"
|
|
995
|
+
* );
|
|
996
|
+
*
|
|
997
|
+
* // Validate the resource name format
|
|
998
|
+
* if (cmek.validatePattern()) {
|
|
999
|
+
* console.log("Valid CMEK format");
|
|
1000
|
+
* }
|
|
1001
|
+
*
|
|
1002
|
+
* // Use in collection schema
|
|
1003
|
+
* const schema = new Schema();
|
|
1004
|
+
* schema.setCmek(cmek);
|
|
1005
|
+
* ```
|
|
1006
|
+
*
|
|
1007
|
+
* @note Pattern validation only checks format correctness. It does not verify
|
|
1008
|
+
* that the key exists or is accessible. Key permissions and access control
|
|
1009
|
+
* must be configured separately in your cloud provider's console.
|
|
1010
|
+
*/
|
|
1011
|
+
declare class Cmek {
|
|
1012
|
+
private static readonly GCP_PATTERN;
|
|
1013
|
+
readonly provider: CmekProvider;
|
|
1014
|
+
readonly resource: string;
|
|
1015
|
+
private constructor();
|
|
1016
|
+
/**
|
|
1017
|
+
* Create a CMEK instance for Google Cloud Platform.
|
|
1018
|
+
*
|
|
1019
|
+
* @param resource - GCP Cloud KMS resource name in the format:
|
|
1020
|
+
* projects/{project-id}/locations/{location}/keyRings/{key-ring}/cryptoKeys/{key-name}
|
|
1021
|
+
*
|
|
1022
|
+
* @returns A new CMEK instance configured for GCP
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```typescript
|
|
1026
|
+
* const cmek = Cmek.gcp(
|
|
1027
|
+
* "projects/my-project/locations/us-central1/keyRings/my-ring/cryptoKeys/my-key"
|
|
1028
|
+
* );
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
static gcp(resource: string): Cmek;
|
|
1032
|
+
/**
|
|
1033
|
+
* Validate the CMEK resource name format.
|
|
1034
|
+
*
|
|
1035
|
+
* Validates that the resource name matches the expected pattern for the
|
|
1036
|
+
* provider. This is a format check only and does not verify that the key
|
|
1037
|
+
* exists or that you have access to it.
|
|
1038
|
+
*
|
|
1039
|
+
* For GCP, the expected format is:
|
|
1040
|
+
* projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}
|
|
1041
|
+
*
|
|
1042
|
+
* @returns true if the resource name format is valid, false otherwise
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```typescript
|
|
1046
|
+
* const cmek = Cmek.gcp("projects/p/locations/l/keyRings/r/cryptoKeys/k");
|
|
1047
|
+
* cmek.validatePattern(); // Returns true
|
|
1048
|
+
*
|
|
1049
|
+
* const badCmek = Cmek.gcp("invalid-format");
|
|
1050
|
+
* badCmek.validatePattern(); // Returns false
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
1053
|
+
validatePattern(): boolean;
|
|
1054
|
+
/**
|
|
1055
|
+
* Serialize CMEK to object format for API transport.
|
|
1056
|
+
*
|
|
1057
|
+
* Returns an object with the provider variant as the key and resource as the value.
|
|
1058
|
+
*
|
|
1059
|
+
* @returns Object containing the provider variant and resource identifier
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```typescript
|
|
1063
|
+
* const cmek = Cmek.gcp("projects/p/locations/l/keyRings/r/cryptoKeys/k");
|
|
1064
|
+
* cmek.toJSON();
|
|
1065
|
+
* // Returns: { gcp: 'projects/p/locations/l/keyRings/r/cryptoKeys/k' }
|
|
1066
|
+
* ```
|
|
1067
|
+
*/
|
|
1068
|
+
toJSON(): Record<string, unknown>;
|
|
1069
|
+
/**
|
|
1070
|
+
* Deserialize CMEK from object format.
|
|
1071
|
+
*
|
|
1072
|
+
* Expects the provider variant as the key and resource as the value.
|
|
1073
|
+
*
|
|
1074
|
+
* @param data - Object containing provider variant and resource
|
|
1075
|
+
* @returns Deserialized CMEK instance
|
|
1076
|
+
* @throws Error if the provider is unsupported or data is malformed
|
|
1077
|
+
*
|
|
1078
|
+
* @example
|
|
1079
|
+
* ```typescript
|
|
1080
|
+
* const data = { gcp: 'projects/p/locations/l/keyRings/r/cryptoKeys/k' };
|
|
1081
|
+
* const cmek = Cmek.fromJSON(data);
|
|
1082
|
+
* ```
|
|
1083
|
+
*/
|
|
1084
|
+
static fromJSON(data: Record<string, unknown>): Cmek;
|
|
1085
|
+
}
|
|
894
1086
|
declare class FtsIndexConfig {
|
|
895
1087
|
readonly type = "FtsIndexConfig";
|
|
896
1088
|
}
|
|
@@ -1004,10 +1196,42 @@ declare class ValueTypes {
|
|
|
1004
1196
|
}
|
|
1005
1197
|
type IndexConfig = FtsIndexConfig | VectorIndexConfig | SparseVectorIndexConfig | StringInvertedIndexConfig | IntInvertedIndexConfig | FloatInvertedIndexConfig | BoolInvertedIndexConfig;
|
|
1006
1198
|
type JsonDict = Record<string, any>;
|
|
1199
|
+
/**
|
|
1200
|
+
* Collection schema for configuring indexes and encryption.
|
|
1201
|
+
*
|
|
1202
|
+
* The schema controls how data is indexed and can optionally specify
|
|
1203
|
+
* customer-managed encryption keys (CMEK) for data at rest.
|
|
1204
|
+
*
|
|
1205
|
+
* @example
|
|
1206
|
+
* ```typescript
|
|
1207
|
+
* const schema = new Schema();
|
|
1208
|
+
* // Optionally add CMEK
|
|
1209
|
+
* schema.setCmek(Cmek.gcp("projects/p/locations/l/keyRings/r/cryptoKeys/k"));
|
|
1210
|
+
* ```
|
|
1211
|
+
*/
|
|
1007
1212
|
declare class Schema {
|
|
1008
1213
|
defaults: ValueTypes;
|
|
1009
1214
|
keys: Record<string, ValueTypes>;
|
|
1215
|
+
cmek: Cmek | null;
|
|
1010
1216
|
constructor();
|
|
1217
|
+
/**
|
|
1218
|
+
* Set the customer-managed encryption key for this collection.
|
|
1219
|
+
*
|
|
1220
|
+
* CMEK allows you to use your own encryption keys managed by cloud providers'
|
|
1221
|
+
* key management services instead of default provider-managed keys.
|
|
1222
|
+
*
|
|
1223
|
+
* @param cmek - CMEK instance or null to remove encryption
|
|
1224
|
+
* @returns this for method chaining
|
|
1225
|
+
*
|
|
1226
|
+
* @example
|
|
1227
|
+
* ```typescript
|
|
1228
|
+
* const schema = new Schema();
|
|
1229
|
+
* schema.setCmek(Cmek.gcp(
|
|
1230
|
+
* "projects/my-project/locations/us-central1/keyRings/my-ring/cryptoKeys/my-key"
|
|
1231
|
+
* ));
|
|
1232
|
+
* ```
|
|
1233
|
+
*/
|
|
1234
|
+
setCmek(cmek: Cmek | null): this;
|
|
1011
1235
|
createIndex(config?: IndexConfig, key?: string): this;
|
|
1012
1236
|
deleteIndex(config?: IndexConfig, key?: string): this;
|
|
1013
1237
|
serializeToJSON(): Schema$1;
|
|
@@ -1442,6 +1666,11 @@ interface Collection {
|
|
|
1442
1666
|
* @returns Promise resolving to column-major search results
|
|
1443
1667
|
*/
|
|
1444
1668
|
search(searches: SearchLike | SearchLike[]): Promise<SearchResult>;
|
|
1669
|
+
/**
|
|
1670
|
+
* Gets the indexing status of the collection.
|
|
1671
|
+
* @returns Promise resolving to indexing status information
|
|
1672
|
+
*/
|
|
1673
|
+
getIndexingStatus(): Promise<IndexingStatus>;
|
|
1445
1674
|
}
|
|
1446
1675
|
|
|
1447
1676
|
declare function withChroma(userNextConfig?: any): any;
|
|
@@ -1661,4 +1890,4 @@ declare class ChromaRateLimitError extends Error {
|
|
|
1661
1890
|
}
|
|
1662
1891
|
declare function createErrorByType(type: string, message: string): InvalidCollectionError | InvalidArgumentError | undefined;
|
|
1663
1892
|
|
|
1664
|
-
export { Abs, AdminClient, type AdminClientArgs, AdminCloudClient, type AnyEmbeddingFunction, type BaseRecordSet, BoolInvertedIndexConfig, BoolInvertedIndexType, BoolValueType, ChromaClient, type ChromaClientArgs, ChromaClientError, ChromaConnectionError, ChromaError, ChromaForbiddenError, ChromaNotFoundError, ChromaQuotaExceededError, ChromaRateLimitError, ChromaServerError, ChromaUnauthorizedError, ChromaUniqueError, ChromaValueError, CloudClient, type Collection, type CollectionConfiguration, type CollectionMetadata, type CreateCollectionConfiguration, DOCUMENT_KEY, Div, EMBEDDING_KEY, type EmbeddingFunction, type EmbeddingFunctionClass, type EmbeddingFunctionSpace, Exp, FloatInvertedIndexConfig, FloatInvertedIndexType, FloatListValueType, FloatValueType, FtsIndexConfig, FtsIndexType, GetResult, type HNSWConfiguration, IncludeEnum, type IndexConfig, IntInvertedIndexConfig, IntInvertedIndexType, IntValueType, InvalidArgumentError, InvalidCollectionError, K, Key, type KeyFactory, Knn, type KnnOptions, Limit, type LimitInput, type LimitOptions, type ListDatabasesArgs, Log, Max, type Metadata, Min, Mul, type PreparedInsertRecordSet, type PreparedRecordSet, type QueryRecordSet, QueryResult, type QueryRowResult, RankExpression, type RankInput, type RankLiteral, type RecordSet, Rrf, type RrfOptions, Schema, Search, type SearchInit, type SearchLike, SearchResult, type SearchResultRow, Select, type SelectInput, type SelectKeyInput, type SparseEmbeddingFunction, type SparseEmbeddingFunctionClass, type SparseVector, SparseVectorIndexConfig, type SparseVectorIndexConfigOptions, SparseVectorIndexType, SparseVectorValueType, StringInvertedIndexConfig, StringInvertedIndexType, StringValueType, Sub, Sum, type UpdateCollectionConfiguration, type UpdateHNSWConfiguration, type UpdateSPANNConfiguration, type UserIdentity, Val, ValueTypes, VectorIndexConfig, type VectorIndexConfigOptions, VectorIndexType, type Where, type WhereDocument, WhereExpression, type WhereInput, type WhereJSON, baseRecordSetFields, createErrorByType, getDefaultEFConfig, getEmbeddingFunction, getSparseEmbeddingFunction, knownEmbeddingFunctions, knownSparseEmbeddingFunctions, processCreateCollectionConfig, processUpdateCollectionConfig, recordSetFields, registerEmbeddingFunction, registerSparseEmbeddingFunction, serializeEmbeddingFunction, toSearch, withChroma };
|
|
1893
|
+
export { Abs, AdminClient, type AdminClientArgs, AdminCloudClient, Aggregate, type AggregateInput, type AggregateJSON, type AnyEmbeddingFunction, type BaseRecordSet, BoolInvertedIndexConfig, BoolInvertedIndexType, BoolValueType, ChromaClient, type ChromaClientArgs, ChromaClientError, ChromaConnectionError, ChromaError, ChromaForbiddenError, ChromaNotFoundError, ChromaQuotaExceededError, ChromaRateLimitError, ChromaServerError, ChromaUnauthorizedError, ChromaUniqueError, ChromaValueError, CloudClient, Cmek, CmekProvider, type Collection, type CollectionConfiguration, type CollectionMetadata, type CreateCollectionConfiguration, DOCUMENT_KEY, Div, EMBEDDING_KEY, type EmbeddingFunction, type EmbeddingFunctionClass, type EmbeddingFunctionSpace, Exp, FloatInvertedIndexConfig, FloatInvertedIndexType, FloatListValueType, FloatValueType, FtsIndexConfig, FtsIndexType, GetResult, GroupBy, type GroupByInput, type GroupByJSON, type HNSWConfiguration, IncludeEnum, type IndexConfig, type IndexingStatus, IntInvertedIndexConfig, IntInvertedIndexType, IntValueType, InvalidArgumentError, InvalidCollectionError, K, Key, type KeyFactory, Knn, type KnnOptions, Limit, type LimitInput, type LimitOptions, type ListDatabasesArgs, Log, Max, MaxK, type Metadata, Min, MinK, Mul, type PreparedInsertRecordSet, type PreparedRecordSet, type QueryRecordSet, QueryResult, type QueryRowResult, RankExpression, type RankInput, type RankLiteral, ReadLevel, type RecordSet, Rrf, type RrfOptions, Schema, Search, type SearchInit, type SearchLike, SearchResult, type SearchResultRow, Select, type SelectInput, type SelectKeyInput, type SparseEmbeddingFunction, type SparseEmbeddingFunctionClass, type SparseVector, SparseVectorIndexConfig, type SparseVectorIndexConfigOptions, SparseVectorIndexType, SparseVectorValueType, StringInvertedIndexConfig, StringInvertedIndexType, StringValueType, Sub, Sum, type UpdateCollectionConfiguration, type UpdateHNSWConfiguration, type UpdateSPANNConfiguration, type UserIdentity, Val, ValueTypes, VectorIndexConfig, type VectorIndexConfigOptions, VectorIndexType, type Where, type WhereDocument, WhereExpression, type WhereInput, type WhereJSON, baseRecordSetFields, createErrorByType, getDefaultEFConfig, getEmbeddingFunction, getSparseEmbeddingFunction, knownEmbeddingFunctions, knownSparseEmbeddingFunctions, processCreateCollectionConfig, processUpdateCollectionConfig, recordSetFields, registerEmbeddingFunction, registerSparseEmbeddingFunction, serializeEmbeddingFunction, toSearch, withChroma };
|