@solvers-hub/llm-json 0.1.5 → 0.1.7

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/README.md CHANGED
@@ -1,50 +1,116 @@
1
- # LLM-JSON Extractor
2
-
3
- A TypeScript SDK for extracting and correcting JSON data from LLM outputs.
4
-
5
- [![npm version](https://badge.fury.io/js/llm-json.svg)](https://badge.fury.io/js/llm-json)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
-
8
- ## Overview
9
-
10
- LLM-JSON is a lightweight library designed to parse and extract JSON objects from large language model (LLM) outputs. It can handle multiple JSON objects within text, extract text separately from JSON, and even attempt to fix malformed JSON.
11
-
12
- ## Key Features
13
-
14
- - **Text/JSON Separation**: Cleanly separates text content from JSON data in LLM outputs
15
- - **Multiple JSON Support**: Extracts multiple JSON objects or arrays from a single input
16
- - **JSON Validation & Correction**: Automatically fixes common JSON formatting errors from LLMs
17
- - **Code Block Support**: Extracts JSON from markdown code blocks (```json)
18
- - **TypeScript Support**: Written in TypeScript with full type definitions
19
-
20
- ## Quick Start
21
-
22
- ### Installation
23
-
24
- ```bash
25
- npm install @solvers-hub/llm-json
26
- ```
27
-
28
- ### Basic Usage
29
-
30
- ```typescript
31
- import { LlmJson } from '@solvers-hub/llm-json';
32
-
33
- const llmOutput = `Here's some text followed by JSON:
34
-
35
- {
36
- "name": "John",
37
- "age": 30,
38
- "skills": ["JavaScript", "TypeScript", "React"]
39
- }`;
40
-
41
- const llmJson = new LlmJson({ attemptCorrection: true });
42
- const { text, json } = llmJson.extract(llmOutput);
43
-
44
- console.log(text); // ['Here\'s some text followed by JSON:']
45
- console.log(json); // [{ name: 'John', age: 30, skills: ['JavaScript', 'TypeScript', 'React'] }]
46
- ```
47
-
48
- ## License
49
-
50
- MIT © 2023
1
+ # LLM-JSON Extractor
2
+
3
+ A TypeScript SDK for extracting and correcting JSON data from LLM outputs.
4
+
5
+ [![npm version](https://badge.fury.io/js/llm-json.svg)](https://badge.fury.io/js/llm-json)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Overview
9
+
10
+ LLM-JSON is a lightweight library designed to parse and extract JSON objects from large language model (LLM) outputs. It can handle multiple JSON objects within text, extract text separately from JSON, and even attempt to fix malformed JSON.
11
+
12
+ ## Key Features
13
+
14
+ - **Text/JSON Separation**: Cleanly separates text content from JSON data in LLM outputs
15
+ - **Multiple JSON Support**: Extracts multiple JSON objects or arrays from a single input
16
+ - **JSON Validation & Correction**: Automatically fixes common JSON formatting errors from LLMs
17
+ - **Code Block Support**: Extracts JSON from markdown code blocks (```json)
18
+ - **Schema Validation**: Validates extracted JSON against provided schemas
19
+ - **TypeScript Support**: Written in TypeScript with full type definitions
20
+
21
+ ## Quick Start
22
+
23
+ ### Installation
24
+
25
+ ```bash
26
+ npm install @solvers-hub/llm-json
27
+ ```
28
+
29
+ ### Basic Usage
30
+
31
+ ```typescript
32
+ import { LlmJson } from '@solvers-hub/llm-json';
33
+
34
+ const llmOutput = `Here's some text followed by JSON:
35
+
36
+ {
37
+ "name": "John",
38
+ "age": 30,
39
+ "skills": ["JavaScript", "TypeScript", "React"]
40
+ }`;
41
+
42
+ const llmJson = new LlmJson({ attemptCorrection: true });
43
+ const { text, json } = llmJson.extract(llmOutput);
44
+
45
+ console.log(text); // ['Here\'s some text followed by JSON:']
46
+ console.log(json); // [{ name: 'John', age: 30, skills: ['JavaScript', 'TypeScript', 'React'] }]
47
+ ```
48
+
49
+ ### Schema Validation
50
+
51
+ You can validate extracted JSON against schemas:
52
+
53
+ ```typescript
54
+ import { LlmJson } from '@solvers-hub/llm-json';
55
+
56
+ const schemas = [
57
+ {
58
+ name: 'person',
59
+ schema: {
60
+ type: 'object',
61
+ properties: {
62
+ name: { type: 'string' },
63
+ age: { type: 'integer' }
64
+ },
65
+ required: ['name', 'age']
66
+ }
67
+ }
68
+ ];
69
+
70
+ const llmJson = new LlmJson({
71
+ attemptCorrection: true,
72
+ schemas
73
+ });
74
+
75
+ const llmOutput = `Here's a person: {"name": "John", "age": 30}
76
+ And some other data: {"title": "Meeting notes"}`;
77
+ const result = llmJson.extract(llmOutput);
78
+
79
+ // Note: All extracted JSON objects are included in the json array
80
+ console.log(result.json);
81
+ // [
82
+ // { name: 'John', age: 30 },
83
+ // { title: 'Meeting notes' }
84
+ // ]
85
+
86
+ // The validatedJson array includes validation results for each JSON object
87
+ console.log(result.validatedJson);
88
+ // [
89
+ // {
90
+ // json: { name: 'John', age: 30 },
91
+ // matchedSchema: 'person',
92
+ // isValid: true
93
+ // },
94
+ // {
95
+ // json: { title: 'Meeting notes' },
96
+ // matchedSchema: null,
97
+ // isValid: false,
98
+ // validationErrors: [...] // Validation errors
99
+ // }
100
+ // ]
101
+
102
+ ```
103
+
104
+ ## Examples
105
+
106
+ See the [examples](examples) directory for more examples of how to use the library.
107
+
108
+ How to run the examples:
109
+
110
+ ```bash
111
+ npm run example:run -- examples/example.ts
112
+ ```
113
+
114
+ ## License
115
+
116
+ MIT © 2025
@@ -164,9 +164,14 @@ class JsonArrayExtractor extends extractor_1.JsonExtractor {
164
164
  // Extract text blocks and clean them up
165
165
  const rawTextBlocks = this.extractTextBlocks(input, visibleJsonBlocks);
166
166
  const cleanedTextBlocks = this.cleanTextBlocks(rawTextBlocks);
167
+ // Combine filtered objects and standalone arrays
168
+ const combinedJson = [...filteredObjects, ...standaloneArrays];
169
+ // Apply schema validation if schemas are provided
170
+ const validatedJson = this.validateJson(combinedJson);
167
171
  return {
168
172
  text: cleanedTextBlocks,
169
- json: [...filteredObjects, ...standaloneArrays]
173
+ json: combinedJson,
174
+ ...(validatedJson.length > 0 && { validatedJson })
170
175
  };
171
176
  }
172
177
  }
@@ -30,28 +30,27 @@ class JsonCorrector {
30
30
  this.fixSingleQuotes,
31
31
  this.fixExtraCommas
32
32
  ];
33
+ let attemptedCorrection = jsonString;
34
+ let wasCorrected = wasCommentsRemoved;
35
+ // Trying both single strategies and cumulative fixes
33
36
  for (const strategy of strategies) {
34
- const correctedJson = strategy(jsonString);
37
+ // Try single strategy
38
+ const singleStrategyResult = strategy(jsonString);
35
39
  try {
36
- JSON.parse(correctedJson);
37
- return { corrected: correctedJson, wasCorrected: true };
40
+ JSON.parse(singleStrategyResult);
41
+ return { corrected: singleStrategyResult, wasCorrected: true };
38
42
  }
39
43
  catch (e) {
40
- // Try the next strategy
44
+ // Single strategy failed, continue with cumulative approach
41
45
  }
42
- }
43
- // If all strategies failed, try a combination of them
44
- let attemptedCorrection = jsonString;
45
- let wasCorrected = wasCommentsRemoved;
46
- for (const strategy of strategies) {
46
+ // Apply current strategy to our cumulative attempt
47
47
  attemptedCorrection = strategy(attemptedCorrection);
48
48
  try {
49
49
  JSON.parse(attemptedCorrection);
50
- wasCorrected = true;
51
- break;
50
+ return { corrected: attemptedCorrection, wasCorrected: true };
52
51
  }
53
52
  catch (e) {
54
- // Continue with the next strategy
53
+ // Continue with next strategy
55
54
  }
56
55
  }
57
56
  return {
@@ -1,9 +1,11 @@
1
- import { ExtractOptions, ExtractResult, JsonBlock } from './types';
1
+ import { ExtractOptions, ExtractResult, JsonBlock, ValidationResult } from './types';
2
+ import { SchemaValidator } from './validator';
2
3
  /**
3
4
  * JsonExtractor class for extracting JSON from text input.
4
5
  */
5
6
  export declare class JsonExtractor {
6
7
  protected options: ExtractOptions;
8
+ protected schemaValidator: SchemaValidator | null;
7
9
  /**
8
10
  * Creates a new instance of JsonExtractor.
9
11
  * @param options - Configuration options for extraction.
@@ -15,6 +17,12 @@ export declare class JsonExtractor {
15
17
  * @returns An object containing arrays of extracted text and JSON.
16
18
  */
17
19
  extract(input: string): ExtractResult;
20
+ /**
21
+ * Validates JSON objects against provided schemas.
22
+ * @param jsonObjects - The JSON objects to validate.
23
+ * @returns Array of validation results.
24
+ */
25
+ protected validateJson(jsonObjects: JsonBlock[]): ValidationResult[];
18
26
  /**
19
27
  * Extract JSON from markdown code blocks.
20
28
  * @param input - The input string that may contain code blocks.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.JsonExtractor = void 0;
4
4
  const corrector_1 = require("./corrector");
5
+ const validator_1 = require("./validator");
5
6
  /**
6
7
  * JsonExtractor class for extracting JSON from text input.
7
8
  */
@@ -11,10 +12,15 @@ class JsonExtractor {
11
12
  * @param options - Configuration options for extraction.
12
13
  */
13
14
  constructor(options = {}) {
15
+ this.schemaValidator = null;
14
16
  this.options = {
15
17
  attemptCorrection: false,
16
18
  ...options
17
19
  };
20
+ // Initialize schema validator if schemas are provided
21
+ if (this.options.schemas && this.options.schemas.length > 0) {
22
+ this.schemaValidator = new validator_1.SchemaValidator();
23
+ }
18
24
  }
19
25
  /**
20
26
  * Extract JSON and text from a string input.
@@ -41,9 +47,12 @@ class JsonExtractor {
41
47
  let parsed;
42
48
  try {
43
49
  parsed = JSON.parse(correctionResult.corrected);
50
+ // Apply schema validation if schemas are provided
51
+ const validatedJson = this.validateJson([parsed]);
44
52
  return {
45
53
  text: [],
46
- json: [parsed]
54
+ json: [parsed],
55
+ ...(validatedJson.length > 0 && { validatedJson })
47
56
  };
48
57
  }
49
58
  catch (e) {
@@ -57,11 +66,26 @@ class JsonExtractor {
57
66
  // Process the found JSON blocks
58
67
  const parsedBlocks = this.parseJsonBlocks(jsonBlocks);
59
68
  const textBlocks = this.extractTextBlocks(input, jsonBlocks);
69
+ const extractedJson = parsedBlocks.map(block => block.parsed).filter(Boolean);
70
+ // Apply schema validation if schemas are provided
71
+ const validatedJson = this.validateJson(extractedJson);
60
72
  return {
61
73
  text: textBlocks,
62
- json: parsedBlocks.map(block => block.parsed).filter(Boolean)
74
+ json: extractedJson,
75
+ validatedJson
63
76
  };
64
77
  }
78
+ /**
79
+ * Validates JSON objects against provided schemas.
80
+ * @param jsonObjects - The JSON objects to validate.
81
+ * @returns Array of validation results.
82
+ */
83
+ validateJson(jsonObjects) {
84
+ if (!this.schemaValidator || !this.options.schemas || this.options.schemas.length === 0 || !jsonObjects.length) {
85
+ return [];
86
+ }
87
+ return this.schemaValidator.validateAll(jsonObjects, this.options.schemas);
88
+ }
65
89
  /**
66
90
  * Extract JSON from markdown code blocks.
67
91
  * @param input - The input string that may contain code blocks.
@@ -165,18 +189,23 @@ class JsonExtractor {
165
189
  * @returns Array of parsed JSON blocks.
166
190
  */
167
191
  parseJsonBlocks(blocks) {
168
- return blocks.map(block => {
192
+ // Only return only the blocks that were successfully parsed
193
+ const parsedBlocks = [];
194
+ for (const block of blocks) {
169
195
  try {
170
196
  block.parsed = JSON.parse(block.raw);
171
- return block;
197
+ parsedBlocks.push(block);
172
198
  }
173
199
  catch (error) {
174
200
  if (this.options.attemptCorrection) {
175
- return this.attemptJsonCorrection(block, error);
201
+ const correctedBlock = this.attemptJsonCorrection(block, error);
202
+ if (correctedBlock.parsed) {
203
+ parsedBlocks.push(correctedBlock);
204
+ }
176
205
  }
177
- return block;
178
206
  }
179
- });
207
+ }
208
+ return parsedBlocks;
180
209
  }
181
210
  /**
182
211
  * Attempt to correct malformed JSON.
@@ -227,25 +256,6 @@ class JsonExtractor {
227
256
  textBlocks.push(lastBlock);
228
257
  }
229
258
  }
230
- // Handle case where no text blocks were found but we need to maintain structure
231
- // for tests expecting a certain number of text segments (like separators)
232
- if (textBlocks.length === 0 && sortedBlocks.length > 0) {
233
- // If multiple JSON blocks, we need to infer text segments between them
234
- if (sortedBlocks.length > 1) {
235
- // Add placeholder text segments between JSON blocks
236
- for (let i = 0; i < sortedBlocks.length - 1; i++) {
237
- const currentBlock = sortedBlocks[i];
238
- const nextBlock = sortedBlocks[i + 1];
239
- const inBetweenText = input.substring(currentBlock.endIndex + 1, nextBlock.startIndex).trim();
240
- if (inBetweenText) {
241
- textBlocks.push(inBetweenText);
242
- }
243
- else {
244
- textBlocks.push(''); // Add empty segment to maintain expected count
245
- }
246
- }
247
- }
248
- }
249
259
  return textBlocks;
250
260
  }
251
261
  }
@@ -7,6 +7,46 @@ export interface ExtractOptions {
7
7
  * @default false
8
8
  */
9
9
  attemptCorrection?: boolean;
10
+ /**
11
+ * JSON schemas to validate extracted JSON against.
12
+ * If provided, the extracted JSON will be validated against these schemas.
13
+ * @default undefined
14
+ */
15
+ schemas?: SchemaDefinition[];
16
+ }
17
+ /**
18
+ * Definition of a JSON schema for validation.
19
+ */
20
+ export interface SchemaDefinition {
21
+ /**
22
+ * A unique name for the schema to identify which schema matched.
23
+ */
24
+ name: string;
25
+ /**
26
+ * The JSON schema object conforming to JSON Schema specification.
27
+ */
28
+ schema: object;
29
+ }
30
+ /**
31
+ * Result of schema validation for a JSON object.
32
+ */
33
+ export interface ValidationResult {
34
+ /**
35
+ * The JSON object that was validated.
36
+ */
37
+ json: any;
38
+ /**
39
+ * The name of the schema that matched, or null if no schema matched.
40
+ */
41
+ matchedSchema: string | null;
42
+ /**
43
+ * Whether the JSON is valid according to the matched schema.
44
+ */
45
+ isValid: boolean;
46
+ /**
47
+ * Validation errors if any, or undefined if validation passed.
48
+ */
49
+ validationErrors?: any[];
10
50
  }
11
51
  /**
12
52
  * Result of the JSON extraction.
@@ -20,6 +60,10 @@ export interface ExtractResult {
20
60
  * Array of parsed JSON objects extracted from the input.
21
61
  */
22
62
  json: any[];
63
+ /**
64
+ * Array of validated JSON results, only present if schemas were provided.
65
+ */
66
+ validatedJson?: ValidationResult[];
23
67
  }
24
68
  /**
25
69
  * Information about a detected JSON block.
@@ -0,0 +1,27 @@
1
+ import { SchemaDefinition, ValidationResult } from './types';
2
+ /**
3
+ * SchemaValidator class for validating JSON against schemas.
4
+ */
5
+ export declare class SchemaValidator {
6
+ private ajv;
7
+ /**
8
+ * Creates a new instance of SchemaValidator.
9
+ */
10
+ constructor();
11
+ /**
12
+ * Validates a JSON object against a set of schemas.
13
+ *
14
+ * @param json - The JSON object to validate.
15
+ * @param schemas - The schemas to validate against.
16
+ * @returns A validation result with matched schema information.
17
+ */
18
+ validate(json: any, schemas: SchemaDefinition[]): ValidationResult;
19
+ /**
20
+ * Validates an array of JSON objects against a set of schemas.
21
+ *
22
+ * @param jsonObjects - The JSON objects to validate.
23
+ * @param schemas - The schemas to validate against.
24
+ * @returns An array of validation results.
25
+ */
26
+ validateAll(jsonObjects: any[], schemas: SchemaDefinition[]): ValidationResult[];
27
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SchemaValidator = void 0;
7
+ const ajv_1 = __importDefault(require("ajv"));
8
+ const ajv_formats_1 = __importDefault(require("ajv-formats"));
9
+ /**
10
+ * SchemaValidator class for validating JSON against schemas.
11
+ */
12
+ class SchemaValidator {
13
+ /**
14
+ * Creates a new instance of SchemaValidator.
15
+ */
16
+ constructor() {
17
+ this.ajv = new ajv_1.default({
18
+ allErrors: true,
19
+ verbose: true
20
+ });
21
+ // Add format validation support
22
+ (0, ajv_formats_1.default)(this.ajv);
23
+ }
24
+ /**
25
+ * Validates a JSON object against a set of schemas.
26
+ *
27
+ * @param json - The JSON object to validate.
28
+ * @param schemas - The schemas to validate against.
29
+ * @returns A validation result with matched schema information.
30
+ */
31
+ validate(json, schemas) {
32
+ if (!json || !schemas || schemas.length === 0) {
33
+ return {
34
+ json,
35
+ matchedSchema: null,
36
+ isValid: false
37
+ };
38
+ }
39
+ // Try each schema until one matches
40
+ for (const schemaObj of schemas) {
41
+ const validate = this.ajv.compile(schemaObj.schema);
42
+ const isValid = validate(json);
43
+ if (isValid) {
44
+ return {
45
+ json,
46
+ matchedSchema: schemaObj.name,
47
+ isValid: true
48
+ };
49
+ }
50
+ }
51
+ // If we reach here, none of the schemas matched
52
+ // Return the validation errors from the first schema as a fallback
53
+ const firstTry = this.ajv.compile(schemas[0].schema);
54
+ firstTry(json);
55
+ return {
56
+ json,
57
+ matchedSchema: null,
58
+ isValid: false,
59
+ validationErrors: firstTry.errors || []
60
+ };
61
+ }
62
+ /**
63
+ * Validates an array of JSON objects against a set of schemas.
64
+ *
65
+ * @param jsonObjects - The JSON objects to validate.
66
+ * @param schemas - The schemas to validate against.
67
+ * @returns An array of validation results.
68
+ */
69
+ validateAll(jsonObjects, schemas) {
70
+ if (!jsonObjects || jsonObjects.length === 0 || !schemas || schemas.length === 0) {
71
+ return [];
72
+ }
73
+ return jsonObjects.map(json => this.validate(json, schemas));
74
+ }
75
+ }
76
+ exports.SchemaValidator = SchemaValidator;
@@ -1 +1 @@
1
- window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACoXPTQuCQBAG4P8yXSXTLMpj4CWComt0WNYRxXVXdkYQov8efeAm28f5fd+HmdMFGHuGFHIsRKcYAmgFl5BCY/JOIU1LbtTEpXWlc0iTaJ3MZ8k1GPY71WzJaLeXShAhha/g4Qz7KF69bbOerZC8b7kymhxRaUZbCIkUjitjLF4sfeyINHrHt56NX9T97o0ysv7IDOk/4iAsYWatsV8dV/Gx8w3jVnzIpQEAAA=="
1
+ window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACoXQywrCMBAF0H+JW/FRq2iXYjciKApuxMWQTmlomkhmBEH8d6lKax/W9b33kMzpLhhvLAIRYQxXzaIvLsCJCERmo6tGGiSc6V6ZpspEIvDHC38y8h/9Yr/R2ZqsKfdSAxHS8BO8nGI/9uZf2/DGDiRvL6ysoZJQhtHFIJGG1UoV86azJrZHqnynab0bXVT+7qW2Mm1livQfsQNHGDpn3U+nrHRhB5lgBiuMlVH5HVq5eqkLPIJWEeStjnPVS03w/AQ1H01DRwIAAA=="
@@ -1 +1 @@
1
- window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACq1Xy47jNhD8l/aV63FT8ku3JNjDBgES5JCLYARaiTPRriwZJOcRGP73gJIsNj2kzB3kaLGqq7uLpJtnkN2rgiw/w/e6rSBDvmPQFkcBGfzWHH9VXQsMnmUDGZRNoZRQD+P35T/62AC7foYM4MKmOCueToHqVumiLcVspAVB2ZBaVZ9q9ekk65dCm6VTIUWrSXZWk69Sm/yT0F+iZF0gKWZWa418kiq7Vmn5XOpOzku5wFgpp5Xd12+i1J/ftCzu670Hf6yxTgaFlMW/kQm8w/4Pxooh3LywBcV22afxU9NEyQy4WKUU92mysg2txGPx3NiCjl313Ag1KNhF7zHj680UZ+zz7yddd62awtWtFvKxKIV6cBHx57fQWhxP+pdOSlEabmTwhY/ob9NN8rMV/ikU7df7HAZAfH1avEWGW4zQ2SLG/AJi39Rs/6jYCP0xMdows/N+brryu09wWoxvlCxe70daDCh/1jajgITShdRf2kq8RSg54A8KiraKlSPQD4q9Fmo8DKKKELyBf1D0VEgVJTcB44Vud9sfJsRnKck/w42eRcTvu6NQqngSkSEXFh4uhCT645v9VvDejr8vdupUHbpZfYoEHyd7YFD3ezc7w4uQynAz4MtkuQcGj7VoKjMHDvkwKLvj0QQ6jGt/CfMPbhAD5GEFLF8xvltikh4OLL8y+oX+Qw9DYDn6YOjAOLCc+2DcgSXA8sQHSxxYCixPfbDUga2B5WsfbO3ANsDyjQ+2cWBbYPnWB9s6sB2wfOeD7RzYHli+98H2bntNt9HrA94Y0Tvht8L1Ak3P0esGunagaTt6DUHXETSdR68n6JqCpvm4ZjxZrvjGRbq+oOk/ep1B1xo0FqDXHHTdQeMCev1B1yA0RqDXInQ94sYI7vWIux5xYwT3esRvzgsPdom7HnFjBPefrcGj/mZ4EVKL8d/NnPF+chd2cj/D3+P1sb7eWWdYQ3a+XOxlYX4ZgXHsK8nYZ/m4sgFwFYjgvJQsN7HUJMCcBmbL2lnWLsASbTWAaaJbkug2RLw+NCxvY2mbeVZh3g2WSPTuyHXXGd+S95a8nyfLcXwmlSKpFAPsJ6HtC91yuaXyANNHo4oB2jD9EgpxH0P2G9LXYeIlzJQw0xlmPwCJYXohJZIdy0M7tmmOtwkTWog1TSpEjbSGh3ozvOy955PUGir1OueRDpHtg6H9Y2cOki31P2RKPx4RMXKFYH+HMOChzdOP+O/PJjlkGDplw1uNkEiuGNJ7LVRpR25CJrcIeq+RA4NTfRJN3QrI8sPl8h+xAR0iXRMAAA==";
1
+ window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACq1Y227bOBD9F/pVTTwj27H9tpc+tFhgF1ugL4KxYCUmUauLISqXhZF/X1CSxaE8VJh0n4JY58wZzhmOKJ5EUz9psU9O4kdeZWIPuI1EJUsl9uKPovys60pE4qEpxF6khdRa6evh96v7tixEdP5Z7IV4icY4S1yNgfJKt7JK1WykBUHZkK3OPuT6w7HJH2VrHh1lo6qWZGc1cbmyyd+p9lOQrAski5nVWgOOUmld6bZ5SNu6mZdygaFSTinrb99V2n58bhv5ut4l+H2FdTKQTSP/DUzgAvs/GKv6cPPCFhRaZU7jl6IIkulxoUor2K3ipS1opm7lQ2EXVNbZQ6F0r2AfstsM15sxzlDnP49tXld6DJdXrWpuZar0tYsI37+ybVV5bH+rm0alhhsYfMER+TJNkvckotN7VcrQtS0s/I2itKxfuiC/q9u8yn1rn2LCS9v9CY24GND8ai4SnS1iuOiIf7MsLeNXWeSZNIC/labtTvSnmPAyfte8MWzExYDm13ORqEeylG16r7Iv3mry2lPazyWR6w4ZLm8JPyf8OOI+Nk3dsFuSz4BhvjkVZuz5u8oBhLdUq54Dwy0G6OyQmS+nr38ZsdnmDRIbHFDZ53DVKedt8tQvE+DXok5/cMrjw3CfGvn0eqRFj+Kzthn5JmYrm/ZTlannACUH/E5BVWWhcgT6TrEnqYcXtGIHyURwAn+n6FE2OkhuBIYLTbvtLxOiGzY+PYsI77tSaS3v2Jc3E3Jh4f6FkETf3uxTwdc6/nWxY629Jx5OkeDDZA+RyLve3Z/Eo2q04e4FXsVXOxGJ21wVmfk2PR+S0rosTaDD8OyrMl8VBtFDrpciSpZRDFer3e5wiJIzo3vQ/dDBQEQJcDBwYCiiBDkYOrBYREnMwWIHthJRsuJgKwe2FlGy5mBrB7YRUbLhYBsHdiOi5IaD3TiwrYiSLQfbOrCdiJIdB9u55TXVBtYHmBjROcFb4XoBpubAugGuHWDKDqwh4DoCpvLAegKuKWCKD6wt4PoCpv6wiXBzFe/ARbrWgLEAWHPAdQeMC8D6A65BYIwA1iJwPUJjBLIeoesRGiOQ9Qgn+wW9a0fXIzRGIL+3XI/QGIGsm+h6hMYIXLHqrkdojEDWTXQ9QmMEsvsMXY/QGIGsm+h6hMYIZN1E16O484h1M3Y9io0RMetm7HoUo7dK8WSsdXON9T3uPeqm96NqWjWcQMwc7m58lL3xOYl/hhG/Pr9XTmIt9qeXFzvQzX9GYLguSMl1geXD0gaApSeCc8NmubGlxh7meNFiWVvL2npYqsp6MKHhxvLwxkc8X1BZHqFt5lnS3DdZ4o0lviJXn++GLHlnybt5cjN8YZGVEkvQZ8mdau3NLuESqofJ0YA0gY+mH/tPXMIiVoLPy/7DipCIIdA5Egn05WrI3/qvGrJG0ne4mmF2h1zVn1AJnXgT+8pbFOU0ceKKjzXcQpyvdsiiSTOBr5vGsyzZYUQ09jnTn+OIGKkP+DZmf4nNjpSVpfuqe/58IFUlvYC+lrdHWbJE0nuxL9vu1E3ESIq47nso9vUQ4wahg2+JPS0jF5QkANlmMK/rTAWg+8xnZ/elezn+yKBH3yDrb0wIieihT2+8g5g2PNJh4nPG3jup4d6JLJfsNPD1hA1wOQmBLBp8r7cnqVP75UzSJ3sO2el0iMQxP6oir5TYJ4eXl/8AZUE3hrgbAAA=";