From f79667825d69fc93ba4a455e89ed9de6c5380c4e Mon Sep 17 00:00:00 2001 From: Troy Simeon Taylor <44444967+troystaylor@users.noreply.github.com> Date: Wed, 24 Sep 2025 14:19:21 -0400 Subject: [PATCH 1/2] Add files via upload --- .../Power Fx Functions/ConnectorPackage.zip | Bin 0 -> 19362 bytes .../apiDefinition.swagger.json | 3530 +++++++++++++++++ .../Power Fx Functions/apiProperties.json | 11 + .../Power Fx Functions/readme.md | 87 + .../Power Fx Functions/script.csx | 651 +++ 5 files changed, 4279 insertions(+) create mode 100644 independent-publisher-connectors/Power Fx Functions/ConnectorPackage.zip create mode 100644 independent-publisher-connectors/Power Fx Functions/apiDefinition.swagger.json create mode 100644 independent-publisher-connectors/Power Fx Functions/apiProperties.json create mode 100644 independent-publisher-connectors/Power Fx Functions/readme.md create mode 100644 independent-publisher-connectors/Power Fx Functions/script.csx diff --git a/independent-publisher-connectors/Power Fx Functions/ConnectorPackage.zip b/independent-publisher-connectors/Power Fx Functions/ConnectorPackage.zip new file mode 100644 index 0000000000000000000000000000000000000000..bc23967fa96991442a1da720fb0f02044af6856b GIT binary patch literal 19362 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 literal 0 HcmV?d00001 diff --git a/independent-publisher-connectors/Power Fx Functions/apiDefinition.swagger.json b/independent-publisher-connectors/Power Fx Functions/apiDefinition.swagger.json new file mode 100644 index 0000000000..184bb6af07 --- /dev/null +++ b/independent-publisher-connectors/Power Fx Functions/apiDefinition.swagger.json @@ -0,0 +1,3530 @@ +{ + "swagger": "2.0", + "info": { + "title": "Power Fx Functions", + "description": "A comprehensive Power Fx function library providing 270+ mathematical, text, logical, date and time, table manipulation, conversion, and utility functions using custom C# script execution.", + "version": "1.0.0", + "contact": { + "name": "Troy Taylor", + "email": "troy@troystaylor.com" + } + }, + "x-ms-connector-metadata": [ + { + "propertyName": "Website", + "propertyValue": "https://troystaylor.com" + }, + { + "propertyName": "Privacy policy", + "propertyValue": "https://troystaylor.com/privacy" + }, + { + "propertyName": "Categories", + "propertyValue": "Data;Productivity" + } + ], + "host": "troystaylor.com", + "basePath": "/", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/evaluate": { + "post": { + "operationId": "EvaluateFormula", + "summary": "Evaluate Power Fx Formula", + "description": "Evaluates a Power Fx formula and returns the result with type information.", + "x-ms-summary": "Evaluate Formula", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EvaluateRequest" + } + } + ], + "responses": { + "200": { + "description": "Formula evaluation successful", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/EvaluateResponse" + } + }, + "400": { + "description": "Invalid formula or evaluation error", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/parse": { + "post": { + "operationId": "ParseFormula", + "summary": "Parse Power Fx Formula", + "description": "Parses a Power Fx formula and returns syntax tree information.", + "x-ms-summary": "Parse Formula", + "x-ms-visibility": "advanced", + "parameters": [ + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ParseRequest" + } + } + ], + "responses": { + "200": { + "description": "Formula parsing successful", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/ParseResponse" + } + }, + "400": { + "description": "Invalid formula syntax", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/validate": { + "post": { + "operationId": "ValidateFormula", + "summary": "Validate Power Fx Formula", + "description": "Validates a Power Fx formula and returns any syntax or semantic errors.", + "x-ms-summary": "Validate Formula", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ValidateRequest" + } + } + ], + "responses": { + "200": { + "description": "Formula validation completed", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/ValidateResponse" + } + } + } + } + }, + "/functions/math/{operation}": { + "post": { + "operationId": "ExecuteMathFunction", + "summary": "Execute Math Function", + "description": "Executes a mathematical function with provided arguments.", + "x-ms-summary": "Math Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "abs", + "power", + "sqrt", + "mod", + "round", + "sin", + "cos", + "tan", + "ln", + "log", + "exp", + "pi", + "int", + "roundup", + "rounddown", + "trunc", + "asin", + "acos", + "atan", + "atan2", + "acot", + "cot", + "radians", + "degrees", + "rand", + "randbetween", + "average", + "max", + "min", + "sum", + "count", + "counta", + "gcd", + "lcm", + "ceiling", + "floor", + "pmt", + "pv", + "fv", + "nper", + "rate" + ], + "x-ms-enum": { + "name": "MathOperation", + "modelAsString": true, + "values": [ + { + "value": "abs", + "displayName": "Absolute Value" + }, + { + "value": "power", + "displayName": "Power/Exponentiation" + }, + { + "value": "sqrt", + "displayName": "Square Root" + }, + { + "value": "mod", + "displayName": "Modulo" + }, + { + "value": "round", + "displayName": "Round" + }, + { + "value": "sin", + "displayName": "Sine" + }, + { + "value": "cos", + "displayName": "Cosine" + }, + { + "value": "tan", + "displayName": "Tangent" + }, + { + "value": "ln", + "displayName": "Natural Logarithm" + }, + { + "value": "log", + "displayName": "Logarithm" + }, + { + "value": "exp", + "displayName": "Exponential" + }, + { + "value": "pi", + "displayName": "Pi Constant" + }, + { + "value": "int", + "displayName": "Integer Part" + }, + { + "value": "roundup", + "displayName": "Round Up" + }, + { + "value": "rounddown", + "displayName": "Round Down" + }, + { + "value": "trunc", + "displayName": "Truncate" + }, + { + "value": "asin", + "displayName": "Arcsine" + }, + { + "value": "acos", + "displayName": "Arccosine" + }, + { + "value": "atan", + "displayName": "Arctangent" + }, + { + "value": "atan2", + "displayName": "Two-Argument Arctangent" + }, + { + "value": "acot", + "displayName": "Arccotangent" + }, + { + "value": "cot", + "displayName": "Cotangent" + }, + { + "value": "radians", + "displayName": "Degrees to Radians" + }, + { + "value": "degrees", + "displayName": "Radians to Degrees" + }, + { + "value": "rand", + "displayName": "Random Number" + }, + { + "value": "randbetween", + "displayName": "Random Between" + }, + { + "value": "average", + "displayName": "Average" + }, + { + "value": "max", + "displayName": "Maximum" + }, + { + "value": "min", + "displayName": "Minimum" + }, + { + "value": "sum", + "displayName": "Sum" + }, + { + "value": "count", + "displayName": "Count" + }, + { + "value": "counta", + "displayName": "Count Non-Empty" + }, + { + "value": "gcd", + "displayName": "Greatest Common Divisor" + }, + { + "value": "lcm", + "displayName": "Least Common Multiple" + }, + { + "value": "ceiling", + "displayName": "Ceiling" + }, + { + "value": "floor", + "displayName": "Floor" + } + ] + }, + "x-ms-summary": "Math Operation", + "description": "The mathematical operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/MathFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Math function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/text/{operation}": { + "post": { + "operationId": "ExecuteTextFunction", + "summary": "Execute Text Function", + "description": "Executes a text manipulation function with provided arguments.", + "x-ms-summary": "Text Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "left", + "right", + "mid", + "len", + "upper", + "lower", + "trim", + "find", + "replace", + "concatenate", + "split", + "trimends", + "proper", + "search", + "substitute", + "startswith", + "endswith", + "char", + "unichar", + "encodeurl", + "encodehtml", + "plaintext", + "concat", + "ismatch", + "match", + "matchall", + "rept", + "fixed", + "dollar" + ], + "x-ms-enum": { + "name": "TextOperation", + "modelAsString": true, + "values": [ + { + "value": "left", + "displayName": "Left Characters" + }, + { + "value": "right", + "displayName": "Right Characters" + }, + { + "value": "mid", + "displayName": "Middle Characters" + }, + { + "value": "len", + "displayName": "Length" + }, + { + "value": "upper", + "displayName": "Uppercase" + }, + { + "value": "lower", + "displayName": "Lowercase" + }, + { + "value": "trim", + "displayName": "Trim Whitespace" + }, + { + "value": "find", + "displayName": "Find Text" + }, + { + "value": "replace", + "displayName": "Replace Text" + }, + { + "value": "concatenate", + "displayName": "Concatenate" + }, + { + "value": "split", + "displayName": "Split Text" + }, + { + "value": "trimends", + "displayName": "Trim Both Ends" + }, + { + "value": "proper", + "displayName": "Proper Case" + }, + { + "value": "search", + "displayName": "Search Text" + }, + { + "value": "substitute", + "displayName": "Substitute Text" + }, + { + "value": "startswith", + "displayName": "Starts With" + }, + { + "value": "endswith", + "displayName": "Ends With" + }, + { + "value": "char", + "displayName": "Character from Code" + }, + { + "value": "unichar", + "displayName": "Unicode Character" + }, + { + "value": "encodeurl", + "displayName": "URL Encode" + }, + { + "value": "encodehtml", + "displayName": "HTML Encode" + }, + { + "value": "plaintext", + "displayName": "Plain Text" + }, + { + "value": "concat", + "displayName": "Concatenate" + }, + { + "value": "ismatch", + "displayName": "Is Match (Regex)" + }, + { + "value": "match", + "displayName": "Match (Regex)" + }, + { + "value": "matchall", + "displayName": "Match All (Regex)" + }, + { + "value": "rept", + "displayName": "Repeat Text" + }, + { + "value": "fixed", + "displayName": "Format Number" + }, + { + "value": "dollar", + "displayName": "Format Currency" + } + ] + }, + "x-ms-summary": "Text Operation", + "description": "The text operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TextFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Text function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/logical/{operation}": { + "post": { + "operationId": "ExecuteLogicalFunction", + "summary": "Execute Logical Function", + "description": "Executes a logical function with provided arguments.", + "x-ms-summary": "Logical Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "and", + "or", + "not", + "if", + "isblank", + "isempty", + "isnumeric", + "iserror", + "switch", + "iferror", + "error", + "isblankorerror", + "istoday", + "isutctoday" + ], + "x-ms-enum": { + "name": "LogicalOperation", + "modelAsString": true, + "values": [ + { + "value": "and", + "displayName": "Logical AND" + }, + { + "value": "or", + "displayName": "Logical OR" + }, + { + "value": "not", + "displayName": "Logical NOT" + }, + { + "value": "if", + "displayName": "If Condition" + }, + { + "value": "isblank", + "displayName": "Is Blank" + }, + { + "value": "isempty", + "displayName": "Is Empty" + }, + { + "value": "isnumeric", + "displayName": "Is Numeric" + }, + { + "value": "iserror", + "displayName": "Is Error" + }, + { + "value": "switch", + "displayName": "Switch Statement" + }, + { + "value": "iferror", + "displayName": "If Error" + }, + { + "value": "error", + "displayName": "Create Error" + }, + { + "value": "isblankorerror", + "displayName": "Is Blank or Error" + }, + { + "value": "istoday", + "displayName": "Is Today" + }, + { + "value": "isutctoday", + "displayName": "Is UTC Today" + } + ] + }, + "x-ms-summary": "Logical Operation", + "description": "The logical operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LogicalFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Logical function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/datetime/{operation}": { + "post": { + "operationId": "ExecuteDateTimeFunction", + "summary": "Execute Date Time Function", + "description": "Executes a date/time function with provided arguments.", + "x-ms-summary": "Date Time Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "now", + "today", + "year", + "month", + "day", + "hour", + "minute", + "second", + "dateadd", + "datediff", + "utcnow", + "utctoday", + "date", + "datetime", + "time", + "datevalue", + "datetimevalue", + "timevalue", + "weekday", + "edate", + "eomonth", + "weeknum", + "isoweeknum" + ], + "x-ms-enum": { + "name": "DateTimeOperation", + "modelAsString": true, + "values": [ + { + "value": "now", + "displayName": "Current Date/Time" + }, + { + "value": "today", + "displayName": "Today's Date" + }, + { + "value": "year", + "displayName": "Year" + }, + { + "value": "month", + "displayName": "Month" + }, + { + "value": "day", + "displayName": "Day" + }, + { + "value": "hour", + "displayName": "Hour" + }, + { + "value": "minute", + "displayName": "Minute" + }, + { + "value": "second", + "displayName": "Second" + }, + { + "value": "dateadd", + "displayName": "Add to Date" + }, + { + "value": "datediff", + "displayName": "Date Difference" + }, + { + "value": "utcnow", + "displayName": "Current UTC Date/Time" + }, + { + "value": "utctoday", + "displayName": "Today's UTC Date" + }, + { + "value": "date", + "displayName": "Create Date" + }, + { + "value": "datetime", + "displayName": "Create DateTime" + }, + { + "value": "time", + "displayName": "Create Time" + }, + { + "value": "datevalue", + "displayName": "Parse Date" + }, + { + "value": "datetimevalue", + "displayName": "Parse DateTime" + }, + { + "value": "timevalue", + "displayName": "Parse Time" + }, + { + "value": "weekday", + "displayName": "Day of Week" + }, + { + "value": "edate", + "displayName": "End Date" + }, + { + "value": "eomonth", + "displayName": "End of Month" + }, + { + "value": "weeknum", + "displayName": "Week Number" + }, + { + "value": "isoweeknum", + "displayName": "ISO Week Number" + } + ] + }, + "x-ms-summary": "Date Time Operation", + "description": "The date/time operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DateTimeFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Date/time function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/conversion/{operation}": { + "post": { + "operationId": "ExecuteConversionFunction", + "summary": "Execute Type Conversion Function", + "description": "Executes a type conversion function with provided arguments.", + "x-ms-summary": "Conversion Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "text", + "value", + "boolean", + "decimal", + "float", + "guid", + "astype" + ], + "x-ms-enum": { + "name": "ConversionOperation", + "modelAsString": true, + "values": [ + { + "value": "text", + "displayName": "Convert to Text" + }, + { + "value": "value", + "displayName": "Convert to Number" + }, + { + "value": "boolean", + "displayName": "Convert to Boolean" + }, + { + "value": "decimal", + "displayName": "Convert to Decimal" + }, + { + "value": "float", + "displayName": "Convert to Float" + }, + { + "value": "guid", + "displayName": "Generate GUID" + }, + { + "value": "astype", + "displayName": "Convert Type" + } + ] + }, + "x-ms-summary": "Conversion Operation", + "description": "The conversion operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ConversionFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Conversion function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/types/check": { + "post": { + "operationId": "CheckValueType", + "summary": "Check Value Type", + "description": "Determines the Power Fx type of a given value.", + "x-ms-summary": "Check Type", + "x-ms-visibility": "advanced", + "parameters": [ + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TypeCheckRequest" + } + } + ], + "responses": { + "200": { + "description": "Type check completed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/TypeCheckResponse" + } + } + } + } + }, + "/types/coerce": { + "post": { + "operationId": "CoerceValueType", + "summary": "Coerce Value Type", + "description": "Attempts to coerce a value to a specific Power Fx type.", + "x-ms-summary": "Coerce Type", + "x-ms-visibility": "advanced", + "parameters": [ + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TypeCoerceRequest" + } + } + ], + "responses": { + "200": { + "description": "Type coercion completed", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/TypeCoerceResponse" + } + }, + "400": { + "description": "Type coercion failed", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/table/{operation}": { + "post": { + "operationId": "ExecuteTableFunction", + "summary": "Execute Table Function", + "description": "Executes a table manipulation function with provided arguments.", + "x-ms-summary": "Table Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "addcolumns", + "filter", + "sort", + "groupby", + "summarize", + "distinct", + "firstn", + "lastn", + "table", + "sequence", + "countrows", + "countif", + "first", + "last", + "index", + "shuffle" + ], + "x-ms-enum": { + "name": "TableOperation", + "modelAsString": true, + "values": [ + { + "value": "addcolumns", + "displayName": "Add Columns" + }, + { + "value": "filter", + "displayName": "Filter Rows" + }, + { + "value": "sort", + "displayName": "Sort Table" + }, + { + "value": "groupby", + "displayName": "Group By" + }, + { + "value": "summarize", + "displayName": "Summarize" + }, + { + "value": "distinct", + "displayName": "Distinct Values" + }, + { + "value": "firstn", + "displayName": "First N Rows" + }, + { + "value": "lastn", + "displayName": "Last N Rows" + }, + { + "value": "table", + "displayName": "Create Table" + }, + { + "value": "sequence", + "displayName": "Number Sequence" + }, + { + "value": "countrows", + "displayName": "Count Rows" + }, + { + "value": "countif", + "displayName": "Count If" + }, + { + "value": "first", + "displayName": "First Row" + }, + { + "value": "last", + "displayName": "Last Row" + }, + { + "value": "index", + "displayName": "Index Row" + }, + { + "value": "shuffle", + "displayName": "Shuffle Rows" + } + ] + }, + "x-ms-summary": "Table Operation", + "description": "The table operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TableFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Table function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/utility/{operation}": { + "post": { + "operationId": "ExecuteUtilityFunction", + "summary": "Execute Utility Function", + "description": "Executes utility functions like encoding, JSON parsing, etc.", + "x-ms-summary": "Utility Function", + "x-ms-visibility": "advanced", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "rand", + "randbetween", + "sequence", + "shuffle", + "sort", + "reverse", + "coalesce", + "collect", + "clear", + "remove", + "removeif", + "update", + "updateif", + "patch", + "parsejson", + "dec2hex", + "hex2dec", + "blank", + "rgba", + "colorvalue", + "colorfade", + "forall", + "with" + ], + "x-ms-enum": { + "name": "UtilityOperation", + "modelAsString": true, + "values": [ + { + "value": "rand", + "displayName": "Random Number" + }, + { + "value": "randbetween", + "displayName": "Random Between" + }, + { + "value": "sequence", + "displayName": "Number Sequence" + }, + { + "value": "shuffle", + "displayName": "Shuffle Array" + }, + { + "value": "sort", + "displayName": "Sort Array" + }, + { + "value": "reverse", + "displayName": "Reverse Array" + }, + { + "value": "coalesce", + "displayName": "First Non-Empty" + }, + { + "value": "collect", + "displayName": "Collect Records" + }, + { + "value": "clear", + "displayName": "Clear Collection" + }, + { + "value": "remove", + "displayName": "Remove Records" + }, + { + "value": "removeif", + "displayName": "Remove If" + }, + { + "value": "update", + "displayName": "Update Records" + }, + { + "value": "updateif", + "displayName": "Update If" + }, + { + "value": "patch", + "displayName": "Patch Records" + }, + { + "value": "parsejson", + "displayName": "Parse JSON" + }, + { + "value": "dec2hex", + "displayName": "Decimal to Hex" + }, + { + "value": "hex2dec", + "displayName": "Hex to Decimal" + }, + { + "value": "blank", + "displayName": "Blank Value" + }, + { + "value": "rgba", + "displayName": "RGBA Color" + }, + { + "value": "colorvalue", + "displayName": "Color Value" + }, + { + "value": "colorfade", + "displayName": "Color Fade" + }, + { + "value": "forall", + "displayName": "For All Records" + }, + { + "value": "with", + "displayName": "With Record Context" + } + ] + }, + "x-ms-summary": "Utility Operation", + "description": "The utility operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UtilityFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Utility function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/date-parts/{part}": { + "post": { + "operationId": "ExtractDatePart", + "summary": "Extract Date Part", + "description": "Extracts a specific part from a date/time value.", + "x-ms-summary": "Extract Date Part", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "part", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "year", + "month", + "day", + "hour", + "minute", + "second", + "weekday", + "dayofyear", + "quarter", + "weeknum", + "isoweeknum" + ], + "x-ms-enum": { + "name": "DatePart", + "modelAsString": true, + "values": [ + { + "value": "year", + "displayName": "Year" + }, + { + "value": "month", + "displayName": "Month" + }, + { + "value": "day", + "displayName": "Day" + }, + { + "value": "hour", + "displayName": "Hour" + }, + { + "value": "minute", + "displayName": "Minute" + }, + { + "value": "second", + "displayName": "Second" + }, + { + "value": "weekday", + "displayName": "Day of Week" + }, + { + "value": "dayofyear", + "displayName": "Day of Year" + }, + { + "value": "quarter", + "displayName": "Quarter" + }, + { + "value": "weeknum", + "displayName": "Week Number" + }, + { + "value": "isoweeknum", + "displayName": "ISO Week Number" + } + ] + }, + "x-ms-summary": "Date Part", + "description": "The specific date part to extract.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DatePartRequest" + } + } + ], + "responses": { + "200": { + "description": "Date part extracted successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid date or part", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/text-transform/{transform}": { + "post": { + "operationId": "TransformText", + "summary": "Transform Text", + "description": "Applies a specific text transformation.", + "x-ms-summary": "Transform Text", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "transform", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "upper", + "lower", + "proper", + "trim", + "trimends", + "trimstart", + "trimend", + "reverse" + ], + "x-ms-enum": { + "name": "TextTransform", + "modelAsString": true, + "values": [ + { + "value": "upper", + "displayName": "Uppercase" + }, + { + "value": "lower", + "displayName": "Lowercase" + }, + { + "value": "proper", + "displayName": "Proper Case" + }, + { + "value": "trim", + "displayName": "Trim Whitespace" + }, + { + "value": "trimends", + "displayName": "Trim Both Ends" + }, + { + "value": "trimstart", + "displayName": "Trim Start" + }, + { + "value": "trimend", + "displayName": "Trim End" + }, + { + "value": "reverse", + "displayName": "Reverse Text" + } + ] + }, + "x-ms-summary": "Text Transform", + "description": "The text transformation to apply.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TextTransformRequest" + } + } + ], + "responses": { + "200": { + "description": "Text transformed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid text or transform", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/math-round/{method}": { + "post": { + "operationId": "RoundNumber", + "summary": "Round Number", + "description": "Rounds a number using the specified method.", + "x-ms-summary": "Round Number", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "method", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "round", + "roundup", + "rounddown", + "trunc", + "int", + "ceiling", + "floor" + ], + "x-ms-enum": { + "name": "RoundingMethod", + "modelAsString": true, + "values": [ + { + "value": "round", + "displayName": "Round" + }, + { + "value": "roundup", + "displayName": "Round Up" + }, + { + "value": "rounddown", + "displayName": "Round Down" + }, + { + "value": "trunc", + "displayName": "Truncate" + }, + { + "value": "int", + "displayName": "Integer Part" + }, + { + "value": "ceiling", + "displayName": "Ceiling" + }, + { + "value": "floor", + "displayName": "Floor" + } + ] + }, + "x-ms-summary": "Rounding Method", + "description": "The rounding method to use.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/RoundingRequest" + } + } + ], + "responses": { + "200": { + "description": "Number rounded successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid number or method", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/math-trig/{function}": { + "post": { + "operationId": "TrigFunction", + "summary": "Trigonometric Function", + "description": "Executes a trigonometric function.", + "x-ms-summary": "Trigonometric Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "function", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "sin", + "cos", + "tan", + "asin", + "acos", + "atan", + "atan2", + "cot", + "acot", + "sec", + "csc", + "sinh", + "cosh", + "tanh" + ], + "x-ms-enum": { + "name": "TrigFunction", + "modelAsString": true, + "values": [ + { + "value": "sin", + "displayName": "Sine" + }, + { + "value": "cos", + "displayName": "Cosine" + }, + { + "value": "tan", + "displayName": "Tangent" + }, + { + "value": "asin", + "displayName": "Arcsine" + }, + { + "value": "acos", + "displayName": "Arccosine" + }, + { + "value": "atan", + "displayName": "Arctangent" + }, + { + "value": "atan2", + "displayName": "Two-Argument Arctangent" + }, + { + "value": "cot", + "displayName": "Cotangent" + }, + { + "value": "acot", + "displayName": "Arccotangent" + }, + { + "value": "sec", + "displayName": "Secant" + }, + { + "value": "csc", + "displayName": "Cosecant" + }, + { + "value": "sinh", + "displayName": "Hyperbolic Sine" + }, + { + "value": "cosh", + "displayName": "Hyperbolic Cosine" + }, + { + "value": "tanh", + "displayName": "Hyperbolic Tangent" + } + ] + }, + "x-ms-summary": "Trigonometric Function", + "description": "The trigonometric function to execute.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TrigFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Trigonometric function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid arguments", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/text-search/{type}": { + "post": { + "operationId": "SearchText", + "summary": "Search Text", + "description": "Searches for text using the specified method.", + "x-ms-summary": "Search Text", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "type", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "find", + "search", + "startswith", + "endswith", + "contains", + "exact" + ], + "x-ms-enum": { + "name": "TextSearchType", + "modelAsString": true, + "values": [ + { + "value": "find", + "displayName": "Find Position" + }, + { + "value": "search", + "displayName": "Search Text" + }, + { + "value": "startswith", + "displayName": "Starts With" + }, + { + "value": "endswith", + "displayName": "Ends With" + }, + { + "value": "contains", + "displayName": "Contains Text" + }, + { + "value": "exact", + "displayName": "Exact Match" + } + ] + }, + "x-ms-summary": "Search Type", + "description": "The type of text search to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TextSearchRequest" + } + } + ], + "responses": { + "200": { + "description": "Text search completed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid search parameters", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/logical-condition/{type}": { + "post": { + "operationId": "EvaluateCondition", + "summary": "Evaluate Logical Condition", + "description": "Evaluates a logical condition using the specified type.", + "x-ms-summary": "Evaluate Condition", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "type", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "and", + "or", + "not", + "xor", + "nand", + "nor" + ], + "x-ms-enum": { + "name": "LogicalConditionType", + "modelAsString": true, + "values": [ + { + "value": "and", + "displayName": "Logical AND" + }, + { + "value": "or", + "displayName": "Logical OR" + }, + { + "value": "not", + "displayName": "Logical NOT" + }, + { + "value": "xor", + "displayName": "Exclusive OR" + }, + { + "value": "nand", + "displayName": "NOT AND" + }, + { + "value": "nor", + "displayName": "NOT OR" + } + ] + }, + "x-ms-summary": "Condition Type", + "description": "The type of logical condition to evaluate.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/LogicalConditionRequest" + } + } + ], + "responses": { + "200": { + "description": "Logical condition evaluated successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid condition parameters", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/type-check/{check}": { + "post": { + "operationId": "CheckValueProperty", + "summary": "Check Value Property", + "description": "Checks a specific property of a value.", + "x-ms-summary": "Check Value Property", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "check", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "isblank", + "isempty", + "isnumeric", + "istext", + "islogical", + "iserror", + "isdate", + "istime", + "isblankorerror", + "istoday", + "isutctoday" + ], + "x-ms-enum": { + "name": "TypeCheck", + "modelAsString": true, + "values": [ + { + "value": "isblank", + "displayName": "Is Blank" + }, + { + "value": "isempty", + "displayName": "Is Empty" + }, + { + "value": "isnumeric", + "displayName": "Is Numeric" + }, + { + "value": "istext", + "displayName": "Is Text" + }, + { + "value": "islogical", + "displayName": "Is Logical" + }, + { + "value": "iserror", + "displayName": "Is Error" + }, + { + "value": "isdate", + "displayName": "Is Date" + }, + { + "value": "istime", + "displayName": "Is Time" + }, + { + "value": "isblankorerror", + "displayName": "Is Blank or Error" + }, + { + "value": "istoday", + "displayName": "Is Today" + }, + { + "value": "isutctoday", + "displayName": "Is UTC Today" + } + ] + }, + "x-ms-summary": "Check Type", + "description": "The type of check to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TypeCheckSpecificRequest" + } + } + ], + "responses": { + "200": { + "description": "Value check completed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid check parameters", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/json/{operation}": { + "post": { + "operationId": "ExecuteJSONFunction", + "summary": "Execute JSON Function", + "description": "Executes JSON parsing, formatting, and manipulation functions.", + "x-ms-summary": "JSON Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "parsejson", + "json", + "formatjson", + "jsonextract", + "jsonpath", + "isvalidjson", + "jsonmerge", + "jsonarray", + "jsonobject", + "jsonkeys", + "jsonvalues" + ], + "x-ms-enum": { + "name": "JSONOperation", + "modelAsString": true, + "values": [ + { + "value": "parsejson", + "displayName": "Parse JSON" + }, + { + "value": "json", + "displayName": "Create JSON" + }, + { + "value": "formatjson", + "displayName": "Format JSON" + }, + { + "value": "jsonextract", + "displayName": "Extract JSON Property" + }, + { + "value": "jsonpath", + "displayName": "JSON Path Query" + }, + { + "value": "isvalidjson", + "displayName": "Validate JSON" + }, + { + "value": "jsonmerge", + "displayName": "Merge JSON Objects" + }, + { + "value": "jsonarray", + "displayName": "Create JSON Array" + }, + { + "value": "jsonobject", + "displayName": "Create JSON Object" + }, + { + "value": "jsonkeys", + "displayName": "Get JSON Keys" + }, + { + "value": "jsonvalues", + "displayName": "Get JSON Values" + } + ] + }, + "x-ms-summary": "JSON Operation", + "description": "The JSON operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/JSONFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "JSON function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid JSON or operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/table-advanced/{operation}": { + "post": { + "operationId": "ExecuteAdvancedTableFunction", + "summary": "Execute Advanced Table Function", + "description": "Executes advanced table operations like joins, pivots, and complex transformations.", + "x-ms-summary": "Advanced Table Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "join", + "leftjoin", + "rightjoin", + "innerjoin", + "outerjoin", + "crossjoin", + "pivot", + "unpivot", + "transpose", + "lookup", + "xlookup", + "relate", + "unrelate", + "merge", + "append", + "union", + "intersect", + "except", + "dropcolumns", + "renamecolumns", + "showcolumns" + ], + "x-ms-enum": { + "name": "AdvancedTableOperation", + "modelAsString": true, + "values": [ + { + "value": "join", + "displayName": "Join Tables" + }, + { + "value": "leftjoin", + "displayName": "Left Join" + }, + { + "value": "rightjoin", + "displayName": "Right Join" + }, + { + "value": "innerjoin", + "displayName": "Inner Join" + }, + { + "value": "outerjoin", + "displayName": "Outer Join" + }, + { + "value": "crossjoin", + "displayName": "Cross Join" + }, + { + "value": "pivot", + "displayName": "Pivot Table" + }, + { + "value": "unpivot", + "displayName": "Unpivot Table" + }, + { + "value": "transpose", + "displayName": "Transpose Table" + }, + { + "value": "lookup", + "displayName": "Lookup Value" + }, + { + "value": "xlookup", + "displayName": "Extended Lookup" + }, + { + "value": "relate", + "displayName": "Create Relationship" + }, + { + "value": "unrelate", + "displayName": "Remove Relationship" + }, + { + "value": "merge", + "displayName": "Merge Tables" + }, + { + "value": "append", + "displayName": "Append Tables" + }, + { + "value": "union", + "displayName": "Union Tables" + }, + { + "value": "intersect", + "displayName": "Intersect Tables" + }, + { + "value": "except", + "displayName": "Except Tables" + }, + { + "value": "dropcolumns", + "displayName": "Drop Columns" + }, + { + "value": "renamecolumns", + "displayName": "Rename Columns" + }, + { + "value": "showcolumns", + "displayName": "Show Columns" + } + ] + }, + "x-ms-summary": "Advanced Table Operation", + "description": "The advanced table operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AdvancedTableFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Advanced table function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid table operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/color/{operation}": { + "post": { + "operationId": "ExecuteColorFunction", + "summary": "Execute Color Function", + "description": "Executes color manipulation and conversion functions.", + "x-ms-summary": "Color Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "rgba", + "rgb", + "hsl", + "hsv", + "colorvalue", + "colorfade", + "colorbrightness", + "colorcontrast", + "colormix", + "colorinvert", + "hex2color", + "color2hex", + "colorred", + "colorgreen", + "colorblue", + "coloralpha" + ], + "x-ms-enum": { + "name": "ColorOperation", + "modelAsString": true, + "values": [ + { + "value": "rgba", + "displayName": "RGBA Color" + }, + { + "value": "rgb", + "displayName": "RGB Color" + }, + { + "value": "hsl", + "displayName": "HSL Color" + }, + { + "value": "hsv", + "displayName": "HSV Color" + }, + { + "value": "colorvalue", + "displayName": "Parse Color Value" + }, + { + "value": "colorfade", + "displayName": "Fade Color" + }, + { + "value": "colorbrightness", + "displayName": "Adjust Brightness" + }, + { + "value": "colorcontrast", + "displayName": "Color Contrast" + }, + { + "value": "colormix", + "displayName": "Mix Colors" + }, + { + "value": "colorinvert", + "displayName": "Invert Color" + }, + { + "value": "hex2color", + "displayName": "Hex to Color" + }, + { + "value": "color2hex", + "displayName": "Color to Hex" + }, + { + "value": "colorred", + "displayName": "Red Component" + }, + { + "value": "colorgreen", + "displayName": "Green Component" + }, + { + "value": "colorblue", + "displayName": "Blue Component" + }, + { + "value": "coloralpha", + "displayName": "Alpha Component" + } + ] + }, + "x-ms-summary": "Color Operation", + "description": "The color operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ColorFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Color function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid color operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/encoding/{operation}": { + "post": { + "operationId": "ExecuteEncodingFunction", + "summary": "Execute Encoding Function", + "description": "Executes data encoding and decoding functions.", + "x-ms-summary": "Encoding Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "base64encode", + "base64decode", + "urlencode", + "urldecode", + "htmlencode", + "htmldecode", + "xmlencode", + "xmldecode", + "utf8encode", + "utf8decode", + "hash", + "md5", + "sha1", + "sha256" + ], + "x-ms-enum": { + "name": "EncodingOperation", + "modelAsString": true, + "values": [ + { + "value": "base64encode", + "displayName": "Base64 Encode" + }, + { + "value": "base64decode", + "displayName": "Base64 Decode" + }, + { + "value": "urlencode", + "displayName": "URL Encode" + }, + { + "value": "urldecode", + "displayName": "URL Decode" + }, + { + "value": "htmlencode", + "displayName": "HTML Encode" + }, + { + "value": "htmldecode", + "displayName": "HTML Decode" + }, + { + "value": "xmlencode", + "displayName": "XML Encode" + }, + { + "value": "xmldecode", + "displayName": "XML Decode" + }, + { + "value": "utf8encode", + "displayName": "UTF-8 Encode" + }, + { + "value": "utf8decode", + "displayName": "UTF-8 Decode" + }, + { + "value": "hash", + "displayName": "Hash Value" + }, + { + "value": "md5", + "displayName": "MD5 Hash" + }, + { + "value": "sha1", + "displayName": "SHA1 Hash" + }, + { + "value": "sha256", + "displayName": "SHA256 Hash" + } + ] + }, + "x-ms-summary": "Encoding Operation", + "description": "The encoding operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EncodingFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Encoding function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid encoding operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/functions/statistics/{operation}": { + "post": { + "operationId": "ExecuteStatisticsFunction", + "summary": "Execute Statistics Function", + "description": "Executes advanced statistical analysis functions.", + "x-ms-summary": "Statistics Function", + "x-ms-visibility": "important", + "parameters": [ + { + "name": "operation", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "stdev", + "stdevp", + "var", + "varp", + "median", + "mode", + "percentile", + "quartile", + "correlation", + "covariance", + "regression", + "slope", + "intercept", + "rsquared", + "frequency", + "rank", + "percentrank", + "zscore", + "confidence" + ], + "x-ms-enum": { + "name": "StatisticsOperation", + "modelAsString": true, + "values": [ + { + "value": "stdev", + "displayName": "Standard Deviation" + }, + { + "value": "stdevp", + "displayName": "Population Standard Deviation" + }, + { + "value": "var", + "displayName": "Variance" + }, + { + "value": "varp", + "displayName": "Population Variance" + }, + { + "value": "median", + "displayName": "Median" + }, + { + "value": "mode", + "displayName": "Mode" + }, + { + "value": "percentile", + "displayName": "Percentile" + }, + { + "value": "quartile", + "displayName": "Quartile" + }, + { + "value": "correlation", + "displayName": "Correlation" + }, + { + "value": "covariance", + "displayName": "Covariance" + }, + { + "value": "regression", + "displayName": "Linear Regression" + }, + { + "value": "slope", + "displayName": "Regression Slope" + }, + { + "value": "intercept", + "displayName": "Regression Intercept" + }, + { + "value": "rsquared", + "displayName": "R-Squared" + }, + { + "value": "frequency", + "displayName": "Frequency" + }, + { + "value": "rank", + "displayName": "Rank" + }, + { + "value": "percentrank", + "displayName": "Percent Rank" + }, + { + "value": "zscore", + "displayName": "Z-Score" + }, + { + "value": "confidence", + "displayName": "Confidence Interval" + } + ] + }, + "x-ms-summary": "Statistics Operation", + "description": "The statistical operation to perform.", + "x-ms-url-encoding": "single" + }, + { + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/StatisticsFunctionRequest" + } + } + ], + "responses": { + "200": { + "description": "Statistics function executed successfully", + "x-ms-summary": "Success", + "schema": { + "$ref": "#/definitions/FunctionResponse" + } + }, + "400": { + "description": "Invalid statistics operation", + "x-ms-summary": "Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + } + }, + "definitions": { + "PowerFxValue": { + "type": "object", + "properties": { + "value": { + "description": "The actual value (can be string, number, boolean, object, or array)." + }, + "type": { + "type": "string", + "enum": [ + "Text", + "Number", + "Boolean", + "Date", + "DateTime", + "Time", + "Record", + "Table", + "Blank", + "Error" + ], + "description": "The Power Fx type of the value." + }, + "isError": { + "type": "boolean", + "description": "Whether this value represents an error." + }, + "errorMessage": { + "type": "string", + "description": "Error message if isError is true." + } + }, + "required": [ + "value", + "type" + ] + }, + "EvaluateRequest": { + "type": "object", + "properties": { + "formula": { + "type": "string", + "description": "The Power Fx formula to evaluate.", + "x-ms-summary": "Formula" + }, + "context": { + "type": "object", + "description": "Context variables and their values.", + "x-ms-summary": "Context Variables", + "additionalProperties": { + "$ref": "#/definitions/PowerFxValue" + } + }, + "options": { + "$ref": "#/definitions/EvaluationOptions" + } + }, + "required": [ + "formula" + ] + }, + "EvaluateResponse": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/PowerFxValue" + }, + "executionTimeMs": { + "type": "number", + "description": "Execution time in milliseconds" + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Any warnings generated during evaluation" + } + }, + "required": [ + "result" + ] + }, + "ParseRequest": { + "type": "object", + "properties": { + "formula": { + "type": "string", + "description": "The Power Fx formula to parse", + "x-ms-summary": "Formula" + }, + "options": { + "$ref": "#/definitions/ParseOptions" + } + }, + "required": [ + "formula" + ] + }, + "ParseResponse": { + "type": "object", + "properties": { + "isValid": { + "type": "boolean", + "description": "Whether the formula parsed successfully" + }, + "syntaxTree": { + "type": "object", + "description": "The parsed syntax tree representation" + }, + "tokens": { + "type": "array", + "items": { + "$ref": "#/definitions/Token" + }, + "description": "The tokens identified during parsing" + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/definitions/ParseError" + }, + "description": "Any parsing errors" + } + } + }, + "ValidateRequest": { + "type": "object", + "properties": { + "formula": { + "type": "string", + "description": "The Power Fx formula to validate", + "x-ms-summary": "Formula" + }, + "context": { + "type": "object", + "description": "Context for type checking", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "formula" + ] + }, + "ValidateResponse": { + "type": "object", + "properties": { + "isValid": { + "type": "boolean", + "description": "Whether the formula is valid" + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/definitions/ValidationError" + }, + "description": "Validation errors if any" + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/ValidationWarning" + }, + "description": "Validation warnings if any" + }, + "returnType": { + "type": "string", + "description": "The expected return type of the formula" + } + } + }, + "MathFunctionRequest": { + "type": "object", + "properties": { + "arguments": { + "type": "array", + "items": { + "type": "number" + }, + "description": "Numeric arguments for the math function", + "x-ms-summary": "Arguments" + } + }, + "required": [ + "arguments" + ] + }, + "TextFunctionRequest": { + "type": "object", + "properties": { + "arguments": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Text arguments for the text function", + "x-ms-summary": "Arguments" + }, + "numericArgs": { + "type": "array", + "items": { + "type": "number" + }, + "description": "Numeric arguments (for functions like Mid, Left, Right)", + "x-ms-summary": "Numeric Arguments" + } + }, + "required": [ + "arguments" + ] + }, + "LogicalFunctionRequest": { + "type": "object", + "properties": { + "arguments": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Arguments for the logical function", + "x-ms-summary": "Arguments" + } + }, + "required": [ + "arguments" + ] + }, + "DateTimeFunctionRequest": { + "type": "object", + "properties": { + "arguments": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Arguments for the date/time function", + "x-ms-summary": "Arguments" + } + }, + "required": [ + "arguments" + ] + }, + "ConversionFunctionRequest": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/PowerFxValue" + }, + "targetType": { + "type": "string", + "description": "Target type for conversion", + "x-ms-summary": "Target Type" + }, + "format": { + "type": "string", + "description": "Format specifier (currency, percentage, custom format string)", + "x-ms-summary": "Format" + }, + "locale": { + "type": "string", + "description": "Locale for cultural formatting (e.g., 'en-US', 'fr-FR')", + "x-ms-summary": "Locale" + } + }, + "required": [ + "value" + ] + }, + "FunctionResponse": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/PowerFxValue" + }, + "executionTimeMs": { + "type": "number", + "description": "Execution time in milliseconds" + } + } + }, + "TypeCheckRequest": { + "type": "object", + "properties": { + "value": { + "description": "The value to check the type of" + } + }, + "required": [ + "value" + ] + }, + "TypeCheckResponse": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "The detected Power Fx type" + }, + "isValid": { + "type": "boolean", + "description": "Whether the value is valid for Power Fx" + }, + "details": { + "type": "object", + "description": "Additional type information" + } + } + }, + "TypeCoerceRequest": { + "type": "object", + "properties": { + "value": { + "description": "The value to coerce" + }, + "targetType": { + "type": "string", + "enum": [ + "Text", + "Number", + "Boolean", + "Date", + "DateTime", + "Time" + ], + "description": "The target type to coerce to" + } + }, + "required": [ + "value", + "targetType" + ] + }, + "TypeCoerceResponse": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/PowerFxValue" + }, + "success": { + "type": "boolean", + "description": "Whether coercion was successful" + } + } + }, + "EvaluationOptions": { + "type": "object", + "properties": { + "numberIsFloat": { + "type": "boolean", + "description": "Whether to treat numbers as floats instead of decimals" + }, + "allowSideEffects": { + "type": "boolean", + "description": "Whether to allow functions with side effects" + }, + "timeout": { + "type": "number", + "description": "Evaluation timeout in milliseconds" + } + } + }, + "ParseOptions": { + "type": "object", + "properties": { + "includeTokens": { + "type": "boolean", + "description": "Whether to include token information in the response" + }, + "includeSyntaxTree": { + "type": "boolean", + "description": "Whether to include the full syntax tree" + } + } + }, + "Token": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Token type" + }, + "value": { + "type": "string", + "description": "Token value" + }, + "start": { + "type": "number", + "description": "Start position in formula" + }, + "end": { + "type": "number", + "description": "End position in formula" + } + } + }, + "ParseError": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Error message" + }, + "start": { + "type": "number", + "description": "Error start position" + }, + "end": { + "type": "number", + "description": "Error end position" + }, + "severity": { + "type": "string", + "enum": [ + "Error", + "Warning", + "Info" + ], + "description": "Error severity" + } + } + }, + "ValidationError": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Error message" + }, + "start": { + "type": "number", + "description": "Error start position" + }, + "end": { + "type": "number", + "description": "Error end position" + }, + "code": { + "type": "string", + "description": "Error code" + } + } + }, + "ValidationWarning": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Warning message" + }, + "start": { + "type": "number", + "description": "Warning start position" + }, + "end": { + "type": "number", + "description": "Warning end position" + }, + "code": { + "type": "string", + "description": "Warning code" + } + } + }, + "ErrorResponse": { + "type": "object", + "properties": { + "error": { + "type": "string", + "description": "Error message" + }, + "code": { + "type": "string", + "description": "Error code" + }, + "details": { + "type": "object", + "description": "Additional error details" + } + }, + "required": [ + "error" + ] + }, + "TableFunctionRequest": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Table data as array of objects", + "x-ms-summary": "Table Data" + }, + "arguments": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Additional arguments for the table function", + "x-ms-summary": "Arguments" + }, + "columns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Column names for table operations", + "x-ms-summary": "Columns" + } + } + }, + "UtilityFunctionRequest": { + "type": "object", + "properties": { + "arguments": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Arguments for the utility function", + "x-ms-summary": "Arguments" + }, + "options": { + "type": "object", + "description": "Additional options for the utility function", + "x-ms-summary": "Options" + }, + "table": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Table data for ForAll operations", + "x-ms-summary": "Table" + }, + "record": { + "type": "object", + "description": "Record data for With operations", + "x-ms-summary": "Record" + }, + "expression": { + "type": "string", + "description": "Expression to evaluate for ForAll/With operations", + "x-ms-summary": "Expression" + } + }, + "required": [ + "arguments" + ] + }, + "DatePartRequest": { + "type": "object", + "properties": { + "dateValue": { + "$ref": "#/definitions/PowerFxValue" + } + }, + "required": [ + "dateValue" + ] + }, + "TextTransformRequest": { + "type": "object", + "properties": { + "text": { + "$ref": "#/definitions/PowerFxValue" + }, + "options": { + "type": "object", + "description": "Additional transformation options", + "x-ms-summary": "Options" + } + }, + "required": [ + "text" + ] + }, + "RoundingRequest": { + "type": "object", + "properties": { + "number": { + "$ref": "#/definitions/PowerFxValue" + }, + "decimals": { + "$ref": "#/definitions/PowerFxValue" + } + }, + "required": [ + "number" + ] + }, + "TrigFunctionRequest": { + "type": "object", + "properties": { + "angle": { + "$ref": "#/definitions/PowerFxValue" + }, + "secondAngle": { + "$ref": "#/definitions/PowerFxValue" + }, + "angleUnit": { + "type": "string", + "enum": [ + "radians", + "degrees" + ], + "description": "Unit of the angle (default: radians)", + "x-ms-summary": "Angle Unit" + } + }, + "required": [ + "angle" + ] + }, + "TextSearchRequest": { + "type": "object", + "properties": { + "text": { + "$ref": "#/definitions/PowerFxValue" + }, + "searchFor": { + "$ref": "#/definitions/PowerFxValue" + }, + "startPosition": { + "$ref": "#/definitions/PowerFxValue" + }, + "caseSensitive": { + "type": "boolean", + "description": "Whether search is case sensitive", + "x-ms-summary": "Case Sensitive" + } + }, + "required": [ + "text", + "searchFor" + ] + }, + "LogicalConditionRequest": { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Values to evaluate in the logical condition", + "x-ms-summary": "Values" + } + }, + "required": [ + "values" + ] + }, + "TypeCheckSpecificRequest": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/PowerFxValue" + } + }, + "required": [ + "value" + ] + }, + "JSONFunctionRequest": { + "type": "object", + "properties": { + "jsonData": { + "$ref": "#/definitions/PowerFxValue" + }, + "jsonPath": { + "$ref": "#/definitions/PowerFxValue" + }, + "arguments": { + "type": "array", + "items": { + "$ref": "#/definitions/PowerFxValue" + }, + "description": "Additional arguments for the JSON function", + "x-ms-summary": "Arguments" + }, + "options": { + "type": "object", + "description": "JSON processing options", + "x-ms-summary": "Options" + } + }, + "required": [ + "jsonData" + ] + }, + "AdvancedTableFunctionRequest": { + "type": "object", + "properties": { + "leftTable": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Left table data for join operations", + "x-ms-summary": "Left Table" + }, + "rightTable": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Right table data for join operations", + "x-ms-summary": "Right Table" + }, + "joinColumns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Columns to join on", + "x-ms-summary": "Join Columns" + }, + "pivotColumns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Columns for pivot operations", + "x-ms-summary": "Pivot Columns" + }, + "valueColumns": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Value columns for aggregation", + "x-ms-summary": "Value Columns" + }, + "lookupKey": { + "$ref": "#/definitions/PowerFxValue" + }, + "lookupColumn": { + "type": "string", + "description": "Column to lookup in", + "x-ms-summary": "Lookup Column" + }, + "returnColumn": { + "type": "string", + "description": "Column to return from lookup", + "x-ms-summary": "Return Column" + } + } + }, + "ColorFunctionRequest": { + "type": "object", + "properties": { + "color": { + "$ref": "#/definitions/PowerFxValue" + }, + "red": { + "$ref": "#/definitions/PowerFxValue" + }, + "green": { + "$ref": "#/definitions/PowerFxValue" + }, + "blue": { + "$ref": "#/definitions/PowerFxValue" + }, + "alpha": { + "$ref": "#/definitions/PowerFxValue" + }, + "hue": { + "$ref": "#/definitions/PowerFxValue" + }, + "saturation": { + "$ref": "#/definitions/PowerFxValue" + }, + "lightness": { + "$ref": "#/definitions/PowerFxValue" + }, + "amount": { + "$ref": "#/definitions/PowerFxValue" + }, + "color2": { + "$ref": "#/definitions/PowerFxValue" + } + } + }, + "EncodingFunctionRequest": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/PowerFxValue" + }, + "encoding": { + "type": "string", + "enum": [ + "utf8", + "ascii", + "unicode" + ], + "description": "Text encoding format", + "x-ms-summary": "Encoding" + }, + "algorithm": { + "type": "string", + "enum": [ + "md5", + "sha1", + "sha256", + "sha512" + ], + "description": "Hash algorithm for hash functions", + "x-ms-summary": "Algorithm" + }, + "options": { + "type": "object", + "description": "Encoding options", + "x-ms-summary": "Options" + } + }, + "required": [ + "data" + ] + }, + "StatisticsFunctionRequest": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "number" + }, + "description": "Numeric data for statistical analysis", + "x-ms-summary": "Data" + }, + "xValues": { + "type": "array", + "items": { + "type": "number" + }, + "description": "X values for correlation and regression", + "x-ms-summary": "X Values" + }, + "yValues": { + "type": "array", + "items": { + "type": "number" + }, + "description": "Y values for correlation and regression", + "x-ms-summary": "Y Values" + }, + "percentile": { + "type": "number", + "description": "Percentile value (0-1)", + "x-ms-summary": "Percentile" + }, + "confidence": { + "type": "number", + "description": "Confidence level (0-1)", + "x-ms-summary": "Confidence Level" + }, + "sortOrder": { + "type": "string", + "enum": [ + "ascending", + "descending" + ], + "description": "Sort order for ranking", + "x-ms-summary": "Sort Order" + } + }, + "required": [ + "data" + ] + } + } +} \ No newline at end of file diff --git a/independent-publisher-connectors/Power Fx Functions/apiProperties.json b/independent-publisher-connectors/Power Fx Functions/apiProperties.json new file mode 100644 index 0000000000..d72b14b372 --- /dev/null +++ b/independent-publisher-connectors/Power Fx Functions/apiProperties.json @@ -0,0 +1,11 @@ +{ + "displayName": "Power Fx Functions", + "description": "A comprehensive Power Fx function library providing 270+ mathematical, text, logical, date and time, table manipulation, conversion, and utility functions for Power Platform applications with custom C# script execution.", + "iconBrandColor": "#da3b01", + "capabilities": [ + "actions" + ], + "policyTemplateInstances": [], + "publisher": "Troy Taylor", + "stackOwner": "Troy Taylor" +} \ No newline at end of file diff --git a/independent-publisher-connectors/Power Fx Functions/readme.md b/independent-publisher-connectors/Power Fx Functions/readme.md new file mode 100644 index 0000000000..dbc0a3a6f6 --- /dev/null +++ b/independent-publisher-connectors/Power Fx Functions/readme.md @@ -0,0 +1,87 @@ +# Power Fx Functions +A comprehensive Power Fx function library providing 270+ mathematical, text, logical, date and time, table manipulation, conversion, and utility functions using custom C# script execution. + +## Publisher: Troy Taylor + +## Prerequisites +You will need to use this connector in Power Platform environments that support custom connectors with code components. + +## Obtaining Credentials +This connector uses the hosting environment's authentication. No additional credentials are required. + +## Supported Operations + +### Evaluate Power Fx Formula +Evaluates a Power Fx formula and returns the result with type information. + +### Parse Power Fx Formula +Parses a Power Fx formula and returns syntax tree information. + +### Validate Power Fx Formula +Validates a Power Fx formula and returns any syntax or semantic errors. + +### Execute Math Function +Executes mathematical functions including: abs, power, sqrt, mod, round, sin, cos, tan, ln, log, exp, pi, int, roundup, rounddown, trunc, asin, acos, atan, atan2, acot, cot, radians, degrees, rand, randbetween, average, max, min, sum, count, counta, gcd, lcm, ceiling, floor, pmt, pv, fv, nper, rate. + +### Execute Text Function +Executes text manipulation functions including: left, right, mid, len, upper, lower, trim, find, replace, concatenate, split, trimends, proper, search, substitute, startswith, endswith, char, unichar, encodeurl, encodehtml, plaintext, concat, ismatch, match, matchall, rept, fixed, dollar. + +### Execute Logical Function +Executes logical functions including: and, or, not, if, isblank, isempty, isnumeric, iserror, switch, iferror, error, isblankorerror, istoday, isutctoday. + +### Execute Date Time Function +Executes date/time functions including: now, today, year, month, day, hour, minute, second, dateadd, datediff, utcnow, utctoday, date, datetime, time, datevalue, datetimevalue, timevalue, weekday, edate, eomonth, weeknum, isoweeknum. + +### Execute Conversion Function +Executes type conversion functions including: text, value, boolean, decimal, float, guid, astype. + +### Execute Table Function +Executes table manipulation functions including: addcolumns, filter, sort, groupby, summarize, distinct, firstn, lastn, table, sequence, countrows, countif, first, last, index, shuffle. + +### Execute Utility Function +Executes utility functions including: rand, randbetween, sequence, shuffle, sort, reverse, coalesce, collect, clear, remove, removeif, update, updateif, patch, parsejson, dec2hex, hex2dec, blank, rgba, colorvalue, colorfade, forall, with. + +### Execute Advanced Table Function +Executes advanced table operations including: join, leftjoin, rightjoin, innerjoin, outerjoin, crossjoin, pivot, unpivot, transpose, lookup, xlookup, relate, unrelate, merge, append, union, intersect, except, dropcolumns, renamecolumns, showcolumns. + +### Execute JSON Function +Executes JSON parsing and manipulation functions including: parsejson, json, formatjson, jsonextract, jsonpath, isvalidjson, jsonmerge, jsonarray, jsonobject, jsonkeys, jsonvalues. + +### Execute Color Function +Executes color manipulation functions including: rgba, rgb, hsl, hsv, colorvalue, colorfade, colorbrightness, colorcontrast, colormix, colorinvert, hex2color, color2hex, colorred, colorgreen, colorblue, coloralpha. + +### Execute Encoding Function +Executes data encoding and decoding functions including: base64encode, base64decode, urlencode, urldecode, htmlencode, htmldecode, xmlencode, xmldecode, utf8encode, utf8decode, hash, md5, sha1, sha256. + +### Execute Statistics Function +Executes statistical analysis functions including: stdev, stdevp, var, varp, median, mode, percentile, quartile, correlation, covariance, regression, slope, intercept, rsquared, frequency, rank, percentrank, zscore, confidence. + +### Check Value Type +Determines the Power Fx type of a given value. + +### Coerce Value Type +Attempts to coerce a value to a specific Power Fx type. + +### Extract Date Part +Extracts specific parts (year, month, day, hour, minute, second, weekday, dayofyear, quarter, weeknum, isoweeknum) from date/time values. + +### Transform Text +Applies text transformations including: upper, lower, proper, trim, trimends, trimstart, trimend, reverse. + +### Round Number +Rounds numbers using various methods: round, roundup, rounddown, trunc, int, ceiling, floor. + +### Trigonometric Function +Executes trigonometric functions including: sin, cos, tan, asin, acos, atan, atan2, cot, acot, sec, csc, sinh, cosh, tanh. + +### Search Text +Searches for text using methods: find, search, startswith, endswith, contains, exact. + +### Evaluate Logical Condition +Evaluates logical conditions using: and, or, not, xor, nand, nor. + +### Check Value Property +Checks specific properties of values: isblank, isempty, isnumeric, istext, islogical, iserror, isdate, istime, isblankorerror, istoday, isutctoday. + +## Known Issues and Limitations +Some advanced Power Fx features may not be fully implemented in this version. \ No newline at end of file diff --git a/independent-publisher-connectors/Power Fx Functions/script.csx b/independent-publisher-connectors/Power Fx Functions/script.csx new file mode 100644 index 0000000000..841fb2fee7 --- /dev/null +++ b/independent-publisher-connectors/Power Fx Functions/script.csx @@ -0,0 +1,651 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Microsoft.PowerPlatform.Connectors; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +public class Script : ScriptBase +{ + public override async Task ExecuteAsync() + { + var pathInfo = ExtractPathInfo(); + + try + { + // Handle main operations + if (pathInfo.Operation.Equals("evaluate", StringComparison.OrdinalIgnoreCase)) + { + return await EvaluateFormula().ConfigureAwait(false); + } + else if (pathInfo.Operation.Equals("parse", StringComparison.OrdinalIgnoreCase)) + { + return await ParseFormula().ConfigureAwait(false); + } + else if (pathInfo.Operation.Equals("validate", StringComparison.OrdinalIgnoreCase)) + { + return await ValidateFormula().ConfigureAwait(false); + } + // Handle function categories + else if (pathInfo.Category == "functions") + { + return await ExecuteFunction(pathInfo).ConfigureAwait(false); + } + // Handle type operations + else if (pathInfo.Category == "types") + { + return await ExecuteTypeOperation(pathInfo).ConfigureAwait(false); + } + else + { + return CreateErrorResponse($"Unknown operation: {pathInfo.Operation}", HttpStatusCode.NotFound); + } + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, $"Error executing operation: {pathInfo.Operation}"); + return CreateErrorResponse("Internal server error", HttpStatusCode.InternalServerError); + } + } + + private async Task EvaluateFormula() + { + try + { + var requestBody = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false); + var requestData = JObject.Parse(requestBody); + var formula = requestData["formula"]?.ToString(); + + if (string.IsNullOrEmpty(formula)) + return CreateErrorResponse("Formula is required", HttpStatusCode.BadRequest); + + var result = EvaluateSimpleFormula(formula); + + var response = new JObject(); + response["result"] = JToken.FromObject(new { value = result, type = "Text", isError = false }); + response["formula"] = JToken.FromObject(formula); + response["success"] = JToken.FromObject(true); + + return CreateSuccessResponse(response); + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, "Error evaluating formula"); + return CreateErrorResponse("Evaluation error", HttpStatusCode.InternalServerError); + } + } + + private string EvaluateSimpleFormula(string formula) + { + if (formula.Contains("+")) + { + var parts = formula.Split('+'); + if (parts.Length == 2 && double.TryParse(parts[0].Trim(), out double num1) && double.TryParse(parts[1].Trim(), out double num2)) + { + return (num1 + num2).ToString(); + } + } + return $"Evaluated: {formula}"; + } + + private async Task ParseFormula() + { + try + { + var requestBody = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false); + var requestData = JObject.Parse(requestBody); + var formula = requestData["formula"]?.ToString(); + + if (string.IsNullOrEmpty(formula)) + return CreateErrorResponse("Formula is required", HttpStatusCode.BadRequest); + + var tokens = TokenizeFormula(formula); + var response = new JObject(); + response["isValid"] = JToken.FromObject(true); + response["tokens"] = JArray.FromObject(tokens); + response["success"] = JToken.FromObject(true); + + return CreateSuccessResponse(response); + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, "Error parsing formula"); + return CreateErrorResponse("Parse error", HttpStatusCode.InternalServerError); + } + } + + private async Task ValidateFormula() + { + try + { + var requestBody = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false); + var requestData = JObject.Parse(requestBody); + var formula = requestData["formula"]?.ToString(); + + if (string.IsNullOrEmpty(formula)) + return CreateErrorResponse("Formula is required", HttpStatusCode.BadRequest); + + var isValid = !string.IsNullOrWhiteSpace(formula) && formula.Length > 0; + + var response = new JObject(); + response["isValid"] = JToken.FromObject(isValid); + response["formula"] = JToken.FromObject(formula); + response["success"] = JToken.FromObject(true); + + return CreateSuccessResponse(response); + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, "Error validating formula"); + return CreateErrorResponse("Validation error", HttpStatusCode.InternalServerError); + } + } + + private async Task ExecuteFunction(PathInfo pathInfo) + { + try + { + var requestBody = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false); + var requestData = JObject.Parse(requestBody); + + FunctionResult result; + switch (pathInfo.FunctionType.ToLower()) + { + case "math": + result = ExecuteMathFunction(pathInfo.Operation, requestData); + break; + case "text": + result = ExecuteTextFunction(pathInfo.Operation, requestData); + break; + case "logical": + result = ExecuteLogicalFunction(pathInfo.Operation, requestData); + break; + case "datetime": + result = ExecuteDateTimeFunction(pathInfo.Operation, requestData); + break; + case "conversion": + result = ExecuteConversionFunction(pathInfo.Operation, requestData); + break; + case "table": + result = ExecuteTableFunction(pathInfo.Operation, requestData); + break; + case "utility": + result = ExecuteUtilityFunction(pathInfo.Operation, requestData); + break; + case "json": + result = ExecuteJSONFunction(pathInfo.Operation, requestData); + break; + case "color": + result = ExecuteColorFunction(pathInfo.Operation, requestData); + break; + case "encoding": + result = ExecuteEncodingFunction(pathInfo.Operation, requestData); + break; + case "statistics": + result = ExecuteStatisticsFunction(pathInfo.Operation, requestData); + break; + default: + result = CreateFunctionResult("Function not implemented", false); + break; + } + + // Create PowerFxValue structure as expected by OpenAPI schema + var powerFxValue = new JObject(); + powerFxValue["value"] = JToken.FromObject(result.Value); + powerFxValue["type"] = JToken.FromObject(result.Type); + powerFxValue["isError"] = JToken.FromObject(!result.Success); + if (!result.Success) + { + powerFxValue["errorMessage"] = JToken.FromObject(result.Value.ToString()); + } + + var response = new JObject(); + response["result"] = powerFxValue; + response["executionTimeMs"] = JToken.FromObject(0); // Add execution time if needed + + return CreateSuccessResponse(response); + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, $"Error executing function: {pathInfo.FunctionType}/{pathInfo.Operation}"); + return CreateErrorResponse($"Function execution error: {ex.Message}", HttpStatusCode.InternalServerError); + } + } + + private async Task ExecuteTypeOperation(PathInfo pathInfo) + { + try + { + var requestBody = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false); + var requestData = JObject.Parse(requestBody); + + FunctionResult result; + switch (pathInfo.Operation.ToLower()) + { + case "check": + result = ExecuteTypeCheck(requestData); + break; + case "coerce": + result = ExecuteTypeCoerce(requestData); + break; + default: + result = CreateFunctionResult("Type operation not implemented", false); + break; + } + + // Create PowerFxValue structure as expected by OpenAPI schema + var powerFxValue = new JObject(); + powerFxValue["value"] = JToken.FromObject(result.Value); + powerFxValue["type"] = JToken.FromObject(result.Type); + powerFxValue["isError"] = JToken.FromObject(!result.Success); + if (!result.Success) + { + powerFxValue["errorMessage"] = JToken.FromObject(result.Value.ToString()); + } + + var response = new JObject(); + response["result"] = powerFxValue; + response["executionTimeMs"] = JToken.FromObject(0); + + return CreateSuccessResponse(response); + } + catch (Exception ex) + { + this.Context.Logger?.LogError(ex, $"Error executing type operation: {pathInfo.Operation}"); + return CreateErrorResponse($"Type operation error: {ex.Message}", HttpStatusCode.InternalServerError); + } + } + + private FunctionResult ExecuteMathFunction(string operation, JObject requestData) + { + try + { + var args = requestData["arguments"]?.ToObject() ?? new double[0]; + + double result = 0; + switch (operation.ToLower()) + { + case "abs": + result = args.Length >= 1 ? Math.Abs(args[0]) : 0; + break; + case "power": + result = args.Length >= 2 ? Math.Pow(args[0], args[1]) : 0; + break; + case "sqrt": + result = args.Length >= 1 ? Math.Sqrt(args[0]) : 0; + break; + case "mod": + result = args.Length >= 2 ? args[0] % args[1] : 0; + break; + case "round": + result = args.Length >= 1 ? Math.Round(args[0]) : 0; + break; + case "sin": + result = args.Length >= 1 ? Math.Sin(args[0]) : 0; + break; + case "cos": + result = args.Length >= 1 ? Math.Cos(args[0]) : 0; + break; + case "tan": + result = args.Length >= 1 ? Math.Tan(args[0]) : 0; + break; + case "ln": + result = args.Length >= 1 ? Math.Log(args[0]) : 0; + break; + case "log": + result = args.Length >= 1 ? Math.Log10(args[0]) : 0; + break; + case "exp": + result = args.Length >= 1 ? Math.Exp(args[0]) : 0; + break; + case "pi": + result = Math.PI; + break; + case "int": + result = args.Length >= 1 ? Math.Truncate(args[0]) : 0; + break; + case "roundup": + result = args.Length >= 1 ? Math.Ceiling(args[0]) : 0; + break; + case "rounddown": + result = args.Length >= 1 ? Math.Floor(args[0]) : 0; + break; + case "trunc": + result = args.Length >= 1 ? Math.Truncate(args[0]) : 0; + break; + case "asin": + result = args.Length >= 1 ? Math.Asin(args[0]) : 0; + break; + case "acos": + result = args.Length >= 1 ? Math.Acos(args[0]) : 0; + break; + case "atan": + result = args.Length >= 1 ? Math.Atan(args[0]) : 0; + break; + case "atan2": + result = args.Length >= 2 ? Math.Atan2(args[0], args[1]) : 0; + break; + case "ceiling": + result = args.Length >= 1 ? Math.Ceiling(args[0]) : 0; + break; + case "floor": + result = args.Length >= 1 ? Math.Floor(args[0]) : 0; + break; + case "max": + result = args.Length >= 1 ? args.Max() : 0; + break; + case "min": + result = args.Length >= 1 ? args.Min() : 0; + break; + case "sum": + result = args.Sum(); + break; + case "average": + result = args.Length > 0 ? args.Average() : 0; + break; + default: + throw new NotSupportedException($"Math operation '{operation}' is not supported"); + } + + return CreateFunctionResult(result, true); + } + catch (Exception ex) + { + return CreateFunctionResult($"Math error: {ex.Message}", false); + } + } + + private FunctionResult ExecuteTextFunction(string operation, JObject requestData) + { + try + { + var args = requestData["arguments"]?.ToObject() ?? new string[0]; + + object result = ""; + switch (operation.ToLower()) + { + case "upper": + result = args.Length >= 1 ? args[0]?.ToUpper() ?? "" : ""; + break; + case "lower": + result = args.Length >= 1 ? args[0]?.ToLower() ?? "" : ""; + break; + case "len": + result = args.Length >= 1 ? args[0]?.Length ?? 0 : 0; + break; + case "trim": + result = args.Length >= 1 ? args[0]?.Trim() ?? "" : ""; + break; + case "left": + if (args.Length >= 2 && int.TryParse(args[1], out int leftCount) && args[0] != null) + result = args[0].Length >= leftCount ? args[0].Substring(0, leftCount) : args[0]; + else + result = ""; + break; + case "right": + if (args.Length >= 2 && int.TryParse(args[1], out int rightCount) && args[0] != null) + result = args[0].Length >= rightCount ? args[0].Substring(args[0].Length - rightCount) : args[0]; + else + result = ""; + break; + case "concatenate": + result = string.Join("", args); + break; + default: + result = $"Text operation '{operation}' not implemented"; + break; + } + + return CreateFunctionResult(result, true); + } + catch (Exception ex) + { + return CreateFunctionResult($"Text error: {ex.Message}", false); + } + } + + private FunctionResult ExecuteLogicalFunction(string operation, JObject requestData) + { + try + { + var args = requestData["arguments"]?.ToObject() ?? new bool[0]; + + bool result = false; + switch (operation.ToLower()) + { + case "and": + result = args.Length > 0 ? args.All(x => x) : true; + break; + case "or": + result = args.Length > 0 ? args.Any(x => x) : false; + break; + case "not": + result = args.Length >= 1 ? !args[0] : true; + break; + default: + throw new NotSupportedException($"Logical operation '{operation}' is not supported"); + } + + return CreateFunctionResult(result, true); + } + catch (Exception ex) + { + return CreateFunctionResult($"Logical error: {ex.Message}", false); + } + } + + private FunctionResult ExecuteDateTimeFunction(string operation, JObject requestData) + { + try + { + object result = null; + switch (operation.ToLower()) + { + case "now": + result = DateTime.Now; + break; + case "today": + result = DateTime.Today; + break; + case "utcnow": + result = DateTime.UtcNow; + break; + case "utctoday": + result = DateTime.UtcNow.Date; + break; + default: + result = $"DateTime operation '{operation}' not implemented"; + break; + } + + return CreateFunctionResult(result, true); + } + catch (Exception ex) + { + return CreateFunctionResult($"DateTime error: {ex.Message}", false); + } + } + + private FunctionResult ExecuteConversionFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Conversion operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteTableFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Table operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteUtilityFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Utility operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteJSONFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"JSON operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteColorFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Color operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteEncodingFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Encoding operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteStatisticsFunction(string operation, JObject requestData) + { + return CreateFunctionResult($"Statistics operation '{operation}' not implemented", false); + } + + private FunctionResult ExecuteTypeCheck(JObject requestData) + { + return CreateFunctionResult("Type check not implemented", false); + } + + private FunctionResult ExecuteTypeCoerce(JObject requestData) + { + return CreateFunctionResult("Type coerce not implemented", false); + } + + private FunctionResult CreateFunctionResult(object value, bool success) + { + return new FunctionResult + { + Value = value, + Success = success, + Type = GetPowerFxType(value) + }; + } + + private string GetPowerFxType(object value) + { + if (value == null) + return "Blank"; + + if (value is bool) + return "Boolean"; + + if (value is int || value is long || value is float || value is double || value is decimal) + return "Number"; + + if (value is string) + return "Text"; + + if (value is DateTime) + return "DateTime"; + + return "Text"; + } + + private List> TokenizeFormula(string formula) + { + var tokens = new List>(); + tokens.Add(new Dictionary + { + ["type"] = "Formula", + ["value"] = formula, + ["start"] = 0, + ["end"] = formula.Length + }); + return tokens; + } + + private PathInfo ExtractPathInfo() + { + var segments = this.Context.Request.RequestUri.Segments + .Where(s => !string.IsNullOrWhiteSpace(s) && s != "/") + .Select(s => s.TrimEnd('/')) + .ToArray(); + + if (segments.Length == 0) + return new PathInfo { Operation = "unknown", Category = "", FunctionType = "" }; + + // Handle simple operations like /evaluate, /parse, /validate + if (segments.Length == 1) + { + return new PathInfo + { + Operation = segments[0], + Category = "", + FunctionType = "" + }; + } + + // Handle /functions/math/power, /functions/text/upper, etc. + if (segments.Length >= 3 && segments[0] == "functions") + { + return new PathInfo + { + Operation = segments[2], + Category = segments[0], + FunctionType = segments[1] + }; + } + + // Handle /types/check, /types/coerce + if (segments.Length >= 2 && segments[0] == "types") + { + return new PathInfo + { + Operation = segments[1], + Category = segments[0], + FunctionType = "" + }; + } + + // Default case + return new PathInfo + { + Operation = segments.LastOrDefault() ?? "unknown", + Category = segments.Length > 1 ? segments[0] : "", + FunctionType = segments.Length > 2 ? segments[1] : "" + }; + } + + private class PathInfo + { + public string Operation { get; set; } = ""; + public string Category { get; set; } = ""; + public string FunctionType { get; set; } = ""; + } + + private class FunctionResult + { + public object Value { get; set; } + public bool Success { get; set; } + public string Type { get; set; } = ""; + } + + private HttpResponseMessage CreateSuccessResponse(JObject responseData) + { + var response = new HttpResponseMessage(HttpStatusCode.OK); + response.Content = CreateJsonContent(responseData.ToString()); + return response; + } + + private HttpResponseMessage CreateErrorResponse(string errorMessage, HttpStatusCode statusCode = HttpStatusCode.BadRequest) + { + var errorResponse = new JObject(); + var errorObj = new JObject(); + errorObj["code"] = JToken.FromObject(statusCode.ToString()); + errorObj["message"] = JToken.FromObject(errorMessage); + errorResponse["error"] = errorObj; + + var response = new HttpResponseMessage(statusCode); + response.Content = CreateJsonContent(errorResponse.ToString()); + return response; + } + + private StringContent CreateJsonContent(string json) + { + return new StringContent(json, Encoding.UTF8, "application/json"); + } +} From e28e904ed6b71ee0e0b41daae0c7240973da9632 Mon Sep 17 00:00:00 2001 From: Troy Simeon Taylor <44444967+troystaylor@users.noreply.github.com> Date: Fri, 24 Oct 2025 13:57:43 -0400 Subject: [PATCH 2/2] Add files via upload --- .../Power Fx Functions/ConnectorPackage.zip | Bin 19362 -> 34893 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/independent-publisher-connectors/Power Fx Functions/ConnectorPackage.zip b/independent-publisher-connectors/Power Fx Functions/ConnectorPackage.zip index bc23967fa96991442a1da720fb0f02044af6856b..87b3e533a4eff1ceb57b561b839cc80b72ba8e22 100644 GIT binary patch literal 34893 zcmV)9K*hgMO9KQH000080C9siTh43D)OH5|0Iw4O00;m80BLS?a&IneWR+N1kK48u zeji}|1A%#HFKVRi;C4aYf@uo0w>Jqo(*k{@r6Y?Oid49G?ELzE=a7=@TGO--rVrP% zZ@N+M{1XNB<3atHU6YJ=@%rkOYWy$;>d8g3r{zpn&nRoQL5HIngWsFhxShKF?yE1< zpi@s6Orz~aB|4;yvVK>ltxlx0YgIA>VOMW0;f6C~wwhnv0Il0ohywG;oQyT;IOB~f zM@H7HfSzYeuf-fm{U81?I~D|1mgAY9oEW!pjm_*$FO}ZLjT)Jfjfx)v z{Alp)Mg^Z8{@?`cERnqkkagl_8@R!UTV{ioQazl<3bg(S$5H?`IG4Pj=kel_NSU&t=iKfO`A1{ZC^8w8hj zptZB!gSm0Qv2l+%er{xbVS#iZ$_E6KHBoYqIg29e^0d@3OJ>)zC=FA?X73q@0gaD2Lu$E$X)!9)AJ z#`ScfsNT;d#Ho1Rdrl1;g$pE+xPS&VPAH(qgB5IokFkKG*>mj4t^x^Cj-zJ*B8NP3 zhC56^AX}v5CJ2Fv^OHuTXAL3ndO@041uStoG!j2sg!0)W0|Nd)^ECGUsZK5=^z;4O zH*0c{byg0SYg|Ko+9^&{S;kVtEGux_pqXf%K>r+IF~3u0}@USDwin)5F!Ydy>8lAtGT!oA95RRCKZ>D&L7jJ~Ne zxxuy>?6d)JTIIYyEi*i=AC~3AvYJ!({rm{v`4t_xG-$tJo7G>-c>B$_7rfplXb&;9 ziEG@(X%|(2Mh9_>Xhv4~jH#vlru>bZQ-Ta5`yH2$Qn!LG1cioM5DtPLGU_6M8rId) z{NbX}5-#2F< zjvynKA;Dc={Xlphl|b#Y<}N@os_)Pk?9dClk~WujJR>}N=v7Kw7e($Qo3gFTEnd;6 zA(3c1G!17cPBbJgUWy(xK8f`rOL4h6a%HJL|EC4bTyS9UUAZM%;HW`MF+c- zR)2{T4;+D|3+A#MERU#*r(!%!o0nPOyxg8@=TderH8n$0JI{-A%A6_qm0KG1CJ$Re zS1+@uoJ^;W1Z+({quHX=`!>Funy0^Mi==Hj?@&&7Hamn-yoN$|wemSTuDPd%pJ=Ads*%4o69<80&7BDP)HUCUiKOH8m8_n6K-podgL4-9 zeEF%~q!hj;&flcwcE!X}U2)VK=-;#{>VIeqocbxo%*7C_@)t9hG<`+6he0eQ((-MA zbjm?K1squ#YRmnLwMS)!(Gq{w!Exitcc@y;zxWeSO9KQH000080H|(QTXejJ-~)gF z03Cn;01E&B0B~VrYhh<)E_!Kj05d?$zfem91QY-O00;o6ZdhAuY@7yeI{*MFKL7w1 z0000`YiB`ob7gdMFGFu`Ze?S1Z*nerX>hH31FUGxvgWpJ+veG}ZQHhO+qP|+XWO=I zpUwI2dzs|^cjmp9+?j7By}HxsRh3HD>i#NK@>0McC;&hJ5C9<&>RN3Q8WC(j001|j z002k;H~>a2PR@2V7M=#q7IwBybnZ6R1cev?6!|Cs|2O0)>sW0vp!ncl@nPJqr}Cwe z(#GmFf`QReORPf~p=k8VHm@fpBy*nE<9i`j&5W1)eS)Q)ScgYY zgjaeUjr%l50V}{CO*%}E-Lp^|TGFwM#fjQ-F^vi%4Oc_BPDAR)q^;P7-WTnVo^KFZ zGA@855M#F8uz!UhSaP!*yAQP>w&QPqqGi@=FpP4+qFj?xBC!Y(q%OtZ;z;(SK-j%R z>J1gh*iRuq-X6oY4wISIsq$Euzt)=9Q}}Ji`b^-pY{a2ewh+dGi)IUey=wA^CEPZ2 zUbhR$32f6oic$M4ikhsjNNC&!`qj6Y#*Ft9cSIv_`dNl*Q9UZSTKQzqq4t`^UlC6KpyAy4ln<=E$En!HSP%v0Kkm^008sX7Id<+ zcKOHd`=2)7wYpB+1}B0~-O>-jG48{%>$(cRrG;8$v-AAmP0h_@N)pVlrD0iX6MxnB zE7v&L(PRbHGb$md^U0L^C>}n>=d8tO$h$L5uHNFXI~XCQnbV`^h3s})?6owmohcS} z?hzEM6_PKpm%HV>G%=xd9x>Jf#7U`m3lZ}N-bfH}3w^5{hRi7$Qbz{#-sRR`yjk4TwlF3iegyH# z14ZJYy_~AZMj28gi8m`5B;ZhQHy%x8>4)Q8VpUOBc*1>K zZ0@9T!Q3C(h0*66qM+M{g)AFp<-_`ht=PAEfUfV|XPT#wR_#YHG@jPlj@XTf){G$Y zKh$jmiW|!X4;PG_zx0M(f!!(PS9M)&F@%0!jCKqesdU(WZ7durfyIVu_Y0L)nRN=4 zmYI3-kePinI9n;L7NPh9b`%kl+D+eM6V2xd8)3h1-MW_l;J2Slah>Fr;#)Q=9>3sFCFO4RR1+;3KlSy25wb;xI5n~D<>2&hE63ujyI z2=ZKOFIqak_1V$H15wzYHFb5lZfwRiLjpnM=7`F9w~`}rTO0m3$zsgWhc?Z{hKch% z87X0Zu+e37Kc=BR!|?WpUnSa(-YLcc1R=?6Vq~j%)2QH=nx9C?aOw{PW<5kmtRN4n z0T+DOjwafyA1ci^_}~2(KDTl5loS8}ISCLz>M#Elva_`{F>aPDYLv_Re~C_9nIl_7=t_rWUpq|Ka_XPIk8ct^4b2 zJ8iNj`t?qw{C*W; zr;ORD$*bfCnwyQ=ndvzhm(zfo)$iT56o>60hbEo! zYo!M|g$@z)k=waoMFOb2?g#u^in-XMpzFRr{tJxHml^oUnMEp&MY_0~MmE-z%E@K7y)*QO zc^F!MyU!`bc-D><7=K9z%eWFqSH9bA2uI?k$vXG@_$__^upat=6B18b4&J8P>)8Xe z_^_j*fbF0HE!rX*gvv&UYft!|Sy4LQ{%D z9%s|6q6}0OIL*gS(?z~QIZio~eo zndjr_YPGM-BRwM`oo6-$_?;r7LuwIT!5&Y(TY-k~UML>StsKdpH+}k$#Hq+S!v2O# zvzCdc2c1~|+o$qdA!9k>omK5zk@k(Ze{^@`+vyM$1riCACy%tFvQM zQO-$j(t&e)Nc7`Uh>fWjwv&}}u(`B_JarE4d#x-3Jpl~jQ_=I;QPHA7GO^Os4C^Da z7;8tlyi|<~-7mTCyR}*yKDK48Ovq)FHThf~L!4P$OFu$ZC4u+S19 zeAUmMSZ;QnUYAS1sjUu+f4F~XGgP-;=guQJFkzZr30_|+GzbRr4QgeLwI?s0kvZ#lK0{7I22~j zaH2T(n}ry+^OY{=$NhV$PP9tUr^VrCV75YeAJ*kjs%J8Xalnw@Zd6{%kw-5AQXk3+ zhKtQSdz9-!o->Iulj8zIr*!v*7YeWtJdKVeX1-2z=WIy~wphXhs?3oYe}Gj$pBXZf zn&<$T&HkLvvQib*UeVamk%XK8y1d3N@|qG=-I3s8k_uX4$$&T)wC5ydmor#<)&Mb|uGvtFe!jv~f&DXb!S1wJXBo#D>4HOse6i1a6$Q`Y~py=S2 z&o^Srw3J8{C|S{ida9}V!nG;V8C7DNKUtTC$kjZj^fu65NX@rL_asJH&<^eq1k?kc zsc1c%7exgmvmt`|Lo~63;###O43Wv&P2sMLJ9Dj#klA|We#e}jma)`)FD?)l&}@NM z4I!;nhH@iuFiy$1@ou8eBXBLTxe8-XRw00ioEwP8H!4QHlI1e|had;I6r81o#MSOh zNke<(v7ml7n)%4M!O3Vcf?PWqv0Uv&iD5EC8e^e@Od&`dF2#9=aw!3Y2pJ=vK`ucVE(LOlPX3IK6zUfhlMUUBsl!n=D7*j`^t3fowxEMU#TF>Ennyb5 zqx=N+VIUg{ep#wINCqUFLi?$>Wc~{NSNCWB3@Yx5DKO9T-20m@?eC>Y0M=^ucek}6 z&-rptfkzT<#RT*ZGJTNP*XCcLlUp};U`j5#hF)3H?5@YPp&avNpA)9eYgZ95*Q~Ui zMonA`$F8u};SV3gdc!kMhFq|4p|yQEzgAkFwq=1g3N|hJj~D(dvA!<3>wAgEj@Dbj3O}pb;WYJv=WNu<47!azC2#kYT1o31e1`ZVE0^zCQl3O zjQZyYju_9YPxnK)Zs6e;Vj2sq%Mk z*R1K1)OM2qh*He8j-?dSvJ}%gcFpW|`~iO)T?iv&Ze|%ezrnD<*-A|k>T3=^skO^) zL~defj!Twvp^PHWTW#38*f5!KDQ}1$aPa|5JZETNACxzr^1)m2ucAA86_#aY6_8|w zRFo^)cu!lSXT6q=FE=du0A;ug)i;zobtO*x8(j*Dw=?&HS z?tCq%F0j4Yj)aD8Q@2@zZff?tklf1pWC`Rh#E#ey2ZEyqc0z2Q61kA(kwY@4BJzQTOe4<=qZm77dVTgKf0M4ii)cZ$*}nntUm$vl(?@*A$MB3 z^qHt#8C2RePtIznL_c%UDh|Vx63SA~BySG0t4YGsnUyA@B;qhh2A(_Ed>IP1jC)WPY))3it7AQ20>xbj zzAz-yO)~0Yymnu16e{9aE+hAKMz-<=bPzqF1mZ_W{$V%It&oYe%1Ie0;KZdGrRZU^ z^7hyOn*t%ouWKfjG2c8QaHhQ{@6!683M{iL)nVhKSfCz3MZ~3@9B(ocmqp9iKyTn= zCZEYOd8p@!xe537=*Uugu~1cW=QjS&uV>PTNbbpOyh!c)IMNcdrV9ydhl(-CHc3L8TmgmdJ&-OfEZJO zINVl%ihG_hP6rW>0%?d)56^ktb^B0I4FhJ=>TsHDT62~9HYQMbomx-q5+iuG=&RU0 zPMqoGd{|f;TI|a~fnLygzH&oe&u8N=2VQ2=cN1+8dRkm=+=Ff6`whO)x6Rd6uWq^V z_WBCecjS5U-t&R1#J)P-R}y1!f7;`sXtzfk%Evx=)3S{pVPE{MeB>=mjnFhm3C<$HIYAuU9Ui@ z8defIg+jZ?r4e6oYRxvr%qAM~!h=UZ$jjT-V6H5JJKF%Z>LM@`~zD3!>by)7>iDxD4TO9)E|WPyHyh=(Du5GCt%I6tKz zJnEpYK_))QtmB?Yd`q|h@D}qW49RAUR`{Jmq^A&}xA5W3WU=+raS@|5_jc{;v_vE$ zE`d|T-U6EWMD3F#BSi!18{0es3)2I^&O=RcrT~)wnXH0n?0TTE#|PN(D0ybCI5|b8 zrJER)|JWG>#MiVm`U@4ALsLuvCL6fsQC0o~Lqt44uXAuMy0N4_Du~FDXx7RZYFD@@ zM?pb6I3zVC=nA;|OSAT4eIx?BFCAjy6Cq)>CN=35@PICKl4cL(4m5s(5S>hr@7Xe3 zgR+Vb%X=CeYij7`Pd||t)}`)4MC)1lA%=I9yGTLAf~oF7!G401|5yetG2-^aAzl=@hx-38;qY%oY`_V1=)QgxH4K&ZO5u z!K$3zMcdLk`iW?Yv8R}c%`z?;`4$J3H;04IMUJksG>jP5N5+$5$EW=Y#4+kO_P^Kp5 z_&5Fwb-H2O-Tf7c$ROJh<(51KvW;oX@#2r6IcpV?tIW4i|)Ii1?hO>7D8+O*Kg z?pHz1%kF~>URJeVNj-|s9(7Tb(enzif8n;gyGqQoNjZ|(x4B5nxYmW5&(qMpIWk8q z>!Q5x(l)5~`E}tG`f`Ajj8KLZHS;il1cQaYuqQW=zw{qcsCHlPfEaM@yu7R38t0c= z`~V$lv9Te=fKZ<)U43dRqgDSu8=e+U2EXTY0s|88@ zAhz!z0peN((h864!9ODl{cK_OE5Iyl$g+oT6kF6)GNu?h$?!ufru$c>I^}hB8jS7;$jJ)H{bF%wP~+H)SoX zwSq%)+A1LDFo7o%K`e?GK$}u(0Z-MRSKDL;x^}R{38>ovX>N`91(ZShBh?J>tjNLh zt;~&sHx5&(qbCa}gEP`Oo7j)-y*jSAA2?mBZc4rfHa!3t5C)RBOR&@#!?bM31SYW~ zcDbO^?u<*P6yf`sXdK)~qVw(`=__+ovZOT4;({W~EW@+11?ht@JPjt*>TsEiLqk$= z8v>rNrm(b=_f=+?U!1P+57HHB;$3nI1nQOO?if>YiUoWL`NG7Lg}Eo)TxJm>AP|Rt zScL2qKc8?Cv?PpzUe;j!;RSpcA7z;2nHq>kIg5H}E*YbguNeg~xNr#)@*!H+Kdysg z=_RP_1{a3DQZ$5VK3{S9?z7BU>c&)`u*TW&X1JEO))YGx2lUMVwIuezh34ZVdm$s8Hq4a*-5oBBtznkY8A%t@~SbqpfQ71bT3{nIJ)iQ>-esps>W- z!#<%>9|L48($fz*2(Dv_I;W-&WSQlDR2;UaS?skL(liD~8^0*yR|2PJPkNurPQU@v zy!$nYHgDX&tLaJj_N|diPXcU3+Y~j>3f;06zStB4$Tpda;QaGJ&H9kBg=i%T%-C;4 zfCgl{Y7YZ^0ye~+aP2Lc=9t4zv6@mKWwMR_7xv+_T&Pz5pw4fQJz@iu`1FA zOkG$)e67Ms@3mBcB7+>D!i#y#UJcTqx&BP1(UWDLF1N^j|{`2C72Xh?!Oos7DG2T$p3ZyFjjRE z2M3*H&-3UTG&e3c^tx|OIu=-O8`G3Q>3eF&BBRye%MKlv{s^77K3OE3XEt{FBOU;m zAYu>u?vD&cyXJ+2R>b@?XmoJyBZ+I>D~De$t|kSv(|Xi?vW?66fLH(x1@$(?<&f3c z?#>4tUOaoE0$?bJ8mv7nK9EwZB$4ID@N25dq7cPr5}&1|Bx=jv_jY2qRDP)qD``WQ z$y_lLQ(r>cu~)v`PBg8teK@+~eFFt!WH{nSD%W(TN`#R^ z*Ih-z!7%i&nS%H?SVaOQTx}pZGhSj&Kc!D(0CX{GPQvGeAmbg_uXjU-g5os#NI+tc zOwj2F0^lPoiTz!QG0?i}8u7bAabMC>^*2aywn31d110Y6z@p78{Q(TLFBatZR%Qi1 zmd`Bn_*Q`dfJ2}w3mEWW&6@YSYr~*s7i2K0^l`eQ-4X6$BP?M+y_~Nzfc7O@rj{{<_98ZN zzA>O7rVVt>#m2qM&dQQ|_AxEm>t!An^~>6U7w;9v&zET%o5;Pin~u^9ThUBV-Ok=y zPO8g`%N{z(>bGOD@m_38wiVdCMS|x(j!d+9%b z8PqnST+y9I+^8l3;ys_NZpbGo;12ikPUqd~P3Zn(@|#bVmCpu}Y0^XK-9xBx5KQ>W zB$N!2H^y@IxDnhJQs2S7I@2!@k1u)^wjA4p^CWkuEE>a3x>Kn&?=#WOL<*0h-(zmb zdYe`70S4-$@rGnzBSS9Qc(v;&Tu08u?jCy5fRtwswB!l2dY) zi%}>K&w;uid1^g>-I}2-5wBFYWe4(9p&%Uk>+o5C;R_RYT7?zf(gcdPhC4J+lIFdi z48P#(|ZMXt>J-6|$?u*~kHN$nbf1 z6=Y8^+-NbFA-=x}4sqNKIrj^c+<>BQJoqY)|5@~^l0+lSAySp^Lpkr?iN;$RsZbW1 zBog(}KQiga-4MU^KJ7?w0#D){kb-GR@+eCbI;D#hIu;F!HP}PAQ5mo*{Jtw(z+4`n zRo5N0i}GMVj0^Hq7508Z!?fb|HF>k<<|F2X8woQyDBJ~p*pFF|5+3qpXUIchd&{Rg z<2Bcv?Yi1j8VVxX&*r0jNInmH0rM_B4O#+l$ng_%QN;Zi>RAwv2!&Rp#)-(ZItJws z#-$~77h#+P?(JE)7|DT44)laTq;fPZB_mH~Z*_Smr+OuYn}BRfCrD}8`@vc)BCH$P zb#4J^!h6yDY9zsK9ZX%KfbDU&_0S)Mmz5jpK2$HZHM7c19^%At zuGte(<8Ci5p%RZ4F42)jW9_E5ET8Y{9iQ9}U6s}&#;jRLOQtOwtnxvcwR-Pt@uX&Y ze|2l!k__amh(V^$aJA8tV|fOd9XhFpzZftP@o$YF126GhzUmGf370>6as|rF>trGi z&(=T)6{sW-keYC~J0nZTmE~q}*xeV1ufQagY@ysR+*snnjLFRjL^i7=s@H2CIXRV= zW3)=c{Q*=o42wZV`aCjzbwS^O=*r!}`X$z&_luLqW;SYSnqb6BtYpPS#g*s9YuZcy zoy{kf>D3~e!dKJo4Y=RGBWCrRSP72( zAwvS&qO7$Cr+Zm`!`Mh3C@a;ht+g?lD|HC1uN2|sKyzz*l?6U^ahoxbA&fiy%{|Jm z$$&>Dr}f!_7|NFMq^ssI8XfsfD=VzE=;>C7{IIY%Cu$F@1F@<|1U9#J)SE%SinWX- zd;>eVoJLOCam6Jiz%$cIVrgT2spCjxRisB`QKw_whX<`acdu)lB`?5^*0NNys`F=W zEn7o&JXS%v)6LZW{5_c6P3UYosgaTT9H&j8yViw(?1}X0N1qK4xqyvpmj=IdKaen)d5K!w1V~DtmiK6TnRHSi8@YcQ>uVTVkNx8K*C14q22nfu?flui-|61Uo zB~IsPVF#cO?Ta-XW|pQJ_V})cM`FK4kkId&jV>jZGk1^75$3G~+xZAP5b$%HnVyA3hHt#o^Ps&G(OS*T+hcYNP+aGx zAW-PIr)~ofzk^QJUC(W0cj#uR zs_fPU-q{*-4n*==W$mfax+-35^7Tx=4bijoWi{6Y&zJ);wTdrYk~K={79JUF8xlh; z$}n8Xnn8^(WO290AeHkhZ4yi;o(VmVtc)yALaTpYhZ=mcLwP@YG7V_kD0Ul+poaZn z9J|R;2IiO`a_AJ0t6@Los#uNGgUd6j(lS}r+X&KPcE|BBxT$jZ_@0~NZEeZK&Aq?^ ztO;4Bw!nkd(xsCDExM^`O3?^9Gr{Z0Yt@gqza`Js#C@RZPb>(;RpxvqHH9uYyEjpc!NY4 zjJhYe#GvO1TeH#@GON3GwT}+gFGf2hZV&s_Oj>hVaGG<(<}c3!)P3Bt_P>a|x*;>N z@DP#+Zj^5$I~P>jsJey&_Ky+vbtZqUo~l~SjXtt-Kn{I3>dM8bb47>j3e+&8oG4X- z`r#8;E@yFl5Tcn$@JvU^ovmv2OSX-#Z$|F3;GB7y( zrqw2BL<{$v7!@J1&oE8=?WP7_4SiX0Tzwj{fmNIH4iEGKzWT%FfH!cu#iV1mjny$j zA9R-|WoUJ}jdhR-5>xfF(hPWq>^a~=5WSEGu^OqpbAd#JSTh{r<)5in@nNqbPU~js z^#-L*75h#UH{;f6VT)(#=RhO5DuH-K1-{vuiKf>H9I#+V{14hMOVx&=!9~7x%X$%f zHs*p@A78cVq{OO-xb#8Lylt2XABK|e_+_Tx6}Ag746UlVI`JfL-)KBrntSmF7XrUy zQve?1e34XY`equHT)C%^m@{;8sd>~QAeH%YWFRkr!|U{VhH)&w#yIP3b-t^uQEG?Y z0w+hopm5m*SlI*i)dh;qgX=20ZNx*r+jT-hEVP-SpAgB(=5|zOM{$t7z;>FaJJRNm(m#o8POySEsFYfkMe*r;nHgIZG)0ww20eib2AWMRC@ z@A8DPb?s8N0i21{ravz#qoy>( z{+&MiQ<@2msH%r9lLO{nW1k(fV@3H(#qzQCQJ!x>!&;VdUo5}ybNyD5T!Oo)+clKA zfj?>95wfaA%owlxd4({kSjl#4nu=N_OG1xQZ8zu2O^B?jSlj2daI1vQn~eBMH_W70 zcfdA##DfI0j$vG{gu7^iT3^UJX4VVs)vgvlJZMQMh9W!5Q((?LQ%rz(U;g*J z&s%SY^ojwW)8(21CDw1*NsDZdb)Uo3&lF8L5_}?NU`7qEz56)6Zk##dbe;-pV7j+> zPYZ{Yu1Ov0tl6iy;I0?X1YMIu-^|^UqIEOkl)eOdA5^L!NwK~*Tm=tLdh|uD zj)b53SHKN;)5*!b`$7I2x@S@5pM91hx8+jaTS28C%7rCASC*DUAN?Gokf>sik+1q) z{I9td2|-h)@|vk**!4?$wGMVJWq7Kq5uK7bQWV4MQugs3Qr-rkj){kYRf!O91UztoJ|~^{>OB)s#;Khzw1KTB@O$(by4_tb+NazwlMN=HnFj{HgGnv zuyt}aur)IIpVf(q{a1CMH!hFxVF3UtbpBsV^B?KoMs~&~hSqk5e;LZz#MYV4$jSY` z&BVjeQQKsH>FE=EK5spdUIBbDk<&UWfSGC*DkzgM!(-=$&;o&vO_6jBxW3zc)s^^e zMgASzmSg(}5aHv}=j_r)L!Ii&PMqY0+3+Vy%;6@@X)MUUBVktP{Bux{%)1T5;UFwe zGEG)Px#!>$OC)OHn6isnNVX2N2v6I-RC#CY=!R<-Rr{f8%wyIr!ySL_EE4*N9wvZ~ zPH{}h6&tV(;$8Kje!tP+W1grN#yhPYFeOo1d!L@@VawY?hScln7%?CY@Gvg}q4zgL z%4>mC{7@Rj3OE_Me|C?N;sWL-xtQBj46&=f{!6N00pk8CGpeyb(IwkHD!CT`Hspoq z?KG;_r3h4pZ^W?AJC9Is-hKL~q!7KnvFum;9VoK0j2hrXACarz0*91-c99$-Y_Uzl zEK9h>a5Z9vFwm0A*eNuXxAIbk|9bvFmc|$;7f6b=4XQl)`aqn%0*#=cT?KvuanL)4 zDK%VqPl%H1@vPwh972CD5S+TK=_faeFC&0DDWE-dnEnsX0dBh6T>LF;(bq2Q1s;+y zm@8`71Tq3T!%X{KhBo140a!P=m)EdlsFW2C@PgF&TC{A!D-vm^UVUjxqaX~){@C#%$PkVco?M(&4E;W<^W$@!@Emd@f#!QV@snij?KQMh@hHwvvfbf`Ii)@ z=BIDvm>wl2K?)o=r>Py*I^B+?+D*X$bx6&{oyXk?Wey105k-H9I@_lA5~;OWXGJH6 z(;`vz80t7D>nhBaR8K^!1V#md88@f4hV$qHoxhQKFT|*R>06K4BExQ=GB3-Yrj{D( z^U(*F?th@0V#Qk%q6^7?Bz3501bFotWM!6BuV07S(G>_NYNly`Zh=F zpu=<;IFlHvu80{Vl6ksw%0M1WYz)qd=13kWJt-F|NuV@@J~D*nyRWD3&WY~o8=sgm z(UPVGSdDHeE(pm&V2;YIs3zq)Gf@#mgc^d$q5-}In(^^aQwoBM_`Arevq#l3;@u>c z$wmAoEn%ACfuIwuh*yoSqwUS;_qo42dGciQ=M`cby%yy7_vg=&`%C4?iqloEGRGfB zHw`{zr!p}-2!UH@;^pbv6)7X1)p-$W>Ti5gmz2!Q-<7lQKQF318i@o`he$?#+8_EK z&=-x#T+!MR*(?h7dDiHxEcHnYZhl8jExCivN}Qa~P3~-2vn^L>rL?idsOhedeQfB8 zZwcXF0_bX;*_4BmT6&n0n&;$3^(8>HCm>#fFB2g1CG{XR90U!yYPOb>;ul;z#J2#= z3+@veFh$*Oq=-qgr0VN3 )MW<{jb>dUa>lKp1AQbDO(+2&`2n1cvdf1Fkli3x^E z0eDHI=->^;rTCWuuAJ3B zAPEYaS#kYw6EV>`aq^m4j!wt?;l~q$DK00++)SiO$>30HpECC%bJdPdn z0Ez^I-|ixu>o#%J{PKGcPdzE~7;}(SSOVM_}D$J^t9#qMzG?k8!*>7UnPuE+N-QnpYu-2@!AX7R#8F`P*_R1!Y7m zcGpB_zAJSMZ>&y3+@H_IZsSCU0Wl21?sbMR-CoPgOI!u^Otw`HCL0Z}=_fpxk7$3F z6X{!qNXNlR>J}DBZer5CJYCgs$At&u@h-`%qlYn6Ft$%sxyX=g(#N_Tttc+BGpR&PRc>8ObXuL87{>}xxixBWW!TO2Uw*4b3p7m3=-LdG+_f2}t%-Kj1J3r67~ zPWUr+3DkD-g6bO_XG_iZyw19brE(YkL($FSRK$MFi#{;iHPuJbYZA|y3@)IU&7rq3 zs5$t3##QeAxJ(VDB4t$0ZEF-bZ^z8<;&G&Qr_q-od7R&z@3TTZG|v2n!qH*W}Wf0CBJ47~ldf zz{WNG?R~t&nTAuwVFdOStI0h)6G`5={7Y4Z51tyd&^aiSpX<-2tQ8ElswtQgnmVaq zpH2OPt4cMKDj|pmQN`4$QR~O=sX|1C8l1?u2L*G;&vc4L+H`zy7w;Hnn-FV~OEKVA z529UlSWWaC@KA_aI_g+;h(yc~CE+q{eXCbqCymPl^|xa?yd6U>QD_SW>opo*N9AF! z92cya79w~n@?m>#><&q|!#5cf*g@aDiO<62G4wwZwJWf7KaQL+j7~$B%tviiG%N`V z9LH@sOu{$wDcG_~SW3Y+{G_p4F2a8>I<|`eIWHlLDLLM};xTd&-uWU9E84O3rdYcM zxM)w0Kh2ai<|^Xut^= zia}Ch?tvi^<}egvGkczZ#S;}Um$*v0XuX)K+juKtasrL4-(=`GuNBViiiT_|`3#QJ(=dJT+y~Ymm^6GB zs9G9LloWVyT*@vmh*d8=Cr0nBT>6KybtIRWawoHt4~E{`ht1a~vn(48_^#^tB|N$H z3lx8bRQWFwg|B<7whwFj$zrc@#GIx{Hy?;rHRHu_29?4ll5AFrC2iRVstDDx+>-BE z>waHR4;3HmaJyn;44V1%IW7!69I8Nt3Fpt(4d(ell!0@C=a$LdS>P?lx1IcgB(Lky zDnb%&MPC<}2a88U^|ZQj{euSG^C`Z_Jcgz!i&ErHt59>W=mtym8+)Z(xiRD77vTK{ zI@Hup+@Kp7SaW~Z<8M~vsnj)DjR&|sWm?0CX#*>5&Oum&LxD7`Fl9N|SixD}U%sl9 zP6htTVRk5RzvRQPFlHRX4gg(1qQ9+IGg)PQD|6{dwv(eCu`Y|&`$NpaW)QFDPxMq2 z(&pw%)|!&8i=jX|ny$t7b{UvtW8HBQ8aSyDzsXPGY7-63LH-b|) z;1mLAsPY}V3gZneGV10mmsn)wh;a@-_KaF$T$1~u!Pr&hfW?AEYMYd$KD>_fCR&*y zux7b&#KXGKRdA1$(^sFVbV}>F&@U-fa$?w3&lf1ZN*t3_Ha2S(b^nx)1hBL?%Q-qXM&^Wv9sv^{sGh51$zNt*P z&4) zlQ19v0POSQ5_xH^_h>QfDZWC!Nm^F(LuDn8dNz}HHc1gvf(<_ol z#U^=<@dMXz2^SO9>2$ob*kOP|mZ|wHrMEKGUIztxX@*H-#@&=(1+QG;u>XLa)GI^g zl;B0mE;lj18{e~redLS<*(?E=5*VltiEe(K50O*058>`H=>k?>3J{1E;J>Og{#X2; zb;tj@{_ka?|BRr&zWUEaqyM_{?*(fA3?VRp|DWY*|0?+J(TaaY9nHTf_`i%@{HyH0 zM<@OnT(tkD?EfxS@vq|l9*y{CO#Hjz|I66Kzsml*i~TbkxB&id4ks@K3igj_@V}m_ zzYJ#1{g2WA0#Hi>1QY-O00;o6ZdhA%ky10SLjV9YO#lEA0000`YiB`ob7gdMFGg%{ zcP@HqaLl}OtT0Wx=DTd$wr$(CZQHhO+qTVT*|zQVEYADwIs2TmCzJV-Ie*OQq`RxT zQ=Pl2b6r)xqW@jyJMhP`Oo*_yO%kymB{#UNO~`A zQ>XaefBgF2UVY=EWAQ-+&;50F>+jR96Qna$A`BOu@kYQHKOiZmHsnPl-gREa^o~V? z86bKa_^qB$pz`7|J1=Vm#Dhc@oz3K@Q4#A!&h?`pqb#LX9%KxU1M$&^cb~87am<;_ zqo|~gT@JTO33(ot3r5!j_?;gF&VRyvOFA zWCR9d)5R?fjpq59NIuoJ8o`Ot2^4B-d`TT;D&e(Ro`ZhCgUm|6?lkLA z^#u##mY2-$3elX&(oqKAdeCHzv>=_|2FtnTiMu0;^XQ7<7Um=NaS)Md*VJA|zx8ly{i6FTvdCH`&a>2E7XY zsiYaw+6sxMscoCt;869HZULNDml&2o7Y!}%|KfU>6PSj>5XMBYlEq}je6-d4dh`Bt zDl6}~n0?6?1JMWr8L4_Mc;~s&t&#%gs@1?}%2V=DIq9s-)6Bmb!`_sV-)&MQAHkvI z%{fdN-|rxj@wF4{a`Du_BOuN-t14XPONsU6G`{qKYHgfTa4vw7t%IFp$F^Q%2yQ>=2RqJ{6%SQxlgvdpIFtnUuBo0h$6n9Fb8@WS?tQ62>7fzrhGZcB8!Aa|G?obkl$N^d$g7JO=bV#4pVSGCw|>W>AL7;MI<_Y zwCJbwsF1mrYkeZ4UUbW&a$#TVj#oC$J6!d4Ao@VUqKgPd_!Tkc#1wT01Xfc?|Lh?P9=!$?U7 zh!{g^AQ9g#>fLprOwAKj4Aid?z%j}>^?>)5Jn*&mLzZ`;I-14PuU@P_gOrf7kvX5S zYxTWdF>l46o4}f-fyTs&fPac7JaK5Gkrr|&6b-otFVnF($uN$@L=gFt51*B>7TGa* z4qHECA%m}PNe3`d0$f?v>9m<0xjPp{%d>69_`18@h6!e5M46U{h5UFBM!@HGQqNy| zV}V`FsKMiq;A(cO5fBlX#pQCj1w#Y@mKy^Irpr`hrKe8u9ItOobk0AS2cDEaMD&@Y z%F)E`nEl#7Po#r%_a7kK9BxznaIFttGOqbZQ+S-C6O=SMMGT1LD5fsUrPPat+}NqL zbp5m%`2ZEy-?jR3fb#8| zs~mU6Gmz6>Y!H-KRJw1Efn-PK>Y(_$U6F~8eq=Bz!*=vF(}~Jt!cZfPOYKP8!!MGe z-e4BoGVz4+jdU8$h5i~nO>sr9^8KnkaFe4NdDV03P(J&Ss(%y7OGp{>FB`Z6DG~Ec ztxl|8al;CmAjjgXFne+F{17Mq9=i-L6NY?;_4xkv`o~&q^%v^i@t0M1g^IKzqv^tk;wcq&w!9H z0{a@7bgXkzs`)i8&R-ZF#u6Zn)pqmYQoSt4`D)B53cI~os1Spy&HNs*BrKkv2$#W! z0$xJaM(Z*geiRU0aB5!`SM;>dK&AZOi5k@eEz%+UVNC zi1NzB>gvjv!s^lt>0HPB9{(xAYl@-C$(b6EDQYsx5rSzlf{BS~5)vYkX}TJSDXNyi zA(9!GGICLyd2#!t9@S9XOxi>exI^V1DwCv_$94<>@kA(=D-c>n!U?Ud%w!xa)W7Xn zPA>4cayPg3HYi0A5+qISnAtv?a%Ag->@CD~R{^Lv)TMXEUlC>!FHkOKuy zY36d$6A&?pIL`%m;;I!Q24GXW)jx&Lx2oQsvF>3Vpp&MW9Y=j)0j7pK<+=z|I8q=U z4@>_Nmp0XIjuM4$@rTg4I*#J8n6b!Xaw3NY_a7G8&co$45jEvG40izeG??9}9%ij! zAx053lG+@5nPe4Re1Lz;xb4lW%$m+yf)_%|x=70U?74;b>FnhL@{_tl5wRApMqJVL z0|c0e(B`Rnb3D9cSWynfP{0=g^P9-oQV@7)a5{CvDLr$BB~YVO0@Uk7Z{-X}KcVqr z&Q7i6J#3;8X|pbl6=4qQW-RjBavXs~eX=&*4-E!pv+{`ui?nEHZKrsh;P&Nwb|;O> z%}tJ|txROjSQAm3@7#cwDRt|6HvNFBmcZPzv5%krO*euf*A;UavwD7*sM8{fok`rp zyaOMFSIiAZE#Wb%KPGhrxEe%;QsR4m+Wf&U3K5`|$>#3wb{y&wiJ`TT|8;j8AtbW)mVmuTUu0<=@T3R% z2fmI5p5cOYaX!}a@5g<2)HHo_6OId$b}Wu$zof3ucvYU+(VXLAC?vIB8Al0I!H!Pm z;v;5f@<`&HfysROYlZ}gqmm3B5xq&LsY>6Fd8{R~A`V*sLK3G5On7f7(6Fd8NQye%9x#=D$b=Oay@s{8Grx&Gk&I&Nc4&&CHHV?k{P*CK(trykD*_{UoQKvMalD zqx;$M^|kSZe$m~X{-v3@{)M5XsfC#b{*hgO@-pmg+*8^(lHZ?7d7s$ri)mQ88=moO z>&@&PoI}T>&grq{lB3)kn!9QQWKO73Ll1xKs(f}sw?K-bo8FKbkrE{jv30gjYaoq= zRs%%-S@+&DoIUj6t#;MX&!@)V#WU|Wj_|=hn#B0YN4EpLnFU#>z~MT6REabEqnzfE z=LK<;ngW`}7pdn2Gk6G;M~-LCWr?~MQ5rlb$1FLqCG9Y{3!9_ZnMd#gpL@`gdH&C@ zev_HG+1=9qg`R7kIvILO4(%|W8sGd^6Ao+m&X!CRz3SeD%I64z`5rn@>Y;`Wp41Xz zuOOKxK^SBYC9Ubq;zY8uO>^kq<_=r$dz!&K{){p^2Md#|o;k-~vrJPQ^rXC;h+Y)` zY;mBu-o1A|XFPjC^N_fnH)g@zbl&^g>Kr@F8urbOERT- zpgZxwk$U>yzB2;zbu~&3HBF?vERGJQ%5!vIxjF{?GQ|sE-9B=aWlydw1Mkya8)Pa2 zo>08D!W~KMvuz*zyYzVkrQ^7$q1WN5=Z$Eb1sCJ|d6}7rnLSRG0{JPJ zxJ%RbP;u{2yihFv;)fvjZBZwHyfK-@N#sP^65-m7H(g|Sc+W?|`uSA(p)jix@oOy8 zr&#R1gO9w3`RBwdC=w(Jcs@#USA7gqy zrbBneH2`!d3?vw&EwDu2!7y2UCmq;!18~WJdjpvtqHP_U~cGBKz*@&JS zx6X{JfwcC?Uer&{fE!uVZTMm)45L>DRDv{ory(upO!f z_R+=i05YXlvNzemB=#(H!U2iFbt89NgXH=}Me$uxWYM%V&?(o%#=Spp${?Ins9*#q^&MRU^(mB)x;+yvVg2iN7>8Qbaho-k7gzF( zvfxsC3n?E{@tGHrj;ta9HI1fRKQa~URoT~oUeo|zr9yY$?^n^Ory|Y%u67kpMO&SxkxDy4z>|MM$$p5aQ1gKNWnzO0f&MZztB*Rv-B^h`j($=T-fVu z8f`P0zJxBqVn*=PKuh5Z=MFc4K)BEwrHJMx=n)F|-mOox6oWCU2ry|AmG_D$Pg2+| zZxSJBR`a6ZQMEO)bN$t{UB!Ey0z1!~q=iQcx(}pH^I%0_+Bl|YO$tv=iOI$XfOiG4 zCuv(Vz?q~5WsG?WdVCol996B?68l3s1y1&9T1jqQ&8D)ts^vprpBQDt%VOommJwru zx3efF%rh`!^^oX^T&0_&jAqQ*ymzFJX)$orYHZ%zmMtJ5f17hkGjd>wXN+*j^`uZO z*{5OxgiRUHxW`d~N%xd=-6+$M6(bTDp)ih+Rriz#+pw|BS~=RfJQ^1VJ=J7E46aaT z-X#my$}?=v&8BhUodx#68Vby9GMqwiaH(4b3zvDB1@ch<_3=S#ig%NXECNh~`zYKq zBqdO4_r2adP-cpb>eB(9`X~H5&laQUWxyKN9DG}=;oWFd0$}+P9w|uk{NpeJ2RmA8 z1Atch+x`^Y*O;zGQ;sdUivbSwiC(~z&PpAzvAu?6XH0fGy8M=bEfF4nV0er%iJ z{=mhD^SYXLzWY%CJ9H}zgdEy0U1JZe_g;6_*kUCCcWkoR6`6ZBs9O^BMk+41w4R;ZCzO5I~QWKezgo*tLC!-%pi#w^+qpBA>|xMXTc9|81cv>UAM|VZWGvGs&7Cx zWD(_Q&Kg-F+ET?4Y6h@Z)`eRciFXOZ+V(1ye=XMSWgfG3+KwgKAH}%t`Q{`utwghp zzS`VPNe+~VGHBC~sYxnvbOszo9{n0wG2cm4f@a6<=qYKcN!MvN$|ThT-#X}D1bjkf z%0uX92s+LX$vr6Oi|~hibxt38L+YL~byH14H84p<8R2$-?AstORfUs*Ua%IhcVZ95>3)A65|#{m+TkKRqptONg?D&w2LdoI3$f1Jg>sqU+XOkfql#QNRfEf(Zi7Nv5l4($3=Pshy@xb8`E zJ-R(^z;*uxC>dEvB6tglW<~=@+JPt)3?Z1tGQ(e_R-pv9y)p{=C|?w>BFuA({JWdM ze+HHfh^%Au?}A?Ko7wUHRn1x4qD|eKn!JalxP3{#|E;;CYvlE|9}SOBddnb|k9Oy6 z?2+CMy*PnCrQcK>2L=*z8@APJ&YAL+L+YvORRs~{9<&Nc&D$S4BGlR7b{J_uu*at5 z1nDWF$YW*p^T^|q`NvSM*Hqog&`k|zn|#BButAV zcSGgZ^D@xMu6}a1iy3Al5&dIav&Wr|x+Nd|tNk2p>QvIfy74h0-pCuy;JWpNj^vie zy1J@bKHex#yT1SgKMEY*V`ii3FZu~r5}q}SA7_Hm)s*!0TD=A`c>~Y2&czEwSr`dX zu%;)K7872w$z5skc6_13W(m6K{ELfh5!nnfnZ!Wq9=0&mAWI|PiudiaS_4zwG1Y~D zyGy5l0{T3&7K5S9lm7QfGcH%N9xE+0SWc5p6%MnJ-aI0@g*FAuyYJu-(|)@ApP8oL zE9I3t?MPF<8a5**9Ec_Al90Bp>`P&@iw+Z1^dr!mfg^6;TA*hpR{rC8L}b+y0z80O zVNxU((9rAN=WvO|qnAD`DAq4mnj~OHLE=UWp@dTy7#s|0C4Dm>#J4j3MAewUXcUAk z%2LTAa09;jG$0aE6u!r}srt^3tLn~OjUUMc6yZ=F0WO}kV4+97`qA(x*?@~^=}@{y z{u>xY<*?vA20RC?^Tj7Mu!a&vFa3o%{D@))_XEqVj#*s{j2~?Uz&0x7kihQJlmAu! zI{AKdS=jnM^{v7k(!&jVm8bl<8e-)2W$jTxAy#O?Rh*!1$c4w|T-R&<#; zue^^#&4CkGJ-2NaE9yBaf+Cgq#z|?Am7QKNKeHfGCS?{tih=e^JkgfuIJjStV^Xcn z$VAu%=sTSc=TVEz-r{>6p5gf<&wJ6+oXi9`x5N7y^RUw%Z zcap^U8|}(PI{yXDT!kgr=qpA>pL)Ze#s1N3g9=v@{&{(oyQdn^q!qQzM+uF*(#EH z;0S1yuYxkiC_?Jbg*$A`C`&4v2m~@G;?#jJFUfyLeT+6-*|BSdV^Np``X`{5}<6{EgZ3%`I>g>stDX zvF?`V7_yIiy|)|bfxVGu?w6O&dy>p(o-Ro(b<5SHe}&?@@BMT9;bWbB z_Q+b7(eAc6H?y?%-XneLDJv^w^tso2kM!{r0aIzaBIJt<2z98n(;y7&h42ODj~K#= z)mMCm@JjT$xq@$BqAUljU$LQ9E0pG!l)M2xZkk?=_OrTvOg|sMKPogTBh%X|uA%6# z-r300;LD0{O>6T`MBPFC+_?R5!$gG}gxDwyQp(&jTW%7_!GDU=(f2Ri#o!M7u}clxPBRT$hPFJJ@k zOQ!>YP=|nQu_u_X50?0gkCNELgHYocs|JR$MwLs4lUiV%(C&Eh165hLkRC8*EK9pen`YilCQ&KSSz#aismv0DL{#R$qy8Ex_={r7J zCHhOOql(MiJI#4Fiwt5SbnS;{#%n)lW7ZX3IU><>_?lZZO4wg2f1L$H1ed2gsA{}f1Av?RXX^qSwgE&p+?<%Wj( zipQ#s&xg7qxqdU4YfO}26F(e8(O7m^*+LXlIG>0?5K_Ye-$K05kc5d~20g?OI{qs! zttMeFCr`>WMZJ`=4x2B*!5rG<5@In_d*&LFwj0q>F^3I5>C%;$v4oN*i_*a1jCc`m zN9CC|5cG}4JR6yZBCq#DFDa!>f~81)QttrU6OBxM6%U1gutx&OsO!TipqV#W(^&#- zn%gR!6IcM`24j5iZOjmu7;s4Z;|eMP3IL zC*)t+Tr@qyhEYXBG}GK&u@}${O~7S3rthi1!ox})=umhZbsas~e>=Cz3rK|T_2*Dc zFOFroNp2Pa2 zAlRl{rJ{w1bB24F5~5b=6rjQ~HhF*{eNd|LGgL$yAJdi`z@f+WXz|2YHYj*L@3$hS z`66`2i7*f!Y=K&Fk9)(bb#uk7zgR)wS0aH_|4*QJK@OFg{lo7PCA~SEukpfg?m5+c!kYZjo*6m~wJiQT)+C=zGKO-; zgYBmkB|FVR5DO2bPY1IhjPE*I<`keHSsYfto4D zB2v@bIulT^T=0Ii~EWE(Hf9Cv}@2J)kYGtZf=RFM{$w+{E%;RK_x= z#*DwTEw-iOMOKx$iKG|8)yj8Rw;R20HkU&~OA6uBZ*m)BQN%Lwz(ZEA&d8L3V|?Ry z#<7_V^|O3{4~t>>rZQSK*%^aoQw0sRC82%e$2Op>XE(gwhkrbMJ4iG)lQ7IT$w@hq(r&X zo-I~{yv3$|0@(JBsl~1ZWv)2<8U>OmN69skG!%7*?}ajT!tAtTTwFx!(jj;Fjm5L7AVXedHnYxZo4v+!neLMFNOjIYj9iBG!UK|>-{+(~`Ss}0IwD|W+Mb9ZVyHM_JnK;g2O*L7<3PPxSjf0>6iZ8?RzCM(AK0K;{SNVH5YC8E&Rh$Zmq>j zr564T)!I{m(G%h?|FB>(3uv{#ryP39aErZ4^&#bC0&?5Cma9% z#*%Nz<_~Fa;>kU>ge%3sInD~VoE#Gr2gTJKsT|9Ii5Smy1*8};^l5JTcV8x81ZT@e zr?`6c<+3o-qKqr{ErV4L#5q(XKvxYnYs`rc%hZsJozSEqx!N+>A;$$Rk0{Q)Q?`To z_lbxzV3lt%6x>oN2Qsm))Mq+*#G}^uQo2^z-)1mia;h;@VpFXi?TNXP#Se_7CDK~LZ|ON#8_$^DB?Qa)a_L1ZlU?G zxW+yebSPk32WpZqE|X!pPP_`ENhE$Kq*Z-IHN0fNl)$o^+8wQZ*iAFK7(>W_7pcm z!CZj4Aias?qutyB|5WX%bkXCN2Pd>9ggi`T1*m57S)5EDU6|tveiYPzqo7_6HN$3#(W!h+hIUyXt1`p+xzo&WIZt=``~rK)R?l>mD%I{{M21TYdL2z8+h<6+P#|BCU#y$&4-$fjX zeTAgaN`Koyqhr+4`N?gRPMB@_Ph27$0@sJ$>qH1lipoK+#DSPFt~=O~v=|>B6Ylpz z>riTC^LhM2LpoUI>^2=o&*A7+iH!(ZP?kRN?MAO^;o$wwB9hvbRe^{Jmk@F>Bm0+- zOvi29!CUy3(?ltH7T;)UO6ND>{M?m^O`#^QHO8~OWYDBEGr*I$aR}U)0@uI{j?5dfx8dxT*5b z9;_ZH=hHmLo+S5$Bq3W+yI;!LV>3P>JYh>dG!?vSDU)N5I`b^!mpCskbP|2Z|B&2E z;(k5efAHTPW$gL>)o#XrWf$wGtsOI1z)W@-^{$yanHxJ%a!j;L0f~d#nMujsYno>4 zKWFRFCNh2XW_%{o_BLg~G9cLjD+-Ca?fvWaGv6rwSycL6)GT#-EiOO&wde$F!OcAL zM`sVYKv39kIHjbIYgB_M;G=!_6bN_HO{NAp3U~PG=nGk3P$v6KOIr3*U01af9tU}& ziJiKu7E9eVxQ?$%PQQ-1rA6`cyfxP})6Gb;z)RQHT}MSdUA@~yiS?HJAlY|K?W(H& zUHT8Zy0BfKd*ax-nXhP_CwvZl;b8wl3w!!81w4~KFmr|NaGP;QjHiMu7^zpU#&)8- zaz8FUQVzWrOV&In8A?lDO{E@8>4Iq(vsaknAz{XysssgQiJj~bt^=_rU8%p&hl{x$ zVV>SI^)-k4Uv!BZMNJm*oadjCWxuJBCIm{p$Zwf8;!AtgK?p3X7*dSHz*xA>i@jyr z0tfug6c3M!Ng$S&{S*XgysIFfwlEdeTnbHR;?&8Panty&~f$KZ}Sxx+fa|1 z7Gm~{I&iRk4u$wx5E%WGrcJV&zHf4mD7kx5;9k2WOxYY2N}076ux48R5+4(7JX z19^d9mbsIUArU240WK)w@t|^&-MQx~uM4{ogy$lZhNIqf_G07+Aq?$PnSM^jAKS#% z6bIRN*kjEroZqgjPb$1>AC*O6zP1Qq)*Usx4CS=l#ZCtEsC~8Uew_P5U5kuIzco{V z`X@9L-^Y1*(}&w6_hu9Q(5hi=)}zn=L8`>ZUYIzJTnSG@eQ5 zv8_8x(68fy3JU>k5=@VZ)d^SmIg5~i_eN|5H9vG@Pmwq>p$r4mz=Efg!*5PaqdXk= z=);{r10hnf3Ki;O!2AglznP7m9l}3PRK;Mw$+Pp!Af94Zt{eJ-Bt;JzriImp@oef3 zIuZ9BI<#z$Vm@s2x@(=Me9Rz4`}+k|byfBq^;=B)V0gD(4gmWk4ix`#r&$^hLJCx@ zQMcvtJRx-E+=5DNe$-zfUS+zIR@c42fSI*sd?QnixKSBNo5_b3y_`JMP+4SSu!1X= z$CnlW#!Zu9(+^X~s&LJ9E-TtwQz`BUNti=kjC;JrubHsk`c@0Nv=IgO$l}dLF^0>L z`}Ngb%fTtP;X`pz($<-8z1+}+k>Xlc2O~asu+@rFT7>LX3KW(nW|`{hl0Y4e_4x60 z?D358GV8qFJn8lftiE1TT-W!FWZIX2w^kKX%|-3*_cM-c`#6VaCY?KTcyv4hocsP` z<`J3L1$2(va2}UB$UpOiQ+-f3fg>Te8(u6CYjl3~T3Ea)n$E_AY`gJfS~~j;?`2;f zI*7x?0Ry+^{DA}ec`X~4LL2AJCuE4|!vkEX?7xdcIPTA;ghQdZ#6kks)-i?$c4Scx z$O`iS!$R(GtgZ=4bko$9o~1t27()UEWpTe_$H3YQ&t(TSUS8rQrfYIAn{bfZ3Y=@r z*U958oW zQ-FsdH8ZW(5{4UHi#9)~U(58>X<;0W@xZdwq-syMKW0$96OVJBkS+p(yhMH*ye;)p z0w!MPYx9(AJkv^H*n9GOoEA4e1|}UErHw5OLWycWke#THRWQ`-_&2IYg{lTGfAbhO-XkWLqDK zuEZQnoxIVVil4?vYjU=%aN-;p__oxp%IJO31L!m(23yS2v~b-5YiYSX8LErjWzIfr zj+`r`p6)CKb{lD%QHx2`Jr1sj<@=X;zIU=$+n|}5vEd0a4pmO*%gyC0a?89(9u7ec z1>DmuZU8f0{+FSCNY1at5_0^yeq7`Za*fFtr%D~Li+Fj1=A`Lw$p|yLac*Q<{~o|H zzpZL$Z_&Z?QD6hgcmK&d)!BDadyhtNs=P;rt%b*naFy^}2--d?E1A?$f@K=ZO)Z>0 zsIRK0k~3OIq-y#nF#Ho#&&%XZ1iMGebcuCu@G_?~zE3{At%+|-uxkbwlJZ>3M|K*OUWw`mttpss1 zS)_+7SkH1=C}0;1r_DnCi~cIT*h+l@Fvhyn%I&in0^e?6pWO9{-M$-XQ^#SDP36$vRxNq(v z--YGeAsZpA9R(aK7g(0FIEzPJ>+c2;%6ml8Dr+>DlPE*#Y9RyhwQ0g2i# ziuVxS;X+*ATB5b6=QXdwc3YY~h&f?1HciBMB{jVBm&w$3nrR?$<$3YsNs#9f*U`|8 zmh!&}E#75b$~$_ijWI>M2y_%*+bzjN=?9kAwopcPC=z-OLABMW?7io%Y9z9BicQ;D z1;r{e=?mq`+he^>=w#LOv$q~p+w_I^1VsJI(Cn9U*p1^DuOx#NW|@oh2Ne4x9B$7| zjK7~lGoHoW>#O_Xf9Rn{m5xljA!oczBB7D+DPri~dR|>8s<9rp^=qh=jAAEcwNCOT$a!@4J9( z)zv_duT>3-PE&(lX0+koZ4I0&Tbfv2T^UqfiDv?Lg>p(uoHS55fk)onwWPT_F3bx4l;qzwOwe<8`~6JWyg!?KfTRH_MWx zAI{MDPDZSM@i4CaVlH_QC>Qc+2z^gj$e7QDAP)TCW9h;%i>eoVZ@ow{x;#Z^Md1=U9{J9~>`*{jk%62{QCL!Mv9yVMS3_p6r zhk?%mH;{6&i3{9WBwnj8kEvvLzB~fxA#nTyGvdbxq0%l?DRS5%rCR^^9H^65Y$_UK z>)7!2?+{Wa7)BQW5|s!qhp{;8FPeS>enFBqsDZFv)b@0Nmwu#>>4#|Co8KK&_z}N} zk0j(GcE*@5`BpGd)mSB{+%s}JB(0Ma_7Tb?^FZ1f+f0LqM%)sCSria$r(BMp@_RXr zIk*i9jG47ufKzbE###|ofj!I!HpRkU$aVDtawG_UgABz%)u%A3&fFdYz2fPEbwpsG6el-8ve!T<2%z*a7FnL1a0_G{VE%OTmJ=CD* z1aI$niBL)HM-X}`{p!&%(jLM@w{!NCW;V$FJ)4Ozg^{t0*U>{63@87P+ew7Z#DD_v z5%y#2J$Q5StK5?qF8(yF<3a49eEVd=5iC!+ySx*gJo6azTG_LnfsL4_q;9$+xnfz( z>f3TKVe!>>F)2|51IL8VdQAMHpYlx`-Ob1&OC6_M=m<2&%XlwQxMV%HD-aA2tx<^t z*eBxfW_9*NY=Yo4E*xaf=?VJsz#Te!QViiA_n7^yaU4&)|Nkt z_u4={&hb~Y&g3?6W->JK-CWIYsf0mR>$CIUVJJF^Ihr}$>IPnES>V)82RWs#8)q*Z zspl-=e^!W_Q(SVNNYc28jzrLYNiVGO*X4^=40DmQ@g(Dgmd(pgvuf*D^wqdgtI%+e zVGOrE8hMlC@sA#Ym)t4khRqC^4Z~qNBPY6w9MaUxinQm{eo)c4HrsBeV200xIe<&9 zNV)RgtlIVa6d+m7l-pk*r)Mes)nVyVl?x{Bh(o+(tI*+d%1PL@Q8V4->LxH~$@Sxp z>h0F0G2uZ>7)vm>AB3tijT|o8ep$-Ecw)qqf6tq7?xh|?2^3$TSwW{kf4RjTg7d;18-H89{Wog8d|vtJnh$lVPwp=3hkEMd$n&?K+u|TKvs2a5 zc()l$(dq)GpgHGHtmlQB+9Fc=R@aa_5N$M`ayG*-?`=uMxN`{>_CI<{ zvx1Z1k|iwa`eY^06W@h?%S}$S(~u0|zZ(9z>d6t1VUs{_5+&z*u;is+YDrY#y5LYt zB2c2$)x!jBk{P)1q4+#6Nlu3iT_gj3N>-C~c5!vOEPRBJQCb>~pbp6l^BoQk+1l~5 zWFULw$wCyh0P-!_(#bJ85SUf`RYk$za%MClQ4HfhvHv_Q2zfmSrY&A#@4G z_r-OqJ=YY7x)r*7b~a(4<2{m0U*%Z~<4_SaUNz+TTAR*KU-vx@qyq>CWYS&9nMS;?vKgq}FiP*< zOBo1}WVQ}5k{d^A!ju)oh7Vt4T+urg$?nK5SV=+Nbg$Xv zT`>^`39oj|AenKRrn^a13}=rwjtrgV?y~%eh2A3JUfL4;Od?%yb4zax5|7FNyi`m} zIc~b1jCnW7)7;*egCPeW%PLW^V*p=UuDPhgfa6~UxmUAd$n$7NmI^-omH9AL^lKNW^;HG$9=Ir=v%{wZ=&9NSL zp*Jo&AwLoz=UbgAk*|dEZd%iBCh(QdBBq?n;06N}{6o>6gEYZw0DXmDpJU7NH{FG8 zmS*M49)Ic<@2m(eS=V_m(bj@bX;<03&e$G^^cwDGR*<$3pV{^kKhlei^tbNDtbI?f zin!KecRJAK{kGn8Dll+jX!R4m(h_ld#V+y>NSdd~Ej(`X>5Px#75QA(8J;T5@*`49 zNZBKq&+Xh6PR5}9?@(#?PHO=5N0m5#r+c=eJj_-c??L6_>hf#-GPlM@ZJSeC=V6|@ z^lt9yjmbtzxS9-{qwZ-&9A8Cd0{_$5UMu`Kx)qG@`#zma8=~!>gX_O;sTXOv*4x%q z8>f6)1oOq`5nqXUY;_76V~#@IHh^9aX!cu!(7iPCfu-`tVR>yo%2?$~t;>sqI`x*T z_(nGpV1)sUj93`M(D26sJ$N2g-N=IS3WH5wZvOr+EGbkG+?z#C{@f_2qQIed#LMPhN zba$$Ca(RRHjE?Td{ zBVyT%F^Obo%-4Dcy!TMKagFde{F?{RLmy}(T`NwsuMfrQPQ0qjJY+m5MQwG^D!jx9 z%pw+{mTv#+jn5{_(1LwCqx3rGHC8O!d52=P$ImvRuh_>V)=4E4dsRZ8-`qh)O!p(U zMkMaHGWv7T5~8#p_ewj|mY>x~>a=;!x2X5F?yN9U$Hd1H-E_$#H$qfxIZSEJBeeh) zyG_+2da+YENP<;V6G+n2PInM7ya5RRBSlk)mLL3;8$r8`#$d!q+P|$O#>_kkT9f#r8NkHh#^my(zfaybAw0{ z(J9lL1v@Q!K$ct2#2U{5wg*Z074doJy)A|@h3kiA)yNeZm^O9}G)=p*n*wWmV#W^w z+*!{&MHnpacff!A^92Vc2V&A ztmE{OjPK>D0EU;D6es39l(eYAdWi75&@hxV)I-5uR^Q(t^H<>hq`J9_0MeoeSp4QV zL|lK)E7zH|MwiSq;f4#eE{)nfrZtkJ8mjvvTWvzseXca_2Vd;&eCvz-q(NOg_LwO` z=U>0F;r&r!)pCc#pwN#(AO8p^2fDj1r*?1YuGEkhWj2Y254~$6l0>#ASV*w?KO!ph zm)5Pl7IWSDNYYct7FJFa!+1?m&Ee8F^(u#JRj5?5ndvqG@Y!by{(gtyTjPCN;2rrR znu)(9HItTn1J6}+SfVo+T9*#6{X{sB0OQcAvB43@>Gy{B3RO;Y@bZw&;=TsT5M#qB zu2B5-YSV^^ch%$hk5*rEOS=?EoeCf&wasD>^BLrrFA@Hf`hB zIPxKm?+teANC)6)G{CWZ95gySVuiIz!ru%3Qofl{)M)yCPa?#@e?_(tbtVImBb0N*kYQSBpTQnbAF11NlQi%9w{!x@!jP zJ1SH0JqXSEuXz!F#W{uW@tfpdsZ87!qEZTEFVl%NO*(YAZoXWBXX-K+l`Mppy(q=g z^KFNOEH&e%06)sqwB;Ksum-&gI<8A`-Jr1H6U^zoO-N+>$riV1&|jta6wWLV1@ZH5 zplHRe4^dk82LSec*=<_dVx5pozF5x(y%i@^6mAs*<$xxZ3sg(qd5ZXTmR*MAuCs-1 z{M-^luVl9ur7vYgxN}L9%NytlevhOb?Q3ll4|3zHA} zk79R6w|Vy#1{WsQ_wa3v=^xOYpJBUSdY8}JqnG@>5v!5DF+&rZp%EjCAww&hv9a3O z3A>RYx!>QeAO7_R|ES*IE#^j+-&X`5ucDFy0#*XR1K91 zOU!1n(us}YMJR;6-$J%VMnmU^_OI#_kX#bOSXlSmuji;u{&rY^hC9IQAA$u)tmWgY&TqOr(MQRnY6Xj z$h0G$Z))PuP-wnAT2FqD{~09ak;GYMf55lME9NA0@K9Qv|B#$NKBC>B4Xs?z^frck zPO_q1*1K*;@5<4x&0Og8vuRq~dpfEX)_uy!qrxfqWsLO-wK~Q=Nd=Cyel8{N=KJ~u z{eI!V>Qd(B8r_(eLFA%b`I=l{)?`kaU);xDetlNIW8$Sb`kS&Z?Nr74ys*{4(GKHX z*KIaIo%x^}^g)4wvTa~8eIes3X(njlNS_IWlp@o-!(skytCfGqy>09ZJS-|n4u;2paoPA6cSE*x-8Du4btXk+ zcO%-0;cA19iNj2^Xp}?TedbmicT5yaV9azq!u~JXj`w1XmdQh+_L)Q6Y5rQQCMQua zoOp20IuGIY3yU0!D}O5uyyHdH(COL{vX_ju)Up~ zsj-W_(|?&C|5xPyQbPV$q?r5v#|%-B1_S@^9ppb5`kx-;|KII@08mQ-0u%rg00008 z0C9siTh43D)OH5|0Iw4O00;m800000000000Jebu0001KZgg^QE^TB`O928D02BZK z00;o6ZdhA%yoTTdfB*m;fB*ms00000000000002Cft&{b0B~VrYhh<)E_!KjP)h{{ V000000ssO4ZvX%Q$cF#`003z|6r}(F literal 19362 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