-
Notifications
You must be signed in to change notification settings - Fork 64
/
Copy pathOCR - Azure AI Document Intelligence.step
1 lines (1 loc) · 113 KB
/
OCR - Azure AI Document Intelligence.step
1
{"creationTimeStamp":"2024-03-28T07:03:05.871Z","modifiedTimeStamp":"2024-03-28T07:08:00.705Z","createdBy":"gerjch","modifiedBy":"gerjch","name":"OCR - Azure AI Document Intelligence.step","displayName":"OCR - Azure AI Document Intelligence.step","localDisplayName":"OCR - Azure AI Document Intelligence.step","properties":{},"links":[{"method":"GET","rel":"self","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","type":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"alternate","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","type":"application/vnd.sas.data.flow.step.summary"},{"method":"GET","rel":"up","href":"/dataFlows/steps","uri":"/dataFlows/steps","type":"application/vnd.sas.collection","itemType":"application/vnd.sas.data.flow.step.summary"},{"method":"PUT","rel":"update","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","type":"application/vnd.sas.data.flow.step","responseType":"application/vnd.sas.data.flow.step"},{"method":"DELETE","rel":"delete","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d"},{"method":"POST","rel":"copy","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d/copy","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d/copy","responseType":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"transferExport","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","responseType":"application/vnd.sas.transfer.object"},{"method":"PUT","rel":"transferImportUpdate","href":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","uri":"/dataFlows/steps/f12940c8-48ff-49d5-89c3-2d812bbd709d","type":"application/vnd.sas.transfer.object","responseType":"application/vnd.sas.summary"}],"metadataVersion":0.0,"version":2,"type":"code","flowMetadata":{"inputPorts":[{"name":"input_table_name","displayName":"input_table_name","localDisplayName":"input_table_name","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table"}],"outputPorts":[{"name":"outputtable1","displayName":"ocr_output","localDisplayName":"ocr_output","description":"Containing OCR results. Structure varies with different options like the type of extraction performed.","localDescription":"Containing OCR results. Structure varies with different options like the type of extraction performed.","minEntries":1,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false},{"name":"outputtable2","displayName":"status_output","localDisplayName":"status_output","description":"Optional table. Contains status information of the OCR processing on a document level. ","localDescription":"Optional table. Contains status information of the OCR processing on a document level. ","minEntries":0,"maxEntries":1,"defaultEntries":0,"type":"table","supportsView":false,"requiresStructure":false}]},"ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"pageSettings\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Settings\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"extractions_settings\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"OCR Settings\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"ocr_type\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"OCR-Type:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"text\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Text\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"form\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Forms\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"query\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Queries\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"table\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Tables\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text_settings\",\n\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\"label\": \"Text\",\n\t\t\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"text\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"text_granularity\",\n\t\t\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Extraction Level:\",\n\t\t\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"document\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Document\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"page\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Page\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"paragraph\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Paragraph\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"line\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Line\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"word\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Word\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"text\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"extract_pragraph_roles\",\n\t\t\t\t\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Extract Paragraph Roles\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$text_granularity\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"paragraph\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"extract_paragraph_role_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"Enabling this option might have cost implication. Links with more information about Azure Document Intelligent pricing can be found in the About page of this custom step. \",\n\t\t\t\t\t\t\t\t\t\"visible\": \"$extract_pragraph_roles\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"query_settings\",\n\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\"label\": \"Query\",\n\t\t\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"query\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"ocr_query_fields\",\n\t\t\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Query Fields:\",\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"seperate, your, fields_with, commas\",\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"query\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"query\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"query_keys_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"Make sure your keys are regex compliant by substituting blanks with underscores ('_'). Do not add quotes.\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"query\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"query_exclude_metadata\",\n\t\t\t\t\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Only Output Query Results\",\n\t\t\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"query_exclude_metadata_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"When unselected, the ouput will be a key-value table including OCR metadata like field location, etc...\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"query\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"table_settings\",\n\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\"label\": \"Table\",\n\t\t\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$ocr_type\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"table\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_output_format\",\n\t\t\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Extraction Mode:\",\n\t\t\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"map\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Mapping-Table\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"reference\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Reference-Table\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"value\": \"table\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"One Table\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_settings_map_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"Outputs one table containing all cells of every processed document in the following format [row_id, column_id, cell_content]\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"map\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_settings_table_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"Outputs table in its original form. NOTE: ONLY SUPPORTS THE OUTPUT OF A SINGLE TABLE! \\nFor more information please refer to the About section of the custom step.\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"table\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_settings_reference_info\",\n\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\"text\": \"Saves all extracted tables in the defined librarary and outputs a reference table. \",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"reference\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_output_library\",\n\t\t\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Output Library:\",\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"reference\"\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"reference\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"select_table\",\n\t\t\t\t\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Enable Table Selection\",\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\"reference\"\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"table_filter_settings\",\n\t\t\t\t\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Filter Settings\",\n\t\t\t\t\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\"$select_table\",\n\t\t\t\t\t\t\t\t\t\t\t\"|\",\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"table\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"&\",\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\"$table_output_format\",\n\t\t\t\t\t\t\t\t\t\t\t\"!=\",\n\t\t\t\t\t\t\t\t\t\t\t\"map\"\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"id\": \"tabel_selection_method\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Selection Method:\",\n\t\t\t\t\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"index\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Index\"\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"value\": \"size\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Table Size\"\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"id\": \"table_selection_idx\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"numberfield\",\n\t\t\t\t\t\t\t\t\t\t\t\"label\": \"Table-Index:\",\n\t\t\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\t\t\t\t\t\t\"min\": 0,\n\t\t\t\t\t\t\t\t\t\t\t\"excludemin\": false,\n\t\t\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"$tabel_selection_method\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"index\"\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\"integer\": true\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\"id\": \"table_filtering_size_info\",\n\t\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\t\"text\": \"Selects the largest table. \",\n\t\t\t\t\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\t\t\t\t\"$tabel_selection_method\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"size\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"input_settings\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Input Settings\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"input_mode\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Input Mode:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"batch\",\n\t\t\t\t\t\t\t\t\t\"label\": \"A list of files (table)\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"single\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Single file (path)\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"input_type\",\n\t\t\t\t\t\t\t\"type\": \"radiogroup\",\n\t\t\t\t\t\t\t\"label\": \"Input Type:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"file\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Local File(s)\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"url\",\n\t\t\t\t\t\t\t\t\t\"label\": \"URL(s)\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"input_table_name\",\n\t\t\t\t\t\t\t\"type\": \"inputtable\",\n\t\t\t\t\t\t\t\"label\": \"Input Table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"Table containing file paths\",\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$input_mode\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"batch\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t\"$input_mode\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"batch\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"path_column\",\n\t\t\t\t\t\t\t\"type\": \"columnselector\",\n\t\t\t\t\t\t\t\"label\": \"File path/URL Column:\",\n\t\t\t\t\t\t\t\"order\": false,\n\t\t\t\t\t\t\t\"columntype\": \"c\",\n\t\t\t\t\t\t\t\"max\": 1,\n\t\t\t\t\t\t\t\"min\": null,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$input_mode\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"batch\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"readonly\": false,\n\t\t\t\t\t\t\t\"table\": \"input_table_name\",\n\t\t\t\t\t\t\t\"include\": null\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"file_path\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"File Path:\",\n\t\t\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\t\t\"placeholder\": \"sasserver:/path/to/file/on/saserver\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$input_mode\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"single\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"&\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$input_type\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"file\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"file_url\",\n\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\"label\": \"File URL: \",\n\t\t\t\t\t\t\t\"placeholder\": \"https://www.example.com/image.jpg\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$input_mode\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"single\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"&\",\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"$input_type\",\n\t\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\t\"url\"\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textInputSettings\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Hint: You can find language related settings on the Advanced Settings page.\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"output_settings\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Output Settings\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable1\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"OCR Output Table:\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"Table to output OCR results\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"output_status_table\",\n\t\t\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\t\t\"label\": \"Output Processing Status Table\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"outputtable2\",\n\t\t\t\t\t\t\t\"type\": \"outputtable\",\n\t\t\t\t\t\t\t\"label\": \"Status Output Table:\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"$output_status_table\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageConnection\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Azure Connection\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"azure_endpoint\",\n\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\"label\": \"Azure Resource Endpoint:\",\n\t\t\t\t\t\"placeholder\": \"https://your-resource.cognitiveservices.azure.com/\",\n\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\"visible\": \"!$local_ocr\",\n\t\t\t\t\t\"enabled\": \"!$local_ocr\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"azure_key\",\n\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\"label\": \"Azure Secret Key:\",\n\t\t\t\t\t\"placeholder\": \"SECRET_KEY\",\n\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\"visible\": \"!$local_ocr\",\n\t\t\t\t\t\"enabled\": \"!$local_ocr\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"local_endpoint\",\n\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\"label\": \"Local Container Endpoint\",\n\t\t\t\t\t\"placeholder\": \"https://localhost:5000\",\n\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\"visible\": \"$local_ocr\",\n\t\t\t\t\t\"enabled\": \"$local_ocr\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"local_ocr\",\n\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\"label\": \"Use local Document Intelligence Container\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAzureConnection\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"For more information about the creation of Azure AI Document Intelligence ressources and access, follow the documentation linked in the about page. \",\n\t\t\t\t\t\"visible\": \"!$local_ocr\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAzureLocalContainer\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"PLEASE NOTE:\\n- Enabling this option does not create a container. You can find information regarding deployment in the about page.\\n- Local document intelligence container do not support query extraction. \\n- Only the 'General Document' container is supported\\n- For more info read the documentation linked in the about page\",\n\t\t\t\t\t\"visible\": \"$local_ocr\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageAdvanced\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Advanced Settings\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"advanced_language\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Language\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"locale_info_text\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"NOTE: Languages are detected automatically. Only select a language if you want to force Document Intelligence to use only this language for detection. For more information follow the link in the About page. \",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"ocr_locale\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Force Language for OCR:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Abaza\",\n\t\t\t\t\t\t\t\t\t\"value\": \"abq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Abkhazian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ab\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Achinese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ace\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Acoli\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ach\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Adangme\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ada\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Adyghe\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ady\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Afar\",\n\t\t\t\t\t\t\t\t\t\"value\": \"aa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Afrikaans\",\n\t\t\t\t\t\t\t\t\t\"value\": \"af\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Akan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ak\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Albanian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Algonquin\",\n\t\t\t\t\t\t\t\t\t\"value\": \"alq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Angika (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"anp\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Arabic\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ar\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Asturian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ast\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Asu (Tanzania)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"asa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Avaric\",\n\t\t\t\t\t\t\t\t\t\"value\": \"av\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Awadhi-Hindi (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"awa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Aymara\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ay\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Azerbaijani (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"az\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bafia\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ksf\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bagheli\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bfy\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bambara\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bm\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bashkir\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ba\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Basque\",\n\t\t\t\t\t\t\t\t\t\"value\": \"eu\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Belarusian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"be\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bemba (Zambia)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bem\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bena (Tanzania)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bez\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bhojpuri-Hindi (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bho\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bikol\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bik\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bini\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bin\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bislama\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bodo (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"brx\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bosnian (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bs\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Brajbha\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bra\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Breton\",\n\t\t\t\t\t\t\t\t\t\"value\": \"br\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bulgarian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Bundeli\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bns\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Buryat (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bua\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Catalan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ca\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Cebuano\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ceb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chamling\",\n\t\t\t\t\t\t\t\t\t\"value\": \"rab\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chamorro\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ch\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chechen\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ce\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chhattisgarhi (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hne\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chiga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cgg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chinese Simplified\",\n\t\t\t\t\t\t\t\t\t\"value\": \"zh-Hans\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chinese Traditional\",\n\t\t\t\t\t\t\t\t\t\"value\": \"zh-Hant\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Choctaw\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cho\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chukot\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ckt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Chuvash\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Cornish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kw\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Corsican\",\n\t\t\t\t\t\t\t\t\t\"value\": \"co\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Cree\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Creek\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mus\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Crimean Tatar (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"crh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Croatian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Crow\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cro\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Czech\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cs\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Danish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"da\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dargwa\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dar\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dari\",\n\t\t\t\t\t\t\t\t\t\"value\": \"prs\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dhimal (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dhi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dogri (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"doi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Duala\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dua\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dungan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dng\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Dutch\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Efik\",\n\t\t\t\t\t\t\t\t\t\"value\": \"efi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"English\",\n\t\t\t\t\t\t\t\t\t\"value\": \"en\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Erzya (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"myv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Estonian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"et\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Faroese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Fijian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fj\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Filipino\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fil\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Finnish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Fon\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fon\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"French\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Friulian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fur\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gaa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gagauz (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gag\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Galician\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ganda\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gayo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gay\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"German\",\n\t\t\t\t\t\t\t\t\t\"value\": \"de\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gilbertese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gil\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gondi (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gon\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Greek\",\n\t\t\t\t\t\t\t\t\t\"value\": \"el\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Greenlandic\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Guarani\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gurung (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gvr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Gusii\",\n\t\t\t\t\t\t\t\t\t\"value\": \"guz\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Haitian Creole\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ht\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Halbi (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hlb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hani\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hni\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Haryanvi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bgc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hawaiian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"haw\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hebrew\",\n\t\t\t\t\t\t\t\t\t\"value\": \"he\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Herero\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hz\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hiligaynon\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hil\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hindi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hmong Daw (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mww\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ho (Devanagiri)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hoc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Hungarian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hu\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Iban\",\n\t\t\t\t\t\t\t\t\t\"value\": \"iba\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Icelandic\",\n\t\t\t\t\t\t\t\t\t\"value\": \"is\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Igbo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ig\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Iloko\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ilo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Inari Sami\",\n\t\t\t\t\t\t\t\t\t\"value\": \"smn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Indonesian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"id\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ingush\",\n\t\t\t\t\t\t\t\t\t\"value\": \"inh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Interlingua\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ia\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Inuktitut (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"iu\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Irish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ga\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Italian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"it\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Japanese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ja\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Jaunsari (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"Jns\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Javanese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"jv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Jola-Fonyi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dyo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"K'iche'\",\n\t\t\t\t\t\t\t\t\t\"value\": \"quc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kabardian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kbd\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kabuverdianu\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kea\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kachin (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kac\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kalenjin\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kln\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kalmyk\",\n\t\t\t\t\t\t\t\t\t\"value\": \"xal\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kangri (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"xnr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kanuri\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kara-Kalpak (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kaa-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kara-Kalpak (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kaa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Karachay-Balkar\",\n\t\t\t\t\t\t\t\t\t\"value\": \"krc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kashubian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"csb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kazakh (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kk-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kazakh (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kk-latn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Khakas\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kjh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Khaling\",\n\t\t\t\t\t\t\t\t\t\"value\": \"klr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Khasi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kha\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kikuyu\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ki\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kildin Sami\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sjd\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kinyarwanda\",\n\t\t\t\t\t\t\t\t\t\"value\": \"rw\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Komi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kongo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Korean\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ko\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Korku\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kfq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Koryak\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kpy\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kosraean\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kos\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kpelle\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kpe\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kuanyama\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kj\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kumyk (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kum\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kurdish (Arabic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ku-arab\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kurdish (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ku-latn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kurukh (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kru\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Kyrgyz (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ky\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lak\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lbe\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lakota\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lkt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Latin\",\n\t\t\t\t\t\t\t\t\t\"value\": \"la\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Latvian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lezghian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lex\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lingala\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ln\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lithuanian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lower Sorbian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dsb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lozi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"loz\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Lule Sami\",\n\t\t\t\t\t\t\t\t\t\"value\": \"smj\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Luo (Kenya and Tanzania)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"luo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Luxembourgish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"lb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Luyia\",\n\t\t\t\t\t\t\t\t\t\"value\": \"luy\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Macedonian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Machame\",\n\t\t\t\t\t\t\t\t\t\"value\": \"jmc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Madurese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mad\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mahasu Pahari (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bfz\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Makhuwa-Meetto\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mgh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Makonde\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kde\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Malagasy\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Malay (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ms\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Maltese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Malto (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"kmj\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mandinka\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mnk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Manx\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Maori\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mapudungun\",\n\t\t\t\t\t\t\t\t\t\"value\": \"arn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Marathi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mari (Russia)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"chm\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Masai\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mas\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mende (Sierra Leone)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"men\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Meru\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mer\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Meta'\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mgo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Minangkabau\",\n\t\t\t\t\t\t\t\t\t\"value\": \"min\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mohawk\",\n\t\t\t\t\t\t\t\t\t\"value\": \"moh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mongolian (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mongondow\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mog\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Montenegrin (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cnr-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Montenegrin (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cnr-latn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Morisyen\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mfe\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Mundang\",\n\t\t\t\t\t\t\t\t\t\"value\": \"mua\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nahuatl\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nah\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Navajo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ndonga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ng\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Neapolitan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nap\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nepali\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ne\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ngomba\",\n\t\t\t\t\t\t\t\t\t\"value\": \"jgo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Niuean\",\n\t\t\t\t\t\t\t\t\t\"value\": \"niu\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nogay\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nog\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"North Ndebele\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nd\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Northern Sami (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sme\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Norwegian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"no\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nyanja\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ny\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nyankole\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nyn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Nzima\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nzi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Occitan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"oc\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ojibwa\",\n\t\t\t\t\t\t\t\t\t\"value\": \"oj\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Oromo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"om\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ossetic\",\n\t\t\t\t\t\t\t\t\t\"value\": \"os\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Pampanga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pam\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Pangasinan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pag\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Papiamento\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pap\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Pashto\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ps\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Pedi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nso\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Persian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Polish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Portuguese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Punjabi (Arabic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"pa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Quechua\",\n\t\t\t\t\t\t\t\t\t\"value\": \"qu\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ripuarian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ksh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Romanian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ro\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Romansh\",\n\t\t\t\t\t\t\t\t\t\"value\": \"rm\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Rundi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"rn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Russian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ru\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Rwa\",\n\t\t\t\t\t\t\t\t\t\"value\": \"rwk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sadri (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sck\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sakha\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sah\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Samburu\",\n\t\t\t\t\t\t\t\t\t\"value\": \"saq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Samoan (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sm\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sango\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sangu (Gabon)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"snq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sanskrit (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sa\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Santali(Devanagiri)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sat\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Scots\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sco\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Scottish Gaelic\",\n\t\t\t\t\t\t\t\t\t\"value\": \"gd\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sena\",\n\t\t\t\t\t\t\t\t\t\"value\": \"seh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Serbian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Serbian (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sr-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Shambala\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ksb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Shona\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Siksika\",\n\t\t\t\t\t\t\t\t\t\"value\": \"bla\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sirmauri (Devanagari)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"srx\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Skolt Sami\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sms\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Slovak\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Slovenian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Soga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"xog\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Somali (Arabic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"so\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Somali (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"so-latn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Songhai\",\n\t\t\t\t\t\t\t\t\t\"value\": \"son\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"South Ndebele\",\n\t\t\t\t\t\t\t\t\t\"value\": \"nr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Southern Altai\",\n\t\t\t\t\t\t\t\t\t\"value\": \"alt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Southern Sami\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sma\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Southern Sotho\",\n\t\t\t\t\t\t\t\t\t\"value\": \"st\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Spanish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"es\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Sundanese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"su\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Swahili (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sw\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Swati\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ss\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Swedish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"sv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tabassaran\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tab\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tachelhit\",\n\t\t\t\t\t\t\t\t\t\"value\": \"shi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tahitian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ty\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Taita\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dav\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tajik (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tg\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tamil\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ta\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tatar (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tt-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tatar (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tt\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Teso\",\n\t\t\t\t\t\t\t\t\t\"value\": \"teo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tetum\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tet\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Thai\",\n\t\t\t\t\t\t\t\t\t\"value\": \"th\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Thangmi\",\n\t\t\t\t\t\t\t\t\t\"value\": \"thf\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tok Pisin\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tpi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tongan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"to\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tsonga\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ts\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tswana\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Turkish\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tr\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Turkmen (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Tuvan\",\n\t\t\t\t\t\t\t\t\t\"value\": \"tyv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Udmurt\",\n\t\t\t\t\t\t\t\t\t\"value\": \"udm\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Uighur (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ug-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Ukrainian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"uk\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Upper Sorbian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"hsb\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Urdu\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ur\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Uyghur (Arabic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"ug\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Uzbek (Arabic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"uz-arab\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Uzbek (Cyrillic)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"uz-cyrl\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Uzbek (Latin)\",\n\t\t\t\t\t\t\t\t\t\"value\": \"uz\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Vietnamese\",\n\t\t\t\t\t\t\t\t\t\"value\": \"vi\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Volapük\",\n\t\t\t\t\t\t\t\t\t\"value\": \"vo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Vunjo\",\n\t\t\t\t\t\t\t\t\t\"value\": \"vun\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Walser\",\n\t\t\t\t\t\t\t\t\t\"value\": \"wae\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Welsh\",\n\t\t\t\t\t\t\t\t\t\"value\": \"cy\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Western Frisian\",\n\t\t\t\t\t\t\t\t\t\"value\": \"fy\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Wolof\",\n\t\t\t\t\t\t\t\t\t\"value\": \"wo\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Xhosa\",\n\t\t\t\t\t\t\t\t\t\"value\": \"xh\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Yucatec Maya\",\n\t\t\t\t\t\t\t\t\t\"value\": \"yua\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Zapotec\",\n\t\t\t\t\t\t\t\t\t\"value\": \"zap\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Zarma\",\n\t\t\t\t\t\t\t\t\t\"value\": \"dje\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Zhuang\",\n\t\t\t\t\t\t\t\t\t\"value\": \"za\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"label\": \"Zulu\",\n\t\t\t\t\t\t\t\t\t\"value\": \"zu\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"advanced_connection\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Connection\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"timeout_seconds\",\n\t\t\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\t\t\"label\": \"Timeout (seconds):\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"timeout_info\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Seconds to wait for the OCR processing to finish before timing out. \",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"n_connection_retries\",\n\t\t\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\t\t\"label\": \"Number of Retries:\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"retry_delay\",\n\t\t\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\t\t\"label\": \"Seconds between Retry Attempts:\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"integer\": true,\n\t\t\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\t\t\"max\": 10,\n\t\t\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"advanced_Processing\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Processing\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"n_threads\",\n\t\t\t\t\t\t\t\"type\": \"numstepper\",\n\t\t\t\t\t\t\t\"label\": \"Number of Threads:\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"integer\": false,\n\t\t\t\t\t\t\t\"min\": 1,\n\t\t\t\t\t\t\t\"max\": 64,\n\t\t\t\t\t\t\t\"stepsize\": 1\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"advanced_output\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Output\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"save_json_info_text\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Saves the raw OCR result as JSON files at the specified location.\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"save_files\",\n\t\t\t\t\t\t\t\"type\": \"checkbox\",\n\t\t\t\t\t\t\t\"label\": \"Save as JSON\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"json_output_folder\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Output Folder:\",\n\t\t\t\t\t\t\t\"pathtype\": \"folder\",\n\t\t\t\t\t\t\t\"placeholder\": \"Folder to save the unparsed OCR results\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": \"$save_files\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"pageAbout\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAbout\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"OCR - Azure AI Document Intelligence\\n=========================\\n\\nThis custom step uses the Azure Document Intelligence service to perform different types of OCR\\n\\nNOTE: The usage of this step requires an Azure AI Document Intelligence Resource. For more information, check the documentation below.\\n\\nSupported OCR types: \\n * Text (word, line, paragraph, page)\\n * Form (key-value pairs)\\n * Query (specific keys)\\n * Tables\\n\\nSupported file types:\\n * Images: .png, .jpg / .jpeg, .bmp, .tiff, .heif\\n * Documents: .pdf\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionPrereqs\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Pre-requisites\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textPrereqs\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Tested on Viya version Stable 2024.02\\n\\nGeneral:\\n * Python 3\\n * Azure AI Document Intelligence Resource\\n\\nPython Packages:\\n * pandas\\n * numpy\\n\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionDocumentation\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Documentation\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"text_noteStepLinksOption\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Note: if there are no links shown below, then ask your SAS administrator to go into SAS Environment manager and use the Configuration panel to configure the allowedStepLinks option of the Data Flow service to allow https connections. \\nYou can find all links in the GitHub repository of this custom step: https://github.com/sassoftware/sas-studio-custom-steps\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link1\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Custom Step Repository & Documentation\",\n\t\t\t\t\t\t\t\"url\": \"https://github.com/sassoftware/sas-studio-custom-steps/tree/main/OCR%20-%20Azure%20Document%20Intelligence\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link2\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Azure AI Document Intelligence documentation\",\n\t\t\t\t\t\t\t\"url\": \"https://learn.microsoft.com/en-US/azure/ai-services/document-intelligence/?view=doc-intel-4.0.0\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link3\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Language Support\",\n\t\t\t\t\t\t\t\"url\": \"https://learn.microsoft.com/en-GB/azure/ai-services/document-intelligence/language-support-ocr?view=doc-intel-4.0.0&tabs=read-print%2Clayout-print%2Cgeneral\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link4\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Pricing\",\n\t\t\t\t\t\t\t\"url\": \"https://azure.microsoft.com/en-us/pricing/details/ai-document-intelligence/#pricing\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link6\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Data Privacy\",\n\t\t\t\t\t\t\t\"url\": \"https://learn.microsoft.com/en-us/legal/cognitive-services/document-intelligence/data-privacy-security\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link7\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Install Local Document Intelligence Container\",\n\t\t\t\t\t\t\t\"url\": \"https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/containers/install-run?view=doc-intel-3.0\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"link8\",\n\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\"label\": \"Proc Python documentation\",\n\t\t\t\t\t\t\t\"url\": \"https://go.documentation.sas.com/doc/en/pgmsascdc/default/proc/p1iycdzbxw2787n178ysea5ghk6l.htm\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"sectionChangelog\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Changelog\",\n\t\t\t\t\t\"open\": false,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"textChangelog\",\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": \"Version 2.0 (22MAR2024)\\n- Renamed to \\\"OCR - Azure AI Document Intelligence\\\" \\n- Added support for text, form and query extraction\\n- Added support for extracting multiple tables at once\\n- Added support for processing multiple files at once\\n- Added support for local document intelligence container\\n- Added option to output status table\\n- Added multithreading \\n- Upgraded used API version to Document Intelligence 4.0\\n\\nVersion 1.0 (02JAN2024)\\n- Initial Version\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"textAuthor\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"This custom step was created by:\\n- Jannic Horst (jannic.horst@sas.com)\\n- Sundaresh Sankaran (sundaresh.sankaran@sas.com)\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"ocr_type\": {\n\t\t\t\"value\": \"text\",\n\t\t\t\"label\": \"Text\"\n\t\t},\n\t\t\"text_granularity\": {\n\t\t\t\"value\": \"paragraph\",\n\t\t\t\"label\": \"Paragraph\"\n\t\t},\n\t\t\"extract_pragraph_roles\": false,\n\t\t\"ocr_query_fields\": \"\",\n\t\t\"query_exclude_metadata\": true,\n\t\t\"table_output_format\": {\n\t\t\t\"value\": \"map\",\n\t\t\t\"label\": \"Mapping-Table\"\n\t\t},\n\t\t\"table_output_library\": \"WORK\",\n\t\t\"select_table\": false,\n\t\t\"tabel_selection_method\": {\n\t\t\t\"value\": \"index\",\n\t\t\t\"label\": \"Index\"\n\t\t},\n\t\t\"table_selection_idx\": 0,\n\t\t\"input_mode\": {\n\t\t\t\"value\": \"batch\",\n\t\t\t\"label\": \"A list of files (table)\"\n\t\t},\n\t\t\"input_type\": {\n\t\t\t\"value\": \"file\",\n\t\t\t\"label\": \"Local File(s)\"\n\t\t},\n\t\t\"input_table_name\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"path_column\": [],\n\t\t\"file_path\": \"\",\n\t\t\"file_url\": \"\",\n\t\t\"outputtable1\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"output_status_table\": false,\n\t\t\"outputtable2\": {\n\t\t\t\"library\": \"\",\n\t\t\t\"table\": \"\"\n\t\t},\n\t\t\"azure_endpoint\": \"https://your-resource.cognitiveservices.azure.com/\",\n\t\t\"azure_key\": \"SECRET_KEY\",\n\t\t\"local_endpoint\": \"https://localhost:5000\",\n\t\t\"local_ocr\": false,\n\t\t\"ocr_locale\": null,\n\t\t\"timeout_seconds\": 30,\n\t\t\"n_connection_retries\": 3,\n\t\t\"retry_delay\": 2,\n\t\t\"n_threads\": 16,\n\t\t\"save_files\": false,\n\t\t\"json_output_folder\": \"\"\n\t}\n}","templates":{"SAS":"proc python restart;\nsubmit;\n# Imports\ntry:\n\timport pandas as pd\n\timport numpy as np\n\timport functools\n\timport requests\n\timport threading\n\timport base64\n\timport json\n\timport io\n\timport re\n\timport os\n\timport time\n\timport uuid\n\tfrom urllib.parse import urlparse\n\tfrom datetime import datetime\n\tfrom urllib.error import HTTPError\nexcept ImportError as e:\n\tSAS.logMessage(f'ImportError - {e}. Please install the required packages!', 'error')\n\texit()\n\n################### DEFINE PARAMETERS ###################\n# azure credentials & container\nazure_key = str(SAS.symget(\"azure_key\"))\nazure_endpoint = str(SAS.symget(\"azure_endpoint\"))\nlocal_ocr = bool(int(SAS.symget(\"local_ocr\"))) # whether to use a locally deployed document intelligence container, default = False\nlocal_ocr_endpoint = str(SAS.symget(\"local_endpoint\")) \t\t\t\t # endpoint of the locally deployed document intelligence container\n\nSERVICE_VERSION = '4.0' \t\t\t\t\t\t# 4.0 is in preview. Local containers are only supported in 3.0 (GA) thus far\nAPI_VERSION = '2023-10-31-preview' \t\t\t\t\t\t\t# default: '2023-10-31-preview'- to lock the API version, in case breaking change are introduced\nDEFAULT_MODEL_ID = 'prebuilt-layout'\nSUPPORTED_EXTENSIONS = ['jpeg', 'jpg', 'png', 'bmp', 'tiff', 'heif', 'pdf']\n\n# general\nocr_type = str(SAS.symget(\"ocr_type\")) \t\t# type of OCR: text, form, query, table\ninput_type = str(SAS.symget(\"input_type\")) \t\t# type of input: file, url \ninput_mode = str(SAS.symget(\"input_mode\")) \t\t# single or batch\nfile_path = str(SAS.symget(\"file_path\")) \t\t\t\t\t\t\t\t# path to a (single) file\nfile_url = str(SAS.symget(\"file_url\")) \ninput_table_name = str(SAS.symget(\"input_table_name\")) # name of table containing the file paths\npath_column = str(SAS.symget(\"path_column\")) # column that contains the file path\noutput_status_table = bool(int(SAS.symget(\"output_status_table\"))) # whether to output the status table\n\n# advanced\nlocale = str(SAS.symget(\"ocr_locale\")) \t# optional, language of the document. Support-list: https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/language-support-ocr?view=doc-intel-4.0.0&tabs=read-hand%2Clayout-print%2Cgeneral\nn_threads = int(SAS.symget(\"n_threads\")) \t# number of threads to use for parallel processing\nn_con_retry = int(SAS.symget(\"n_connection_retries\")) # number of retries if connection fails\nretry_delay = int(SAS.symget(\"retry_delay\")) # delay between retries\ntimeout_seconds = int(SAS.symget(\"timeout_seconds\")) # seconds waiting for ocr processing to finish before timing out\nsave_json = bool(int(SAS.symget(\"save_files\"))) # whether to save the json output\njson_output_folder = str(SAS.symget(\"json_output_folder\")) # folder to save the json output\n\n# for text extraction\ntext_granularity = str(SAS.symget(\"text_granularity\")) \t# level of detail: word, line, paragraph, page, document\nmodel_id = '' \t\t\t\t\t \t # Has cost implications. Layout more expensive but allows for more features: prebuilt-read, prebuilt-layout\nextract_pragraph_roles = bool(int(SAS.symget(\"extract_pragraph_roles\")))\n\n# for query extraction\nquery_fields = str(SAS.symget(\"ocr_query_fields\")) \t\t\t# string containing comma separated keys to extract\nquery_exclude_metadata = bool(int(SAS.symget(\"query_exclude_metadata\")))# if excluded, the resulting table will contain a column per query field (doesn't support ocr metadata like bounding boxes)\n\n# for table extraction\ntable_output_format = str(SAS.symget(\"table_output_format\")) # how the tables should be returned: map, reference*, table** *reference requires a cas\ntable_output_library = str(SAS.symget(\"table_output_library\")) # caslib to store the table (only relevant if table_output_format = 'reference')\nselect_table = bool(int(SAS.symget(\"select_table\"))) # whether to select a specific table or all tables (only relevant if table_output_format = 'reference')\ntable_selection_method = str(SAS.symget(\"table_selection_method\")) # how to select the table: size, index (only relevant if table_output_format = 'reference' and selected_table = True)\ntable_selection_idx = int(SAS.symget(\"table_selection_idx\")) # index of the table to extract (only relevant if table_output_format = 'table')\n\n\n##################### HELPER FUNCTIONS #####################\ndef retry_on_endpoint_connection_error(max_retries=3, delay=2):\n\t\"\"\"\n\tThis is a decorator function that allows a function to retry execution when an EndpointConnectionError occurs.\n\n\tParameters:\n\t-----------\n\tmax_retries (int): \n\t\tThe maximum number of retries if an EndpointConnectionError occurs. Default is 3.\n\tdelay (int): \n\t\tThe delay (in seconds) between retries. Default is 2.\n\n\tReturns:\n\twrapper function: \n\t\tThe decorated function that includes retry logic.\n\t\"\"\"\n\tdef decorator(func):\n\t\t@functools.wraps(func)\n\t\tdef wrapper(*args, **kwargs):\n\t\t\tretries = 0\n\t\t\twhile retries < max_retries:\n\t\t\t\ttry:\n\t\t\t\t\treturn func(*args, **kwargs)\n\t\t\t\t\t\"\"\" except EndpointConnectionError as e:\n\t\t\t\t\t\tSAS.logMessage(f'Retrying due to EndpointConnectionError: {e}')\n\t\t\t\t\t\tretries += 1\n\t\t\t\t\t\ttime.sleep(delay) \"\"\"\n\t\t\t\texcept Exception as e:\n\t\t\t\t\traise e # Let other exceptions be handled by the utility class\n\n\t\t\tif retries == max_retries:\n\t\t\t\tSAS.logMessage(f\"Max retries ({max_retries}) reached. Unable to complete operation.\", 'warning')\n\t\t\t\traise RuntimeError(\"Max retries to contact Azure endpoint reached. Unable to complete operation.\")\n\t\treturn wrapper\n\n\treturn decorator\n\ndef prepare_query(query_fields: str):\n\t\"\"\" Prepare the query string for the Azure Document Intelligence API\"\"\"\n\t# Split, strip, and replace spaces with underscores\n\tquery_list = query_fields.split(',')\n\tquery_list = [q.strip().replace(' ', '_') for q in query_list]\n\n\t# Check if query string is regex compatible\n\tfor q in query_list:\n\t\ttry:\n\t\t\tre.compile(q)\n\t\texcept re.error as e:\n\t\t\traise ValueError(f'Query string \"{q}\" is not regex compatible! Error: {e}')\n\n\t# Join back into a string with comma-separated values\n\tfinal_query_string = ','.join(query_list)\n\n\treturn final_query_string\n\ndef check_column_names(df):\n\t\"\"\"\n\tCheck dataframe column names for length (<=32) and truncate if needed to adhere to SAS table rules/limitations. \n\t\n\tArgs:\n\tdf (pd.DataFrame): The input DataFrame.\n\t\n\tReturns:\n\tpd.DataFrame: The DataFrame with truncated column names if necessary.\n\t\"\"\"\n\ttruncated_columns = {}\n\tfor col in df.columns:\n\t\tif len(col) > 32:\n\t\t\tnew_name = col[:29] + '...'\n\t\t\ttruncated_columns[col] = new_name\n\t\t\tSAS.logMessage(f\"Column '{col}' too long. Truncated to '{new_name}'.\", 'warning')\n\t\telse:\n\t\t\ttruncated_columns[col] = col\n\t\n\t# Rename the columns of the DataFrame\n\tdf.rename(columns=truncated_columns, inplace=True)\n\t\n\treturn df\n###################### OCR STRATEGIES #####################\n# parent class for the OCR strategies\nclass OCRStrategy:\n\t\"\"\" Base class for the OCR strategies \"\"\"\n\tdef __init__(self, kwargs):\n\t\tself.kwargs = kwargs\n\n\tdef parse_ocr_result(self, result) -> pd.DataFrame:\n\t\tpass\n\n\tdef analyze_document(self, document) -> pd.DataFrame:\n\t\tpass\n\n# implemented OCR strategies\nclass ExtractText(OCRStrategy): \n\tdef __init__(self, kwargs):\n\t\tself.endpoint = kwargs.get('endpoint', '')\n\t\tself.key = kwargs.get('key', '')\n\t\tself.model_id = kwargs.get('model_id', 'prebuilt-read')\n\t\tself.version = kwargs.get('version', '2023-10-31-preview')\n\t\tself.local_ocr = kwargs.get('local_ocr', False)\n\t\tself.input_type = kwargs.get('input_type', 'file')\n\t\tself.text_granularity = kwargs.get('text_granularity', 'line')\n\t\tself.file_location = kwargs.get('file_location', 'local')\n\t\tself.locale = kwargs.get('locale', '')\n\t\tself.model_id = kwargs.get('model_id', 'prebuilt-read')\n\n\t\tif self.local_ocr:\n\t\t\tself.endpoint = kwargs.get('endpoint', 'http://localhost:5000')\n\n\tdef parse_ocr_result(self,result) -> pd.DataFrame:\n\t\tparsed_result = pd.DataFrame()\n\n\t\t# set the text granularity\n\t\tlevel = self.text_granularity\n\t\tif (level.upper() == 'PAGE'):\n\t\t\tself.text_granularity = \"LINE\"\n\t\telse:\n\t\t\tself.text_granularity = level.upper()\n\t\t\n\t\tif self.text_granularity == \"DOCUMENT\":\n\t\t\tocr_data = []\n\t\t\t\n\t\t\t# check if the document contains handwriting\n\t\t\ttry:\n\t\t\t\tcontains_handwriting = result['styles'][0]['isHandwritten']\n\t\t\texcept:\n\t\t\t\tcontains_handwriting = False\n\n\t\t\tdocument_info = {\n\t\t\t\t\"text\": result['content'],\n\t\t\t\t\"contains_handwriting\": contains_handwriting,\n\t\t\t\t}\n\t\t\tocr_data.append(document_info)\n\t\t\tdf = pd.DataFrame(ocr_data)\n\t\t\tparsed_result = pd.concat([parsed_result, df], ignore_index=True)\n\n\t\telif self.text_granularity == \"PARAGRAPH\":\n\t\t\tocr_data = []\n\t\t\tprint('paragraph')\n\t\t\tfor paragraph_idx, paragraph in enumerate(result['paragraphs']):\n\t\t\t\tx1, y1, x2, y2, x3, y3, x4, y4 = paragraph['boundingRegions'][0]['polygon']\n\n\t\t\t\ttry: \n\t\t\t\t\trole = paragraph['role']\n\t\t\t\texcept:\n\t\t\t\t\trole = ''\n\n\t\t\t\tparagrpah_info = {\n\t\t\t\t\t\"page\": paragraph['boundingRegions'][0]['pageNumber'],\n\t\t\t\t\t\"paragraph\": paragraph_idx,\n\t\t\t\t\t\"role\": role,\n\t\t\t\t\t\"text\": paragraph['content'], \n\t\t\t\t\t\"bb_x1\": x1,\n\t\t\t\t\t\"bb_y1\": y1,\n\t\t\t\t\t\"bb_x2\": x2,\n\t\t\t\t\t\"bb_y2\": y2,\n\t\t\t\t\t\"bb_x3\": x3,\n\t\t\t\t\t\"bb_y3\": y3,\n\t\t\t\t\t\"bb_x4\": x4,\n\t\t\t\t\t\"bb_y4\": y4,\n\t\t\t\t\t\"offset\": paragraph['spans'][0]['offset'],\n\t\t\t\t\t\"length\": paragraph['spans'][0]['length'],\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tocr_data.append(paragrpah_info)\n\t\t\tdf = pd.DataFrame(ocr_data)\n\t\t\tparsed_result = pd.concat([parsed_result, df], ignore_index=True)\n\t\telse:\n\t\t\tfor page in result['pages']:\n\t\t\t\tocr_data = []\n\t\t\t\t\n\t\t\t\t# to calculate the average confidence\n\t\t\t\tif self.text_granularity != \"WORD\":\n\t\t\t\t\tword_confidences = [word['confidence'] for word in page['words']]\n\t\t\t\t\ttotal_confidence = sum(word_confidences)\n\t\t\t\t\ttotal_words = len(word_confidences)\n\t\t\t\t\taverage_confidence = total_confidence / total_words if total_words > 0 else 0\n\n\t\t\t\t# extraction on line level\n\t\t\t\tif self.text_granularity == \"LINE\":\n\t\t\t\t\tfor line_idx, line in enumerate(page['lines']):\n\t\t\t\t\t\tx1, y1, x2, y2, x3, y3, x4, y4 = line['polygon']\n\n\t\t\t\t\t\tline_info = {\n\t\t\t\t\t\t\t\"page\": page['pageNumber'],\n\t\t\t\t\t\t\t\"line\": line_idx,\n\t\t\t\t\t\t\t\"text\": line['content'],\n\t\t\t\t\t\t\t\"bb_x1\": x1,\n\t\t\t\t\t\t\t\"bb_y1\": y1,\n\t\t\t\t\t\t\t\"bb_x2\": x2,\n\t\t\t\t\t\t\t\"bb_y2\": y2,\n\t\t\t\t\t\t\t\"bb_x3\": x3,\n\t\t\t\t\t\t\t\"bb_y3\": y3,\n\t\t\t\t\t\t\t\"bb_x4\": x4,\n\t\t\t\t\t\t\t\"bb_y4\": y4,\n\t\t\t\t\t\t\t\"offset\": line['spans'][0]['offset'],\n\t\t\t\t\t\t\t\"length\": line['spans'][0]['length'],\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tocr_data.append(line_info)\n\n\t\t\t\t# extraction on word level\n\t\t\t\telif self.text_granularity == \"WORD\":\n\t\t\t\t\tfor word in page['words']:\n\t\t\t\t\t\tx1, y1, x2, y2, x3, y3, x4, y4 = word['polygon']\n\n\t\t\t\t\t\tword_info = {\n\t\t\t\t\t\t\t\"page\": page['pageNumber'],\n\t\t\t\t\t\t\t\"text\": word['content'],\n\t\t\t\t\t\t\t\"confidence\": word['confidence'],\n\t\t\t\t\t\t\t\"bb_x1\": x1,\n\t\t\t\t\t\t\t\"bb_y1\": y1,\n\t\t\t\t\t\t\t\"bb_x2\": x2,\n\t\t\t\t\t\t\t\"bb_y2\": y2,\n\t\t\t\t\t\t\t\"bb_x3\": x3,\n\t\t\t\t\t\t\t\"bb_y3\": y3,\n\t\t\t\t\t\t\t\"bb_x4\": x4,\n\t\t\t\t\t\t\t\"bb_y4\": y4,\n\t\t\t\t\t\t\t\"offset\": word['span']['offset'],\n\t\t\t\t\t\t\t\"length\": word['span']['length'],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tocr_data.append(word_info)\n\t\t\t\t\n\t\t\t\tdf = pd.DataFrame(ocr_data)\n\n\t\t\t\t# aggregation on page level\n\t\t\t\tif level.upper() == \"PAGE\":\n\t\t\t\t\tocr_data = []\n\t\t\t\t\tpage_info = {\n\t\t\t\t\t\t\t\"page\": page['pageNumber'],\n\t\t\t\t\t\t\t\"text\": \"\\n \".join(df['text']),\n\t\t\t\t\t\t\t\"avg_confidence\": average_confidence\n\t\t\t\t\t\t\t}\n\t\t\t\t\tocr_data.append(page_info)\n\t\t\t\t\t\n\t\t\t\t\tdf = pd.DataFrame(ocr_data)\n\n\t\t\t\tparsed_result = pd.concat([parsed_result, df], ignore_index=True)\n\n\t\tif self.model_id == 'prebuilt-read' and self.text_granularity.upper() == 'PARAGRAPH': # 'read' model doesn't provide semantic role, only 'layout' does\n\t\t\tparsed_result = parsed_result.drop(columns=['role'])\n\n\t\treturn parsed_result\n\n\t@retry_on_endpoint_connection_error(max_retries=n_con_retry, delay=retry_delay)\n\tdef analyze_document(self, document):\n\t\t\"\"\" Analyze the document and return the result\n\n\t\tParameters:\n\t\t-----------\n\t\tdocument:\n\t\t\tstr: document (base64) or url to document to analyze\n\t\t\n\t\tReturns:\n\t\t--------\n\t\tparsed_result:\n\t\t\tpd.DataFrame: OCR results\n\t\t \"\"\"\n\t\t# azure cloud\n\t\tif not self.local_ocr:\n\t\t\tif self.input_type.upper() == 'FILE':\n\t\t\t\tdata = {\n\t\t\t\t\t\"base64Source\": document\n\t\t\t\t}\n\t\t\telif self.input_type.upper() == 'URL':\n\t\t\t\tdata = {\n\t\t\t\t\t\"urlSource\": document\n\t\t\t\t}\n\n\t\t\turl = f\"{self.endpoint}documentintelligence/documentModels/{self.model_id}:analyze?_overload=analyzeDocument&api-version={self.version}\"\n\n\t\t\t# if a specific language was selected\n\t\t\tif self.locale != \"\":\n\t\t\t\turl = url + f'&locale={self.locale}'\n\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key,\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t}\n\n\t\t\tresponse = requests.post(url, headers=headers, json=data)\n\n\t\t\tif int(response.status_code) in {400, 403, 404}:\n\t\t\t\tSAS.logMessage(f'Error: {response.status_code} - {response.text}', 'error')\n\t\t\t\traise HTTPError(f'Error: {response.status_code} - {response.text}')\n\n\t\t\t# Check processing status\n\t\t\tresponse_url = response.headers.get('Operation-Location') # This is the URL you got from the POST response\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key\n\t\t\t}\n\n\t\t\titeration = 0\n\t\t\tstatus = ''\n\t\t\twhile status != 'succeeded' and iteration < timeout_seconds:\n\t\t\t\ttime.sleep(1)\n\t\t\t\tresponse = requests.get(response_url, headers=headers)\n\t\t\t\tstatus = response.json().get('status')\n\t\t\t\titeration += 1\n\n\t\t\t\tif status == 'succeeded':\n\t\t\t\t\tbreak\n\n\t\t\tif status != 'succeeded':\n\t\t\t\tSAS.logMessage(f'The request did not complete within the time limit. Iterations: {iteration}', 'error')\n\t\t\t\texit()\n\t\t\t\t\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult'] \n\t\t\t\t\t\t\t\t\t\t\t \n\t\t# local ocr \n\t\telse:\n\t\t\turl = f\"{self.endpoint}/formrecognizer/documentModels/prebuilt-document:syncAnalyze?api-version=2022-08-31\"\n\t\t\theaders = {\n\t\t\t\t'accept': '*/*',\n\t\t\t\t'Content-Type': 'application/octet-stream',\n\t\t\t}\n\t\t\tresponse = requests.post(url, headers=headers, data=document)\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult']\n\n\t\treturn result\n\nclass ExtractForm(OCRStrategy):\n\tdef __init__(self, kwargs):\n\t\tself.endpoint = kwargs.get('endpoint', '')\n\t\tself.key = kwargs.get('key', '')\n\t\tself.model_id = kwargs.get('model_id', 'prebuilt-layout')\n\t\tself.version = kwargs.get('version', '2023-10-31-preview')\n\t\tself.local_ocr = kwargs.get('local_ocr', False)\n\t\tself.input_type = kwargs.get('input_type', 'file')\n\t\tself.file_location = kwargs.get('file_location', 'local')\n\t\tself.locale = kwargs.get('locale', '')\n\n\t\tif self.local_ocr:\n\t\t\tself.endpoint = kwargs.get('endpoint', 'http://localhost:5000')\n\n\tdef parse_ocr_result(self, result) -> pd.DataFrame:\n\t\tkey_value_pairs = result['keyValuePairs']\n\t\tform_data = []\n\n\t\tfor pair in key_value_pairs:\n\t\t\tpage_number = pair['key']['boundingRegions'][0]['pageNumber']\n\t\t\tkey = pair['key']['content']\n\t\t\tkey_x1, key_y1, key_x2, key_y2, key_x3, key_y3, key_x4, key_y4 = pair['key']['boundingRegions'][0]['polygon']\n\t\t\tkey_offset = pair['key']['spans'][0]['offset']\n\t\t\tkey_length = pair['key']['spans'][0]['length']\n\n\t\t\ttry:\n\t\t\t\tvalue = pair['value']['content']\n\t\t\t\tvalue_x1, value_y1, value_x2, value_y2, value_x3, value_y3, value_x4, value_y4 = pair['value']['boundingRegions'][0]['polygon']\n\t\t\t\tvalue_offset = pair['value']['spans'][0]['offset']\n\t\t\t\tvalue_length = pair['value']['spans'][0]['length']\n\t\t\texcept KeyError as e:\n\t\t\t\tvalue_x1 = value_y1 = value_x2 = value_y2 = value_x3 = value_y3 = value_x4 = value_y4 = None\n\t\t\t\tvalue_offset = value_length = None\n\t\t\t\tvalue = None\n\n\t\t\tkey_value = {\n\t\t\t\t'page_number': page_number,\n\t\t\t\t'key': key,\n\t\t\t\t'value': value,\n\t\t\t\t'key_x1': key_x1,\n\t\t\t\t'key_y1': key_y1,\n\t\t\t\t'key_x2': key_x2,\n\t\t\t\t'key_y2': key_y2,\n\t\t\t\t'key_x3': key_x3,\n\t\t\t\t'key_y3': key_y3,\n\t\t\t\t'key_x4': key_x4,\n\t\t\t\t'key_y4': key_y4,\n\t\t\t\t'key_offset': key_offset,\n\t\t\t\t'key_length': key_length,\n\t\t\t\t'value_x1': value_x1,\n\t\t\t\t'value_y1': value_y1,\n\t\t\t\t'value_x2': value_x2,\n\t\t\t\t'value_y2': value_y2,\n\t\t\t\t'value_x3': value_x3,\n\t\t\t\t'value_y3': value_y3,\n\t\t\t\t'value_x4': value_x4,\n\t\t\t\t'value_y4': value_y4,\n\t\t\t\t'value_offset': value_offset,\n\t\t\t\t'value_length': value_length,\n\t\t\t}\n\n\t\t\tform_data.append(key_value)\n\t\t\n\t\tdf = pd.DataFrame(form_data)\n\n\t\treturn df\n\t\t\n\t@retry_on_endpoint_connection_error(max_retries=n_con_retry, delay=retry_delay)\n\tdef analyze_document(self, document):\n\t\tif not local_ocr:\n\t\t\tif self.input_type.upper() == 'FILE':\n\t\t\t\tdata = {\n\t\t\t\t\t\"base64Source\": document\n\t\t\t\t}\n\t\t\telif self.input_type.upper() == 'URL':\n\t\t\t\tdata = {\n\t\t\t\t\t\"urlSource\": document\n\t\t\t\t}\n\t\t\t\n\t\t\tfeatures = 'keyValuePairs'\n\t\t\turl = f\"{self.endpoint}documentintelligence/documentModels/{self.model_id}:analyze?_overload=analyzeDocument&api-version={self.version}&features={features}\"\n\n\t\t\t# if a specific language was selected\n\t\t\tif self.locale != \"\":\n\t\t\t\turl = url + f'&locale={self.locale}'\n\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key,\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t}\n\t\t\tresponse = requests.post(url, headers=headers, json=data)\n\t\t\tif int(response.status_code) in {400, 403, 404}:\n\t\t\t\tSAS.logMessage(f'Error: {response.status_code} - {response.text}', 'error')\n\t\t\t\traise HTTPError(f'Error: {response.status_code} - {response.text}')\n\n\t\t\t# Check processing status\n\t\t\tresponse_url = response.headers.get('Operation-Location') # This is the URL you got from the POST response\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key\n\t\t\t}\n\n\t\t\titeration = 0\n\t\t\tstatus = ''\n\n\t\t\twhile status != 'succeeded' and iteration < timeout_seconds:\n\t\t\t\ttime.sleep(1)\n\t\t\t\tresponse = requests.get(response_url, headers=headers)\n\t\t\t\tstatus = response.json().get('status')\n\t\t\t\titeration += 1\n\n\t\t\t\tif status == 'succeeded':\n\t\t\t\t\tbreak\n\n\t\t\tif status != 'succeeded':\n\t\t\t\tSAS.logMessage(f'The request did not complete within the time limit. Iterations: {iteration}', 'error')\n\t\t\t\texit()\n\t\t\t\t\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult'] \n\t\telse:\n\t\t\turl = f\"{self.endpoint}/formrecognizer/documentModels/prebuilt-document:syncAnalyze?api-version=2022-08-31\"\n\t\t\theaders = {\n\t\t\t\t'accept': '*/*',\n\t\t\t\t'Content-Type': 'application/octet-stream',\n\t\t\t}\n\n\t\t\tresponse = requests.post(url, headers=headers, data=document)\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult']\n\t\t\n\t\treturn result\n\nclass ExtractQuery(OCRStrategy):\n\tdef __init__(self, kwargs):\n\t\tself.endpoint = kwargs.get('endpoint', '')\n\t\tself.key = kwargs.get('key', '')\n\t\tself.model_id = kwargs.get('model_id', 'prebuilt-layout')\n\t\tself.version = kwargs.get('version', '2023-10-31-preview')\n\t\tself.input_type = kwargs.get('input_type', 'file')\n\t\tself.file_location = kwargs.get('file_location', 'local')\n\t\tself.locale = kwargs.get('locale', '')\n\t\tself.query_fields = kwargs.get('query_fields', '')\n\t\tself.query_exclude_metadata = kwargs.get('query_exclude_metadata', False)\n\n\tdef parse_ocr_result(self, result) -> pd.DataFrame:\n\t\tquery_data = []\n\t\tfor doc in result['documents']:\n\t\t\tfor field in doc['fields'].keys():\n\t\t\t\tif not self.query_exclude_metadata:\n\t\t\t\t\ttry:\n\t\t\t\t\t\tx1, y1, x2, y2, x3, y3, x4, y4 = doc['fields'][field]['boundingRegions'][0]['polygon']\n\t\t\t\t\t\tquery_info = {\n\t\t\t\t\t\t\t'page_number': doc['fields'][field]['boundingRegions'][0]['pageNumber'],\n\t\t\t\t\t\t\t'key': field,\n\t\t\t\t\t\t\t'value': doc['fields'][field]['content'],\n\t\t\t\t\t\t\t'confidence': doc['fields'][field]['confidence'],\n\t\t\t\t\t\t\t'type': doc['fields'][field]['type'],\n\t\t\t\t\t\t\t'x1': x1,\n\t\t\t\t\t\t\t'y1': y1,\n\t\t\t\t\t\t\t'x2': x2,\n\t\t\t\t\t\t\t'y2': y2,\n\t\t\t\t\t\t\t'x3': x3,\n\t\t\t\t\t\t\t'y3': y3,\n\t\t\t\t\t\t\t'x4': x4,\n\t\t\t\t\t\t\t'y4': y4,\n\t\t\t\t\t\t\t'offset': doc['fields'][field]['spans'][0]['offset'],\n\t\t\t\t\t\t\t'length': doc['fields'][field]['spans'][0]['length'],\n\t\t\t\t\t\t}\n\t\t\t\t\texcept KeyError as e:\n\t\t\t\t\t\tquery_info = {\n\t\t\t\t\t\t\t'page_number': None,\n\t\t\t\t\t\t\t'key': field,\n\t\t\t\t\t\t\t'value': None,\n\t\t\t\t\t\t\t'confidence': None,\n\t\t\t\t\t\t\t'type': None,\n\t\t\t\t\t\t\t'x1': None,\n\t\t\t\t\t\t\t'y1': None,\n\t\t\t\t\t\t\t'x2': None,\n\t\t\t\t\t\t\t'y2': None,\n\t\t\t\t\t\t\t'x3': None,\n\t\t\t\t\t\t\t'y3': None,\n\t\t\t\t\t\t\t'x4': None,\n\t\t\t\t\t\t\t'y4': None,\n\t\t\t\t\t\t\t'offset': None,\n\t\t\t\t\t\t\t'length': None,\n\t\t\t\t\t\t}\n\t\t\t\t\tquery_data.append(query_info)\n\t\t\t\telse:\n\t\t\t\t\ttry:\n\t\t\t\t\t\tquery_info = {\n\t\t\t\t\t\t\t'key': field,\n\t\t\t\t\t\t\t'value': doc['fields'][field]['content'],\n\t\t\t\t\t\t}\n\t\t\t\t\texcept KeyError as e:\n\t\t\t\t\t\tquery_info = {\n\t\t\t\t\t\t\t'key': field,\n\t\t\t\t\t\t\t'value': None,\n\t\t\t\t\t\t}\n\t\t\t\t\tquery_data.append(query_info)\n\n\t\tparsed_result = pd.DataFrame(query_data)\n\n\t\t# if query_exclude_metadata, transpose results\n\t\tif query_exclude_metadata:\n\t\t\tparsed_result = parsed_result.set_index('key').T\n\n\t\treturn parsed_result\n\t\t\n\t@retry_on_endpoint_connection_error(max_retries=n_con_retry, delay=retry_delay)\n\tdef analyze_document(self, document):\n\t\tif self.input_type.upper() == 'FILE':\n\t\t\tdata = {\n\t\t\t\t\"base64Source\": document\n\t\t\t}\n\t\telif self.input_type.upper() == 'URL':\n\t\t\tdata = {\n\t\t\t\t\"urlSource\": document\n\t\t\t}\n\t\t\n\t\tfeatures = 'queryFields'\n\t\turl = f\"{self.endpoint}/documentintelligence/documentModels/{self.model_id}:analyze?_overload=analyzeDocument&api-version={self.version}&features={features}&queryFields={self.query_fields}\"\n\t\theaders = {\n\t\t\t\"Ocp-Apim-Subscription-Key\": self.key,\n\t\t\t\"Content-Type\": \"application/json\"\n\t\t}\n\n\t\tresponse = requests.post(url, headers=headers, json=data)\n\n\t\tif int(response.status_code) in {400, 403, 404}:\n\t\t\tSAS.logMessage(f'Error: {response.status_code} - {response.text}', 'error')\n\t\t\traise HTTPError(f'Error: {response.status_code} - {response.text}')\n\n\n\t\t# Check processing status\n\t\tresponse_url = response.headers.get('Operation-Location') # This is the URL you got from the POST response\n\t\theaders = {\n\t\t\t\"Ocp-Apim-Subscription-Key\": self.key\n\t\t}\n\n\t\titeration = 0\n\t\tstatus = ''\n\n\t\twhile status != 'succeeded' and iteration < timeout_seconds:\n\t\t\ttime.sleep(1)\n\t\t\tresponse = requests.get(response_url, headers=headers)\n\t\t\tstatus = response.json().get('status')\n\t\t\titeration += 1\n\n\t\t\tif status == 'succeeded':\n\t\t\t\tbreak\n\n\t\tif status != 'succeeded':\n\t\t\tprint('The request did not complete within the time limit.')\n\t\t\texit()\n\t\t\t\n\t\t# return results\n\t\tresponse_json = json.loads(response.text)\n\t\tresult = response_json['analyzeResult'] \n\t\treturn result\n\nclass ExtractTable(OCRStrategy):\n\tdef __init__(self, kwargs): \n\t\tself.endpoint = kwargs.get('endpoint', '')\n\t\tself.key = kwargs.get('key', '')\n\t\tself.model_id = kwargs.get('model_id', 'prebuilt-layout')\n\t\tself.version = kwargs.get('version', '2023-10-31-preview')\n\t\tself.local_ocr = kwargs.get('local_ocr', False)\n\t\tself.input_type = kwargs.get('input_type', 'file')\n\t\tself.file_location = kwargs.get('file_location', 'local')\n\t\tself.locale = kwargs.get('locale', '')\n\t\tself.table_output_format = kwargs.get('table_output_format', 'map')\n\t\tself.select_table = kwargs.get('select_table', False)\n\t\tself.table_selection_method = kwargs.get('table_selection_method', 'index')\n\t\tself.table_selection_idx = kwargs.get('table_selection_idx', 0)\n\t\tself.table_output_caslib = kwargs.get('table_output_caslib', 'work')\n\n\t\tif self.local_ocr:\n\t\t\tself.endpoint = kwargs.get('endpoint', 'http://localhost:5000')\n\n\tdef result_to_dfs(self, result) -> list:\n\t\ttables = []\n\t\tfor table in result['tables']:\n\t\t\ttable_df = pd.DataFrame(columns=range(table['columnCount']), index=range(table['rowCount']))\n\n\t\t\tfor cell in table['cells']:\n\t\t\t\ttable_df.iloc[cell['rowIndex'], cell['columnIndex']] = cell['content']\n\n\t\t\t# use the first row as column names\n\t\t\ttable_df.columns = table_df.iloc[0]\n\t\t\ttable_df = table_df[1:]\n\t\t\t\n\t\t\ttables.append(table_df)\n\t\treturn tables\n\n\t# TABLE PARSING METHODS\n\tdef map_parsing(self, result) -> pd.DataFrame:\n\t\t\"\"\" Parses tables as a list of column/row index and cell content for later reconstruction.\"\"\"\n\t\ttables = []\n\n\t\t# extract all table data\n\t\tfor index, table in enumerate(result['tables']):\n\t\t\tif self.table_output_format.upper() == 'MAP':\n\n\t\t\t\tif not isinstance(table, dict):\n\t\t\t\t\ttable = table.as_dict()\n\n\t\t\t\tdf = pd.DataFrame.from_dict(table['cells'])\n\n\t\t\t\t# extract page_number and polygon coordinates\n\t\t\t\tdf['page'] = df['boundingRegions'].apply(lambda x: x[0]['pageNumber'])\n\t\t\t\tdf['table_index'] = index\n\t\t\t\tdf['polygon'] = df['boundingRegions'].apply(lambda x: x[0]['polygon'])\n\n\t\t\t\t# extract polygon coordinates\n\t\t\t\tdf['x1'] = df['polygon'].apply(lambda x: x[0])\n\t\t\t\tdf['y1'] = df['polygon'].apply(lambda x: x[1])\n\t\t\t\tdf['x2'] = df['polygon'].apply(lambda x: x[2])\n\t\t\t\tdf['y2'] = df['polygon'].apply(lambda x: x[3])\n\t\t\t\tdf['x3'] = df['polygon'].apply(lambda x: x[4])\n\t\t\t\tdf['y3'] = df['polygon'].apply(lambda x: x[5])\n\t\t\t\tdf['x4'] = df['polygon'].apply(lambda x: x[6])\n\t\t\t\tdf['y4'] = df['polygon'].apply(lambda x: x[7])\n\n\t\t\t\t# extract offset and length\n\t\t\t\tdf['offset'] = df['spans'].apply(lambda x: int(x[0]['offset']) if x else None)\n\t\t\t\tdf['length'] = df['spans'].apply(lambda x: int(x[0]['length']) if x else None)\n\n\t\t\t\t# drop unnecessary columns\n\t\t\t\tdf.drop(columns=['boundingRegions','spans', 'polygon'], inplace=True)\n\n\t\t\t\ttable_info = {\n\t\t\t\t\t'table_index': index,\n\t\t\t\t\t'row_count': table['rowCount'],\n\t\t\t\t\t'column_count': table['columnCount'],\n\t\t\t\t\t'cell_count': table['rowCount']*table['columnCount'],\n\t\t\t\t\t'table': df\n\t\t\t\t}\n\n\t\t\t\ttables.append(table_info)\n\n\t\t# select specific table (optional)\n\t\tif self.select_table:\n\t\t\tif self.table_selection_method.upper() == 'INDEX':\n\t\t\t\tparsed_result = tables[table_selection_idx]['table']\n\t\t\telif self.table_selection_method.upper() == 'SIZE':\n\t\t\t\t# Find the entry with the highest cell_count using max function\n\t\t\t\ttable_most_cells = max(tables, key=lambda x: x['cell_count'], default=None)\n\t\t\t\tparsed_result = table_most_cells['table'] if table_most_cells else None\n\n\t\telse:\n\t\t\t# combine all extracted tables (only works for output type 'map')\n\t\t\tparsed_result = pd.concat([table['table'] for table in tables], ignore_index=True)\n\n\t\treturn parsed_result\n\n\tdef reference_parsing(self, result) -> pd.DataFrame: \n\t\t\"\"\" Parses and stores every table to specified SAS Library and returns a generated reference ID.\"\"\"\n\t\ttables = self.result_to_dfs(result)\n\t\ttable_info = []\n\n\t\tfor table in tables:\n\t\t\treference = uuid.uuid4()\n\t\t\treference = re.sub(r'^\\w{3}', 'tbl', str(reference))\n\t\t\treference = reference.replace('-', '')\n\t\t\ttable = check_column_names(table)\n\n\t\t\t# save table to caslib\n\t\t\ttry:\n\t\t\t\tSAS.df2sd(table, f\"{self.table_output_caslib}.{reference}\")\n\t\t\t\tSAS.logMessage(f\"Save Table {reference} to {self.table_output_caslib}\")\n\t\t\texcept Exception as e:\n\t\t\t\tSAS.logMessage(f'{e} Failed to save table {reference} to caslib {self.table_output_caslib}', 'error')\n\t\t\t\traise e\n\t\t\t\n\t\t\ttable_info.append({\n\t\t\t\t'out_library': self.table_output_caslib,\n\t\t\t\t'table_reference': reference,\n\t\t\t\t'row_count': table.shape[0],\n\t\t\t\t'column_count': table.shape[1],\n\t\t\t})\n\n\t\tparsed_result = pd.DataFrame(table_info)\n\t\treturn parsed_result\n\n\tdef table_parsing(self, result) -> pd.DataFrame:\n\t\t\"\"\" For a given document parses and returns one table. For multiple tables: Selection by size or index\"\"\"\n\t\ttables = self.result_to_dfs(result)\n\t\tself.select_table = True\n\n\t\t# select specific table \n\t\tif self.select_table:\n\t\t\tif self.table_selection_method.upper() == 'INDEX': # Table with index == table_selection_idx\n\t\t\t\tparsed_result = tables[table_selection_idx]\n\t\t\telif self.table_selection_method.upper() == 'SIZE': # Table with most cells\n\t\t\t\ttable_most_cells = max(tables, key=lambda x: x.size, default=None)\n\t\t\t\ttry:\n\t\t\t\t\tparsed_result = table_most_cells\n\t\t\t\texcept:\n\t\t\t\t\tparsed_result = None\n\n\t\t\telse:\n\t\t\t\traise ValueError(f'Invalid table selection method: {self.table_selection_method}')\n\n\t\tparsed_result = check_column_names(parsed_result)\n\n\t\treturn parsed_result\n\n\t# TABLE PARSING METHODS MAPPING\n\tparsing_methods = {\n\t\t'MAP': map_parsing,\n\t\t'REFERENCE': reference_parsing,\n\t\t'TABLE': table_parsing\n\t}\n\n\tdef parse_ocr_result(self, result) -> pd.DataFrame:\n\t\t# call one of the parsing methods depending on the output format\n\t\tparsing_method = table_output_format.upper()\n\t\tparsed_result = self.parsing_methods.get(parsing_method)(self,result = result)\n\n\t\treturn parsed_result\n\n\t@retry_on_endpoint_connection_error(max_retries=n_con_retry, delay=retry_delay)\n\tdef analyze_document(self, document):\n\t\tif not self.local_ocr: \n\t\t\tif self.input_type.upper() == 'FILE':\n\t\t\t\tdata = {\n\t\t\t\t\t\"base64Source\": document\n\t\t\t\t}\n\t\t\telif self.input_type.upper() == 'URL':\n\t\t\t\tdata = {\n\t\t\t\t\t\"urlSource\": document\n\t\t\t\t}\n\t\t\t\n\t\t\turl = f\"{self.endpoint}documentintelligence/documentModels/{self.model_id}:analyze?_overload=analyzeDocument&api-version={self.version}\"\n\n\t\t\t# if a specific language was selected\n\t\t\tif self.locale != \"\":\n\t\t\t\turl = url + f'&locale={self.locale}'\n\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key,\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t}\n\n\t\t\tresponse = requests.post(url, headers=headers, json=data)\n\n\t\t\tif int(response.status_code) in {400, 403, 404}:\n\t\t\t\tSAS.logMessage(f'Error: {response.status_code} - {response.text}', 'error')\n\t\t\t\traise HTTPError(f'Error: {response.status_code} - {response.text}')\n\n\t\t\t# Check processing status\n\t\t\tresponse_url = response.headers.get('Operation-Location') # This is the URL you got from the POST response\n\t\t\theaders = {\n\t\t\t\t\"Ocp-Apim-Subscription-Key\": self.key\n\t\t\t}\n\n\t\t\titeration = 0\n\t\t\tstatus = ''\n\n\t\t\twhile status != 'succeeded' and iteration < timeout_seconds:\n\t\t\t\ttime.sleep(1)\n\t\t\t\tresponse = requests.get(response_url, headers=headers)\n\t\t\t\tstatus = response.json().get('status')\n\t\t\t\titeration += 1\n\n\t\t\t\tif status == 'succeeded':\n\t\t\t\t\tbreak\n\n\t\t\tif status != 'succeeded':\n\t\t\t\tprint('The request did not complete within the time limit.')\n\t\t\t\texit()\n\t\t\t\t\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult'] \n\t\telse:\n\t\t\turl = f\"{self.endpoint}/formrecognizer/documentModels/prebuilt-document:syncAnalyze?api-version=2022-08-31\"\n\n\t\t\theaders = {\n\t\t\t\t'accept': '*/*',\n\t\t\t\t'Content-Type': 'application/octet-stream',\n\t\t\t}\n\n\t\t\tresponse = requests.post(url, headers=headers, data=document)\n\t\t\tresponse_json = json.loads(response.text)\n\t\t\tresult = response_json['analyzeResult']\n\t\t\n\t\treturn result\n\n# class that processes the OCR\nclass OCRProcessor:\n\t\"\"\" Class that processes the OCR depending on the strategy\"\"\"\n\tdef __init__(self, ocr_type:str, **kwargs):\n\t\tself.ocr_type = ocr_type\n\t\tself.kwargs = kwargs\n\n\t\t# Define the strategy mapping\n\t\tself.strategy_mapping = {\n\t\t\t('text'): ExtractText,\n\t\t\t('form'): ExtractForm,\n\t\t\t('query'): ExtractQuery,\n\t\t\t('table'): ExtractTable\n\t\t}\n\n\t\t# Get the strategy class, parameters and initiate strategy\n\t\tstrategy_class = self.strategy_mapping[(self.ocr_type)]\n\t\tself.strategy = strategy_class(kwargs = self.kwargs)\n\n\tdef analyze_document(self, document):\n\t\t\"\"\" Analyze the document and return the result\n\t\t\n\t\tParameters:\n\t\t-----------\n\t\tdocument:\n\t\t\tstr: document (base64) or document url to analyze\n\t\t\t\n\t\tReturns:\n\t\t--------\n\t\tresult:\n\t\t\tAnalyzeResult: OCR results\"\"\"\n\n\t\treturn self.strategy.analyze_document(document)\n\t\n\tdef parse_ocr_result(self, result) -> pd.DataFrame:\n\t\t\"\"\" Parse the OCR result and return the result\n\n\t\tParameters:\n\t\t-----------\n\t\tresult:\n\t\t\tAnalyzeResult: OCR results\n\n\t\tReturns:\n\t\t--------\n\t\tparsed_result:\n\t\t\tpd.DataFrame: parsed OCR results\n\t\t\"\"\"\n\t\treturn self.strategy.parse_ocr_result(result)\n\t\n###################### PREPARATION ######################\nif input_mode.upper() == 'BATCH': # When input_mode = 'batch' try to load the file list using the input_table_name\n\ttry:\n\t\tfile_list = SAS.sd2df(input_table_name)\n\texcept Exception as e:\n\t\tSAS.logMessage('No input table was provided!', 'error')\n\t\texit()\n\n\t\"\"\"if path_column not in file_list.columns:\n\t\tSAS.logMessage(f'Path column not found in input table! Provided path column: {path_column}', 'error')\n\t\texit()\"\"\"\nelse:\n\tfile_list = ''\n\nif ocr_type.upper() == 'QUERY': # prepare the query string to the right format\n\ttry:\n\t\tquery_fields = prepare_query(query_fields)\n\texcept ValueError as e:\n\t\tprint(f'REGEX ERROR: {e}')\n\t\texit()\n\texcept Exception as e:\n\t\tprint(f'ERROR: {e}')\n\t\texit()\n\nif input_mode.upper() == 'SINGLE': # if input_mode = 'single', create a dataframe with the file path\n\tif file_path.startswith('sasserver:'):\n\t\tfile_path = (file_path[len('sasserver:'):])\n\telif file_path.startswith('sascontent:'):\n\t\tSAS.logMessage(\"Please select a valid path. Files have to be located on SAS Server (not SAS Content)!\", 'error')\n\t\texit()\n\tif input_type.upper() == 'URL': \n\t\tfile_path = file_url\n\tfile_list = pd.DataFrame({'file_path': [file_path]})\n\tpath_column = 'file_path'\n\nif save_json: # check if output folder should be created (if save_json = True)\n\t# remove 'sasserver:'\n\tif json_output_folder.startswith('sasserver:'):\n\t\tjson_output_folder = (json_output_folder[len('sasserver:'):])\n\n\t# check if output folder exists\n\tif not os.path.exists(json_output_folder):\n\t\ttry:\n\t\t\tos.makedirs(json_output_folder)\n\t\t\tSAS.logMessage(f'Created output folder {json_output_folder}!')\n\t\texcept OSError as e:\n\t\t\tSAS.logMessage(f'OSError - Could not create output folder {json_output_folder}!', 'error')\n\t\t\texit()\n\t\n\t# check if output folder is writable\n\tif not os.access(json_output_folder, os.W_OK):\n\t\tSAS.logMessage(f'OSError - Output folder {json_output_folder} is not writable!', 'error')\n\t\texit()\n\nif local_ocr: # check if local ocr container is running and reachable\n\tfor check in ['status', 'ready', 'containerliveness']:\n\t\turl = f'{local_ocr_endpoint}/{check}'\n\t\theaders = {\n\t\t\t'accept': '*/*',\n\t\t}\n\t\tresponse = requests.get(url, headers=headers)\n\t\tif response.status_code != 200:\n\t\t\tSAS.logMessage(f\"Local OCR container is not running or can't be reached! {check}: {response.status_code}\", 'error')\n\t\t\texit()\n\t\n\tSAS.logMessage('Local OCR container is running!')\n\nif ocr_type.upper() != 'TEXT': \n\tmodel_id = DEFAULT_MODEL_ID\nelse:\n\tif extract_pragraph_roles:\n\t\tmodel_id = DEFAULT_MODEL_ID\n\telse:\n\t\tmodel_id = 'prebuilt-read'\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n###################### PRE-CHECKS ######################\nif ocr_type.upper() == 'TABLE' and table_output_format.upper() == 'TABLE' and file_list.shape[0] > 1: # if table_output_format = 'table', check if only one row in the file_list\n\tSAS.logMessage('Only one file as input is supported if output format = \"table\"!')\n\texit()\n\nif input_mode.upper() == 'BATCH':\n\tif file_list.shape[0] < 1: # if input_mode = 'batch' and input_type = 'file', check if the file list is not empty\n\t\tSAS.logMessage('Provided file list is empty!', 'error')\n\t\texit()\n\nif local_ocr: # Local OCR doesn't support Query extraction \n\tif ocr_type.upper() == 'QUERY':\n\t\tSAS.logMessage('Local OCR container does not support query extraction!', 'error')\n\t\texit()\n\nif not local_ocr: \n\tif azure_endpoint == 'https://your-resource.cognitiveservices.azure.com/' or azure_endpoint == '': # If no endpoint was provided\n\t\tSAS.logMessage('ERROR - No Azure Document Intelligence Endpoint Provided!', 'error')\n\t\texit()\n\tif azure_key == 'SECRET_KEY' or azure_key == '': # If no azure key was provided\n\t\tSAS.logMessage('ERROR - No Azure Document Intelligence Secret Key Provided!', 'error')\n\t\texit()\n\n\n###################### EXECUTION ######################\nSAS.logMessage(f\"START PROCESSING - Type: {ocr_type}, Mode: {input_mode}, Input Type: {input_type}\")\n# define all possible parameters for the OCR\nocr_params = {\n\t\t\t # general\n\t\t\t 'locale': locale,\n\t\t\t 'input_type': input_type,\n\t\t\t 'local_ocr': local_ocr,\n\t\t\t 'endpoint': azure_endpoint,\n\t\t\t 'key': azure_key,\n\t\t\t 'model_id': model_id,\n\t\t\t 'version': API_VERSION,\n\t\t\t # for text extraction\n\t\t\t 'text_granularity': text_granularity,\n\t\t\t # for query extraction\n\t\t\t 'query_fields': query_fields,\n\t\t\t 'query_exclude_metadata': query_exclude_metadata,\n\t\t\t # for table extraction\n\t\t\t 'table_output_format': table_output_format,\n\t\t\t 'selected_table': select_table,\n\t\t\t 'selection_method': table_selection_method,\n\t\t\t 'table_selection_idx': table_selection_idx,\n\t\t\t 'table_output_caslib': table_output_library,\n\t\t\t }\n\n# initiate dataframe to store results and status\nocr_results = pd.DataFrame()\nstatus = pd.DataFrame()\n\n# initiate the OCR client and processor\nocr_processor = OCRProcessor(ocr_type = ocr_type, \n\t\t\t\t\t\t\t **ocr_params\n\t\t\t\t\t\t\t )\n\ndef process_files(file_list, ocr_processor, path_column):\n\t\"\"\" Process the files in the file_list using the ocr_processor\n\n\tParameters:\n\t-----------\n\tfile_list:\n\t\tpd.DataFrame: dataframe containing the file paths\n\tocr_processor:\n\t\tOCRProcessor: OCR processor\n\tpath_column:\n\t\tstr: column that contains the file path\n\t\"\"\"\n\t# go through every document in the list\n\tglobal ocr_results, status, SUPPORTED_EXTENSIONS\n\n\tfor _, row in file_list.iterrows():\n\t\tSAS.logMessage(f'Processing file: {row[path_column]}')\n\t\tfile_ok = True\n\t\tdone = False\n\t\tn_rows = 0\n\t\terror_type = ''\n\t\tmessage = ''\n\t\tstart = datetime.now()\n\n\t\t# perform the OCR\n\t\tif input_type.upper() == 'FILE':\n\t\t\ttry:\n\t\t\t\tfile_extension = row[path_column].split('.')[-1].lower()\n\t\t\t\tif file_extension not in SUPPORTED_EXTENSIONS:\n\t\t\t\t\tSAS.logMessage(f\"Unsupported file type: '.{file_extension}'. Supported file types are: {', '.join(SUPPORTED_EXTENSIONS)}\", 'warning')\n\t\t\t\t\terror_type = 'UnsupportedFileType'\n\t\t\t\t\tmessage = f\"Unsupported file type: {file_extension}. Supported file types are: {', '.join(SUPPORTED_EXTENSIONS)}\"\n\t\t\t\t\tfile_ok = False\n\t\t\t\twith open(row[path_column], 'rb') as file:\n\t\t\t\t\tdoc_data = file.read()\n\t\t\t\t\tbase64_encoded_data = base64.b64encode(doc_data)\n\t\t\t\t\tdocument = base64_encoded_data.decode('utf-8')\n\t\t\texcept FileNotFoundError as e:\n\t\t\t\tSAS.logMessage(f\"FILE NOT FOUND: {row[path_column]}. Please make sure the file paths are correct and the files are located on 'sasserver'. SAS Content is not supported!\", 'error')\n\t\t\t\terror_type = type(e).__name__\n\t\t\t\tmessage = str(e)\n\t\t\t\tfile_ok = False\n\n\t\telif input_type.upper() == 'URL':\n\t\t\tdocument = row[path_column]\n\n\t\tif file_ok == True:\n\t\t\ttry:\n\t\t\t\t# run ocr processing on the document\n\t\t\t\tSAS.logMessage(f'Start Processing of: {row[path_column]}')\n\t\t\t\tresult = ocr_processor.analyze_document(document=document)\n\t\t\t\tSAS.logMessage(f'Received OCR Result for file: {row[path_column]}')\n\n\t\t\t\t# parse the ocr result\n\t\t\t\tparsed_result = ocr_processor.parse_ocr_result(result=result)\n\t\t\t\tSAS.logMessage(f'Parsed Result Shape: {ocr_results.shape}, for file: {row[path_column]}')\n\n\t\t\t\t# add the file path to the result\n\t\t\t\tif not parsed_result.empty:\n\t\t\t\t\tparsed_result[path_column] = row[path_column]\n\n\t\t\t\t# append result to the overall result table\n\t\t\t\tif not parsed_result.empty:\n\t\t\t\t\tocr_results = pd.concat(\n\t\t\t\t\t\t[ocr_results, parsed_result], ignore_index=True)\n\t\t\t\t\tn_rows = parsed_result.shape[0]\n\t\t\t\tdone = True\n\n\t\t\texcept Exception as e:\n\t\t\t\terror_type = type(e).__name__\n\t\t\t\tmessage = str(e)\n\t\t\t\tSAS.logMessage(f'Warning: {error_type} - {message} - for {row[path_column]}', 'warning')\n\n\t\t# Post processing\n\t\t# if output_table_format = 'table', drop the path_column\n\t\tif ocr_type.upper() == 'TABLE' and table_output_format.upper() == 'TABLE':\n\t\t\tocr_results.drop(columns=[path_column], inplace=True)\n\n\t\t# save raw ocr results as json if save_json = True\n\t\tif done and save_json: # if save_json = True, save the azure ocr result as json\n\t\t\ttry:\n\t\t\t\twith open(f'{json_output_folder}/{os.path.basename(row[path_column]).split(\".\")[0]}_{ocr_type}OCR.json', 'w') as f:\n\t\t\t\t\tjson.dump(result, f)\n\t\t\texcept Exception as e:\n\t\t\t\terror_type = type(e).__name__\n\t\t\t\tmessage = str(e)\n\t\t\t\tSAS.logMessage(f'Warning: {error_type} - {message} for {row[path_column]}', 'warning')\n\n\t\t# update the status\n\t\tdoc_status = {'file': row[path_column],\n\t\t\t\t\t 'done': done,\n\t\t\t\t\t 'num_rows': n_rows,\n\t\t\t\t\t 'error_type': error_type,\n\t\t\t\t\t 'message': message,\n\t\t\t\t\t 'start': start,\n\t\t\t\t\t 'end': datetime.now(),\n\t\t\t\t\t 'duration_seconds': round((datetime.now() - start).total_seconds(), 3)\n\t\t\t\t\t }\n\n\t\tstatus = pd.concat([status, pd.DataFrame(\n\t\t\tdoc_status, index=[0])], ignore_index=True)\n\n\n# Parallel processing of the files\ndf_split = np.array_split(file_list, n_threads)\nthreads = []\n\nif file_list.shape[0] < n_threads:\n\tn_threads = file_list.shape[0]\n\nfor i in range(n_threads):\n\tpaths = df_split[i]\n\tthread = threading.Thread(target=process_files, args=(paths, ocr_processor, path_column))\n\tthreads.append(thread)\n\tthread.start()\n\tSAS.logMessage(f'Started thread {i+1} of {n_threads}!', 'info')\n\n# Wait for all threads to complete\nfor index, thread in enumerate(threads):\n\tthread.join()\n\tSAS.logMessage(f'Thread {index+1} of {n_threads} completed!', 'info')\n\nSAS.logMessage(f'FINISHED - Successfully processed {status[\"done\"].sum()} / {status.shape[0]} files!', 'info')\n\n# Output the results\nSAS.df2sd(ocr_results, SAS.symget(\"outputtable1\"))\nif output_status_table:\n\tSAS.logMessage(f'Output status table with {status.shape[0]} rows!', 'info')\n\tSAS.df2sd(status, SAS.symget(\"outputtable2\"))\n\tpass\n\nendsubmit;\nrun;\n\nproc python terminate; quit; "}}