UNPKG

@ultipa-graph/ultipa-driver

Version:

NodeJS SDK for Ultipa GQL

257 lines 31.4 kB
"use strict"; /** * Type conversion utilities between gRPC proto types and JavaScript types. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildGqlRequest = buildGqlRequest; exports.buildParameters = buildParameters; exports.convertGqlResponse = convertGqlResponse; exports.convertTypedValue = convertTypedValue; exports.convertProtoProperties = convertProtoProperties; exports.convertGraphInfo = convertGraphInfo; exports.graphTypeToProto = graphTypeToProto; exports.protoToGraphType = protoToGraphType; exports.protoToHealthStatus = protoToHealthStatus; exports.cacheTypeToProto = cacheTypeToProto; exports.nodeDataToProto = nodeDataToProto; exports.edgeDataToProto = edgeDataToProto; const response_1 = require("../response"); const types_1 = require("../types"); /** * Build a GQL request from config. */ function buildGqlRequest(query, session, config, queryConfig) { return { gql: query, graph_name: queryConfig?.graphName || session?.defaultGraph || config.defaultGraph || '', parameters: buildParameters(queryConfig?.parameters), session_id: session?.id?.toString() || '0', transaction_id: queryConfig?.transactionId?.toString() || '0', timeout: Math.floor((queryConfig?.timeout || config.timeout || 30000) / 1000), // Convert ms to seconds for gRPC read_only: queryConfig?.readOnly || false, max_path_results: queryConfig?.maxPathResults || 0, }; } /** * Build parameters array for gRPC. */ function buildParameters(params) { if (!params) return []; return Object.entries(params).map(([name, value]) => ({ name, value: (0, types_1.createTypedValue)(value), })); } /** * Convert gRPC response to Response object. */ function convertGqlResponse(grpcResponse) { const columns = grpcResponse.columns || []; const rows = (grpcResponse.rows || []).map((row) => { const rawValues = row.values || []; const values = rawValues.map((tv) => convertTypedValue(tv)); const types = rawValues.map((tv) => protoTypeToEnum(tv?.type)); return new response_1.Row(values, types); }); return new response_1.Response(columns, rows, parseInt(grpcResponse.row_count || '0', 10), grpcResponse.has_more || false, grpcResponse.warnings || [], parseInt(grpcResponse.rows_affected || '0', 10), grpcResponse.current_graph || '', // Old servers omit these proto3 fields → 0 means "not reported". parseInt(grpcResponse.time_cost_ns || '0', 10), parseInt(grpcResponse.disk_cost_ns || '0', 10), parseInt(grpcResponse.compute_cost_ns || '0', 10)); } /** * Map proto type string or number to PropertyType enum. * Handles both string enum names (e.g., 'PROPERTY_TYPE_STRING') and numeric values. */ function protoTypeToEnum(protoType) { // Handle numeric enum values directly if (typeof protoType === 'number') { // If it's already a valid PropertyType number, return it directly // PropertyType ranges from UNSET(0) to EDGE(33) if (protoType >= types_1.PropertyType.UNSET && protoType <= types_1.PropertyType.EDGE) { return protoType; } return types_1.PropertyType.NULL; } const typeMap = { 'PROPERTY_TYPE_NULL': types_1.PropertyType.NULL, 'PROPERTY_TYPE_UNSET': types_1.PropertyType.UNSET, 'PROPERTY_TYPE_BOOL': types_1.PropertyType.BOOL, 'PROPERTY_TYPE_INT32': types_1.PropertyType.INT32, 'PROPERTY_TYPE_UINT32': types_1.PropertyType.UINT32, 'PROPERTY_TYPE_INT64': types_1.PropertyType.INT64, 'PROPERTY_TYPE_UINT64': types_1.PropertyType.UINT64, 'PROPERTY_TYPE_FLOAT': types_1.PropertyType.FLOAT, 'PROPERTY_TYPE_DOUBLE': types_1.PropertyType.DOUBLE, 'PROPERTY_TYPE_STRING': types_1.PropertyType.STRING, 'PROPERTY_TYPE_TEXT': types_1.PropertyType.TEXT, 'PROPERTY_TYPE_BLOB': types_1.PropertyType.BLOB, 'PROPERTY_TYPE_TIMESTAMP': types_1.PropertyType.TIMESTAMP, 'PROPERTY_TYPE_DATETIME': types_1.PropertyType.DATETIME, 'PROPERTY_TYPE_DATE': types_1.PropertyType.DATE, 'PROPERTY_TYPE_LOCAL_DATETIME': types_1.PropertyType.LOCAL_DATETIME, 'PROPERTY_TYPE_ZONED_DATETIME': types_1.PropertyType.ZONED_DATETIME, 'PROPERTY_TYPE_LOCAL_TIME': types_1.PropertyType.LOCAL_TIME, 'PROPERTY_TYPE_ZONED_TIME': types_1.PropertyType.ZONED_TIME, 'PROPERTY_TYPE_YEAR_TO_MONTH': types_1.PropertyType.YEAR_TO_MONTH, 'PROPERTY_TYPE_DAY_TO_SECOND': types_1.PropertyType.DAY_TO_SECOND, 'PROPERTY_TYPE_DECIMAL': types_1.PropertyType.DECIMAL, 'PROPERTY_TYPE_POINT': types_1.PropertyType.POINT, 'PROPERTY_TYPE_POINT3D': types_1.PropertyType.POINT3D, 'PROPERTY_TYPE_VECTOR': types_1.PropertyType.VECTOR, 'PROPERTY_TYPE_LIST': types_1.PropertyType.LIST, 'PROPERTY_TYPE_SET': types_1.PropertyType.SET, 'PROPERTY_TYPE_MAP': types_1.PropertyType.MAP, 'PROPERTY_TYPE_NODE': types_1.PropertyType.NODE, 'PROPERTY_TYPE_EDGE': types_1.PropertyType.EDGE, 'PROPERTY_TYPE_PATH': types_1.PropertyType.PATH, 'PROPERTY_TYPE_RECORD': types_1.PropertyType.RECORD, 'PROPERTY_TYPE_TABLE': types_1.PropertyType.TABLE, 'PROPERTY_TYPE_ERROR': types_1.PropertyType.ERROR, }; return typeMap[protoType] ?? types_1.PropertyType.NULL; } /** * Convert gRPC TypedValue to JS value. * Uses the same decoding logic as typedValueToJS for consistency. */ function convertTypedValue(tv) { if (!tv || tv.is_null || tv.isNull) return null; const data = tv.data; const protoType = tv.type; // Handle null types (both string and numeric enum values) if (protoType === 'PROPERTY_TYPE_NULL' || protoType === 'PROPERTY_TYPE_UNSET' || protoType === types_1.PropertyType.NULL || protoType === types_1.PropertyType.UNSET) { return null; } // Handle empty data - but STRING type with empty data should return "" if (!data || data.length === 0) { const isStringType = protoType === 'PROPERTY_TYPE_STRING' || protoType === 'PROPERTY_TYPE_TEXT' || protoType === types_1.PropertyType.STRING || protoType === types_1.PropertyType.TEXT; const isBlobType = protoType === 'PROPERTY_TYPE_BLOB' || protoType === types_1.PropertyType.BLOB; if (isStringType) { return ''; } if (isBlobType) { return Buffer.alloc(0); } return null; } const buf = Buffer.from(data); const enumType = protoTypeToEnum(protoType); // Use typedValueToJS for consistent decoding return (0, types_1.typedValueToJS)({ type: enumType, data: buf, isNull: false }); } /** * Convert proto properties map to JS object. */ function convertProtoProperties(protoProps) { const result = {}; for (const [key, tv] of Object.entries(protoProps)) { result[key] = convertTypedValue(tv); } return result; } /** * Convert GraphInfo from proto to JS object. */ function convertGraphInfo(g) { return { name: g.name || '', graphType: protoToGraphType(g.graph_type), nodeCount: parseInt(g.node_count || '0', 10), edgeCount: parseInt(g.edge_count || '0', 10), description: g.description || '', }; } /** * Map GraphType enum to proto string. */ function graphTypeToProto(graphType) { switch (graphType) { case types_1.GraphType.OPEN: return 'GRAPH_TYPE_OPEN'; case types_1.GraphType.CLOSED: return 'GRAPH_TYPE_CLOSED'; case types_1.GraphType.ONTOLOGY: return 'GRAPH_TYPE_ONTOLOGY'; default: return 'GRAPH_TYPE_OPEN'; } } /** * Map proto string to GraphType enum. */ function protoToGraphType(proto) { switch (proto) { case 'GRAPH_TYPE_CLOSED': return types_1.GraphType.CLOSED; case 'GRAPH_TYPE_ONTOLOGY': return types_1.GraphType.ONTOLOGY; default: return types_1.GraphType.OPEN; } } /** * Map proto HealthStatus to enum. */ function protoToHealthStatus(proto) { switch (proto) { case 'HEALTH_STATUS_SERVING': return types_1.HealthStatus.SERVING; case 'HEALTH_STATUS_NOT_SERVING': return types_1.HealthStatus.NOT_SERVING; case 'HEALTH_STATUS_SERVICE_UNKNOWN': return types_1.HealthStatus.SERVICE_UNKNOWN; default: return types_1.HealthStatus.UNKNOWN; } } /** * Map CacheType to proto string. */ function cacheTypeToProto(cacheType) { switch (cacheType) { case types_1.CacheType.AST: return 'CACHE_TYPE_AST'; case types_1.CacheType.PLAN: return 'CACHE_TYPE_PLAN'; default: return 'CACHE_TYPE_ALL'; } } /** * Convert NodeData to proto format. */ function nodeDataToProto(node) { const properties = {}; if (node.properties) { for (const [key, value] of Object.entries(node.properties)) { properties[key] = (0, types_1.createTypedValue)(value); } } return { id: node.id || '', labels: node.labels || [], properties, }; } /** * Convert EdgeData to proto format. */ function edgeDataToProto(edge) { const properties = {}; if (edge.properties) { for (const [key, value] of Object.entries(edge.properties)) { properties[key] = (0, types_1.createTypedValue)(value); } } return { id: edge.id || '', label: edge.label || '', from_node_id: edge.fromNodeId || '', to_node_id: edge.toNodeId || '', properties, }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9jb252ZXJ0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7R0FFRzs7QUFtQkgsMENBZ0JDO0FBS0QsMENBTUM7QUFLRCxnREFxQkM7QUE0REQsOENBZ0NDO0FBS0Qsd0RBTUM7QUFLRCw0Q0FRQztBQUtELDRDQVdDO0FBS0QsNENBU0M7QUFLRCxrREFXQztBQUtELDRDQVNDO0FBS0QsMENBWUM7QUFLRCwwQ0FjQztBQTFSRCwwQ0FBNEM7QUFDNUMsb0NBUWtCO0FBS2xCOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUM3QixLQUFhLEVBQ2IsT0FBdUIsRUFDdkIsTUFBbUIsRUFDbkIsV0FBeUI7SUFFekIsT0FBTztRQUNMLEdBQUcsRUFBRSxLQUFLO1FBQ1YsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLElBQUksT0FBTyxFQUFFLFlBQVksSUFBSSxNQUFNLENBQUMsWUFBWSxJQUFJLEVBQUU7UUFDeEYsVUFBVSxFQUFFLGVBQWUsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDO1FBQ3BELFVBQVUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEdBQUc7UUFDMUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLElBQUksR0FBRztRQUM3RCxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxpQ0FBaUM7UUFDaEgsU0FBUyxFQUFFLFdBQVcsRUFBRSxRQUFRLElBQUksS0FBSztRQUN6QyxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsY0FBYyxJQUFJLENBQUM7S0FDbkQsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxNQUE0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SUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzNELFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFBLHdCQUFnQixFQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTztRQUNMLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUU7UUFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRTtRQUN6QixVQUFVO0tBQ1gsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxJQUFTO0lBQ3ZDLE1BQU0sVUFBVSxHQUF3QixFQUFFLENBQUM7SUFDM0MsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDM0QsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUEsd0JBQWdCLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPO1FBQ0wsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRTtRQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUU7UUFDbkMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTtRQUMvQixVQUFVO0tBQ1gsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFR5cGUgY29udmVyc2lvbiB1dGlsaXRpZXMgYmV0d2VlbiBnUlBDIHByb3RvIHR5cGVzIGFuZCBKYXZhU2NyaXB0IHR5cGVzLlxuICovXG5cbmltcG9ydCB7IFJlc3BvbnNlLCBSb3cgfSBmcm9tICcuLi9yZXNwb25zZSc7XG5pbXBvcnQge1xuICBHcmFwaFR5cGUsXG4gIEhlYWx0aFN0YXR1cyxcbiAgQ2FjaGVUeXBlLFxuICBHcmFwaEluZm8sXG4gIGNyZWF0ZVR5cGVkVmFsdWUsXG4gIFByb3BlcnR5VHlwZSxcbiAgdHlwZWRWYWx1ZVRvSlMsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IEdxbGRiQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi9zZXNzaW9uJztcbmltcG9ydCB7IFF1ZXJ5Q29uZmlnIH0gZnJvbSAnLi4vY2xpZW50JztcblxuLyoqXG4gKiBCdWlsZCBhIEdRTCByZXF1ZXN0IGZyb20gY29uZmlnLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRHcWxSZXF1ZXN0KFxuICBxdWVyeTogc3RyaW5nLFxuICBzZXNzaW9uOiBTZXNzaW9uIHwgbnVsbCxcbiAgY29uZmlnOiBHcWxkYkNvbmZpZyxcbiAgcXVlcnlDb25maWc/OiBRdWVyeUNvbmZpZ1xuKTogYW55IHtcbiAgcmV0dXJuIHtcbiAgICBncWw6IHF1ZXJ5LFxuICAgIGdyYXBoX25hbWU6IHF1ZXJ5Q29uZmlnPy5ncmFwaE5hbWUgfHwgc2Vzc2lvbj8uZGVmYXVsdEdyYXBoIHx8IGNvbmZpZy5kZWZhdWx0R3JhcGggfHwgJycsXG4gICAgcGFyYW1ldGVyczogYnVpbGRQYXJhbWV0ZXJzKHF1ZXJ5Q29uZmlnPy5wYXJhbWV0ZXJzKSxcbiAgICBzZXNzaW9uX2lkOiBzZXNzaW9uPy5pZD8udG9TdHJpbmcoKSB8fCAnMCcsXG4gICAgdHJhbnNhY3Rpb25faWQ6IHF1ZXJ5Q29uZmlnPy50cmFuc2FjdGlvbklkPy50b1N0cmluZygpIHx8ICcwJyxcbiAgICB0aW1lb3V0OiBNYXRoLmZsb29yKChxdWVyeUNvbmZpZz8udGltZW91dCB8fCBjb25maWcudGltZW91dCB8fCAzMDAwMCkgLyAxMDAwKSwgLy8gQ29udmVydCBtcyB0byBzZWNvbmRzIGZvciBnUlBDXG4gICAgcmVhZF9vbmx5OiBxdWVyeUNvbmZpZz8ucmVhZE9ubHkgfHwgZmFsc2UsXG4gICAgbWF4X3BhdGhfcmVzdWx0czogcXVlcnlDb25maWc/Lm1heFBhdGhSZXN1bHRzIHx8IDAsXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgcGFyYW1ldGVycyBhcnJheSBmb3IgZ1JQQy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGFyYW1ldGVycyhwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogYW55W10ge1xuICBpZiAoIXBhcmFtcykgcmV0dXJuIFtdO1xuICByZXR1cm4gT2JqZWN0LmVudHJpZXMocGFyYW1zKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7XG4gICAgbmFtZSxcbiAgICB2YWx1ZTogY3JlYXRlVHlwZWRWYWx1ZSh2YWx1ZSksXG4gIH0pKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGdSUEMgcmVzcG9uc2UgdG8gUmVzcG9uc2Ugb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEdxbFJlc3BvbnNlKGdycGNSZXNwb25zZTogYW55KTogUmVzcG9uc2Uge1xuICBjb25zdCBjb2x1bW5zID0gZ3JwY1Jlc3BvbnNlLmNvbHVtbnMgfHwgW107XG4gIGNvbnN0IHJvd3M6IFJvd1tdID0gKGdycGNSZXNwb25zZS5yb3dzIHx8IFtdKS5tYXAoKHJvdzogYW55KSA9PiB7XG4gICAgY29uc3QgcmF3VmFsdWVzID0gcm93LnZhbHVlcyB8fCBbXTtcbiAgICBjb25zdCB2YWx1ZXMgPSByYXdWYWx1ZXMubWFwKCh0djogYW55KSA9PiBjb252ZXJ0VHlwZWRWYWx1ZSh0dikpO1xuICAgIGNvbnN0IHR5cGVzID0gcmF3VmFsdWVzLm1hcCgodHY6IGFueSkgPT4gcHJvdG9UeXBlVG9FbnVtKHR2Py50eXBlKSk7XG4gICAgcmV0dXJuIG5ldyBSb3codmFsdWVzLCB0eXBlcyk7XG4gIH0pO1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKFxuICAgIGNvbHVtbnMsXG4gICAgcm93cyxcbiAgICBwYXJzZUludChncnBjUmVzcG9uc2Uucm93X2NvdW50IHx8ICcwJywgMTApLFxuICAgIGdycGNSZXNwb25zZS5oYXNfbW9yZSB8fCBmYWxzZSxcbiAgICBncnBjUmVzcG9uc2Uud2FybmluZ3MgfHwgW10sXG4gICAgcGFyc2VJbnQoZ3JwY1Jlc3BvbnNlLnJvd3NfYWZmZWN0ZWQgfHwgJzAnLCAxMCksXG4gICAgZ3JwY1Jlc3BvbnNlLmN1cnJlbnRfZ3JhcGggfHwgJycsXG4gICAgLy8gT2xkIHNlcnZlcnMgb21pdCB0aGVzZSBwcm90bzMgZmllbGRzIOKGkiAwIG1lYW5zIFwibm90IHJlcG9ydGVkXCIuXG4gICAgcGFyc2VJbnQoZ3JwY1Jlc3BvbnNlLnRpbWVfY29zdF9ucyB8fCAnMCcsIDEwKSxcbiAgICBwYXJzZUludChncnBjUmVzcG9uc2UuZGlza19jb3N0X25zIHx8ICcwJywgMTApLFxuICAgIHBhcnNlSW50KGdycGNSZXNwb25zZS5jb21wdXRlX2Nvc3RfbnMgfHwgJzAnLCAxMClcbiAgKTtcbn1cblxuLyoqXG4gKiBNYXAgcHJvdG8gdHlwZSBzdHJpbmcgb3IgbnVtYmVyIHRvIFByb3BlcnR5VHlwZSBlbnVtLlxuICogSGFuZGxlcyBib3RoIHN0cmluZyBlbnVtIG5hbWVzIChlLmcuLCAnUFJPUEVSVFlfVFlQRV9TVFJJTkcnKSBhbmQgbnVtZXJpYyB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIHByb3RvVHlwZVRvRW51bShwcm90b1R5cGU6IHN0cmluZyB8IG51bWJlcik6IFByb3BlcnR5VHlwZSB7XG4gIC8vIEhhbmRsZSBudW1lcmljIGVudW0gdmFsdWVzIGRpcmVjdGx5XG4gIGlmICh0eXBlb2YgcHJvdG9UeXBlID09PSAnbnVtYmVyJykge1xuICAgIC8vIElmIGl0J3MgYWxyZWFkeSBhIHZhbGlkIFByb3BlcnR5VHlwZSBudW1iZXIsIHJldHVybiBpdCBkaXJlY3RseVxuICAgIC8vIFByb3BlcnR5VHlwZSByYW5nZXMgZnJvbSBVTlNFVCgwKSB0byBFREdFKDMzKVxuICAgIGlmIChwcm90b1R5cGUgPj0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHByb3RvVHlwZSA8PSBQcm9wZXJ0eVR5cGUuRURHRSkge1xuICAgICAgcmV0dXJuIHByb3RvVHlwZSBhcyBQcm9wZXJ0eVR5cGU7XG4gICAgfVxuICAgIHJldHVybiBQcm9wZXJ0eVR5cGUuTlVMTDtcbiAgfVxuXG4gIGNvbnN0IHR5cGVNYXA6IFJlY29yZDxzdHJpbmcsIFByb3BlcnR5VHlwZT4gPSB7XG4gICAgJ1BST1BFUlRZX1RZUEVfTlVMTCc6IFByb3BlcnR5VHlwZS5OVUxMLFxuICAgICdQUk9QRVJUWV9UWVBFX1VOU0VUJzogUHJvcGVydHlUeXBlLlVOU0VULFxuICAgICdQUk9QRVJUWV9UWVBFX0JPT0wnOiBQcm9wZXJ0eVR5cGUuQk9PTCxcbiAgICAnUFJPUEVSVFlfVFlQRV9JTlQzMic6IFByb3BlcnR5VHlwZS5JTlQzMixcbiAgICAnUFJPUEVSVFlfVFlQRV9VSU5UMzInOiBQcm9wZXJ0eVR5cGUuVUlOVDMyLFxuICAgICdQUk9QRVJUWV9UWVBFX0lOVDY0JzogUHJvcGVydHlUeXBlLklOVDY0LFxuICAgICdQUk9QRVJUWV9UWVBFX1VJTlQ2NCc6IFByb3BlcnR5VHlwZS5VSU5UNjQsXG4gICAgJ1BST1BFUlRZX1RZUEVfRkxPQVQnOiBQcm9wZXJ0eVR5cGUuRkxPQVQsXG4gICAgJ1BST1BFUlRZX1RZUEVfRE9VQkxFJzogUHJvcGVydHlUeXBlLkRPVUJMRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9TVFJJTkcnOiBQcm9wZXJ0eVR5cGUuU1RSSU5HLFxuICAgICdQUk9QRVJUWV9UWVBFX1RFWFQnOiBQcm9wZXJ0eVR5cGUuVEVYVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9CTE9CJzogUHJvcGVydHlUeXBlLkJMT0IsXG4gICAgJ1BST1BFUlRZX1RZUEVfVElNRVNUQU1QJzogUHJvcGVydHlUeXBlLlRJTUVTVEFNUCxcbiAgICAnUFJPUEVSVFlfVFlQRV9EQVRFVElNRSc6IFByb3BlcnR5VHlwZS5EQVRFVElNRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9EQVRFJzogUHJvcGVydHlUeXBlLkRBVEUsXG4gICAgJ1BST1BFUlRZX1RZUEVfTE9DQUxfREFURVRJTUUnOiBQcm9wZXJ0eVR5cGUuTE9DQUxfREFURVRJTUUsXG4gICAgJ1BST1BFUlRZX1RZUEVfWk9ORURfREFURVRJTUUnOiBQcm9wZXJ0eVR5cGUuWk9ORURfREFURVRJTUUsXG4gICAgJ1BST1BFUlRZX1RZUEVfTE9DQUxfVElNRSc6IFByb3BlcnR5VHlwZS5MT0NBTF9USU1FLFxuICAgICdQUk9QRVJUWV9UWVBFX1pPTkVEX1RJTUUnOiBQcm9wZXJ0eVR5cGUuWk9ORURfVElNRSxcbiAgICAnUFJPUEVSVFlfVFlQRV9ZRUFSX1RPX01PTlRIJzogUHJvcGVydHlUeXBlLllFQVJfVE9fTU9OVEgsXG4gICAgJ1BST1BFUlRZX1RZUEVfREFZX1RPX1NFQ09ORCc6IFByb3BlcnR5VHlwZS5EQVlfVE9fU0VDT05ELFxuICAgICdQUk9QRVJUWV9UWVBFX0RFQ0lNQUwnOiBQcm9wZXJ0eVR5cGUuREVDSU1BTCxcbiAgICAnUFJPUEVSVFlfVFlQRV9QT0lOVCc6IFByb3BlcnR5VHlwZS5QT0lOVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9QT0lOVDNEJzogUHJvcGVydHlUeXBlLlBPSU5UM0QsXG4gICAgJ1BST1BFUlRZX1RZUEVfVkVDVE9SJzogUHJvcGVydHlUeXBlLlZFQ1RPUixcbiAgICAnUFJPUEVSVFlfVFlQRV9MSVNUJzogUHJvcGVydHlUeXBlLkxJU1QsXG4gICAgJ1BST1BFUlRZX1RZUEVfU0VUJzogUHJvcGVydHlUeXBlLlNFVCxcbiAgICAnUFJPUEVSVFlfVFlQRV9NQVAnOiBQcm9wZXJ0eVR5cGUuTUFQLFxuICAgICdQUk9QRVJUWV9UWVBFX05PREUnOiBQcm9wZXJ0eVR5cGUuTk9ERSxcbiAgICAnUFJPUEVSVFlfVFlQRV9FREdFJzogUHJvcGVydHlUeXBlLkVER0UsXG4gICAgJ1BST1BFUlRZX1RZUEVfUEFUSCc6IFByb3BlcnR5VHlwZS5QQVRILFxuICAgICdQUk9QRVJUWV9UWVBFX1JFQ09SRCc6IFByb3BlcnR5VHlwZS5SRUNPUkQsXG4gICAgJ1BST1BFUlRZX1RZUEVfVEFCTEUnOiBQcm9wZXJ0eVR5cGUuVEFCTEUsXG4gICAgJ1BST1BFUlRZX1RZUEVfRVJST1InOiBQcm9wZXJ0eVR5cGUuRVJST1IsXG4gIH07XG4gIHJldHVybiB0eXBlTWFwW3Byb3RvVHlwZV0gPz8gUHJvcGVydHlUeXBlLk5VTEw7XG59XG5cbi8qKlxuICogQ29udmVydCBnUlBDIFR5cGVkVmFsdWUgdG8gSlMgdmFsdWUuXG4gKiBVc2VzIHRoZSBzYW1lIGRlY29kaW5nIGxvZ2ljIGFzIHR5cGVkVmFsdWVUb0pTIGZvciBjb25zaXN0ZW5jeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUeXBlZFZhbHVlKHR2OiBhbnkpOiBhbnkge1xuICBpZiAoIXR2IHx8IHR2LmlzX251bGwgfHwgdHYuaXNOdWxsKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCBkYXRhID0gdHYuZGF0YTtcbiAgY29uc3QgcHJvdG9UeXBlID0gdHYudHlwZTtcblxuICAvLyBIYW5kbGUgbnVsbCB0eXBlcyAoYm90aCBzdHJpbmcgYW5kIG51bWVyaWMgZW51bSB2YWx1ZXMpXG4gIGlmIChwcm90b1R5cGUgPT09ICdQUk9QRVJUWV9UWVBFX05VTEwnIHx8IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfVU5TRVQnIHx8XG4gICAgICBwcm90b1R5cGUgPT09IFByb3BlcnR5VHlwZS5OVUxMIHx8IHByb3RvVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBIYW5kbGUgZW1wdHkgZGF0YSAtIGJ1dCBTVFJJTkcgdHlwZSB3aXRoIGVtcHR5IGRhdGEgc2hvdWxkIHJldHVybiBcIlwiXG4gIGlmICghZGF0YSB8fCBkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnN0IGlzU3RyaW5nVHlwZSA9IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfU1RSSU5HJyB8fCBwcm90b1R5cGUgPT09ICdQUk9QRVJUWV9UWVBFX1RFWFQnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9UeXBlID09PSBQcm9wZXJ0eVR5cGUuU1RSSU5HIHx8IHByb3RvVHlwZSA9PT0gUHJvcGVydHlUeXBlLlRFWFQ7XG4gICAgY29uc3QgaXNCbG9iVHlwZSA9IHByb3RvVHlwZSA9PT0gJ1BST1BFUlRZX1RZUEVfQkxPQicgfHwgcHJvdG9UeXBlID09PSBQcm9wZXJ0eVR5cGUuQkxPQjtcblxuICAgIGlmIChpc1N0cmluZ1R5cGUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKGlzQmxvYlR5cGUpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgYnVmID0gQnVmZmVyLmZyb20oZGF0YSk7XG4gIGNvbnN0IGVudW1UeXBlID0gcHJvdG9UeXBlVG9FbnVtKHByb3RvVHlwZSk7XG5cbiAgLy8gVXNlIHR5cGVkVmFsdWVUb0pTIGZvciBjb25zaXN0ZW50IGRlY29kaW5nXG4gIHJldHVybiB0eXBlZFZhbHVlVG9KUyh7IHR5cGU6IGVudW1UeXBlLCBkYXRhOiBidWYsIGlzTnVsbDogZmFsc2UgfSk7XG59XG5cbi8qKlxuICogQ29udmVydCBwcm90byBwcm9wZXJ0aWVzIG1hcCB0byBKUyBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UHJvdG9Qcm9wZXJ0aWVzKHByb3RvUHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdHZdIG9mIE9iamVjdC5lbnRyaWVzKHByb3RvUHJvcHMpKSB7XG4gICAgcmVzdWx0W2tleV0gPSBjb252ZXJ0VHlwZWRWYWx1ZSh0dik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IEdyYXBoSW5mbyBmcm9tIHByb3RvIHRvIEpTIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRHcmFwaEluZm8oZzogYW55KTogR3JhcGhJbmZvIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBnLm5hbWUgfHwgJycsXG4gICAgZ3JhcGhUeXBlOiBwcm90b1RvR3JhcGhUeXBlKGcuZ3JhcGhfdHlwZSksXG4gICAgbm9kZUNvdW50OiBwYXJzZUludChnLm5vZGVfY291bnQgfHwgJzAnLCAxMCksXG4gICAgZWRnZUNvdW50OiBwYXJzZUludChnLmVkZ2VfY291bnQgfHwgJzAnLCAxMCksXG4gICAgZGVzY3JpcHRpb246IGcuZGVzY3JpcHRpb24gfHwgJycsXG4gIH07XG59XG5cbi8qKlxuICogTWFwIEdyYXBoVHlwZSBlbnVtIHRvIHByb3RvIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyYXBoVHlwZVRvUHJvdG8oZ3JhcGhUeXBlOiBHcmFwaFR5cGUpOiBzdHJpbmcge1xuICBzd2l0Y2ggKGdyYXBoVHlwZSkge1xuICAgIGNhc2UgR3JhcGhUeXBlLk9QRU46XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT1BFTic7XG4gICAgY2FzZSBHcmFwaFR5cGUuQ0xPU0VEOlxuICAgICAgcmV0dXJuICdHUkFQSF9UWVBFX0NMT1NFRCc7XG4gICAgY2FzZSBHcmFwaFR5cGUuT05UT0xPR1k6XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT05UT0xPR1knO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ0dSQVBIX1RZUEVfT1BFTic7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXAgcHJvdG8gc3RyaW5nIHRvIEdyYXBoVHlwZSBlbnVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdG9Ub0dyYXBoVHlwZShwcm90bzogc3RyaW5nKTogR3JhcGhUeXBlIHtcbiAgc3dpdGNoIChwcm90bykge1xuICAgIGNhc2UgJ0dSQVBIX1RZUEVfQ0xPU0VEJzpcbiAgICAgIHJldHVybiBHcmFwaFR5cGUuQ0xPU0VEO1xuICAgIGNhc2UgJ0dSQVBIX1RZUEVfT05UT0xPR1knOlxuICAgICAgcmV0dXJuIEdyYXBoVHlwZS5PTlRPTE9HWTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIEdyYXBoVHlwZS5PUEVOO1xuICB9XG59XG5cbi8qKlxuICogTWFwIHByb3RvIEhlYWx0aFN0YXR1cyB0byBlbnVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdG9Ub0hlYWx0aFN0YXR1cyhwcm90bzogc3RyaW5nKTogSGVhbHRoU3RhdHVzIHtcbiAgc3dpdGNoIChwcm90bykge1xuICAgIGNhc2UgJ0hFQUxUSF9TVEFUVVNfU0VSVklORyc6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLlNFUlZJTkc7XG4gICAgY2FzZSAnSEVBTFRIX1NUQVRVU19OT1RfU0VSVklORyc6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLk5PVF9TRVJWSU5HO1xuICAgIGNhc2UgJ0hFQUxUSF9TVEFUVVNfU0VSVklDRV9VTktOT1dOJzpcbiAgICAgIHJldHVybiBIZWFsdGhTdGF0dXMuU0VSVklDRV9VTktOT1dOO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gSGVhbHRoU3RhdHVzLlVOS05PV047XG4gIH1cbn1cblxuLyoqXG4gKiBNYXAgQ2FjaGVUeXBlIHRvIHByb3RvIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhY2hlVHlwZVRvUHJvdG8oY2FjaGVUeXBlOiBDYWNoZVR5cGUpOiBzdHJpbmcge1xuICBzd2l0Y2ggKGNhY2hlVHlwZSkge1xuICAgIGNhc2UgQ2FjaGVUeXBlLkFTVDpcbiAgICAgIHJldHVybiAnQ0FDSEVfVFlQRV9BU1QnO1xuICAgIGNhc2UgQ2FjaGVUeXBlLlBMQU46XG4gICAgICByZXR1cm4gJ0NBQ0hFX1RZUEVfUExBTic7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnQ0FDSEVfVFlQRV9BTEwnO1xuICB9XG59XG5cbi8qKlxuICogQ29udmVydCBOb2RlRGF0YSB0byBwcm90byBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub2RlRGF0YVRvUHJvdG8obm9kZTogYW55KTogYW55IHtcbiAgY29uc3QgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICBpZiAobm9kZS5wcm9wZXJ0aWVzKSB7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobm9kZS5wcm9wZXJ0aWVzKSkge1xuICAgICAgcHJvcGVydGllc1trZXldID0gY3JlYXRlVHlwZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgaWQ6IG5vZGUuaWQgfHwgJycsXG4gICAgbGFiZWxzOiBub2RlLmxhYmVscyB8fCBbXSxcbiAgICBwcm9wZXJ0aWVzLFxuICB9O1xufVxuXG4vKipcbiAqIENvbnZlcnQgRWRnZURhdGEgdG8gcHJvdG8gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWRnZURhdGFUb1Byb3RvKGVkZ2U6IGFueSk6IGFueSB7XG4gIGNvbnN0IHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgaWYgKGVkZ2UucHJvcGVydGllcykge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGVkZ2UucHJvcGVydGllcykpIHtcbiAgICAgIHByb3BlcnRpZXNba2V5XSA9IGNyZWF0ZVR5cGVkVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGlkOiBlZGdlLmlkIHx8ICcnLFxuICAgIGxhYmVsOiBlZGdlLmxhYmVsIHx8ICcnLFxuICAgIGZyb21fbm9kZV9pZDogZWRnZS5mcm9tTm9kZUlkIHx8ICcnLFxuICAgIHRvX25vZGVfaWQ6IGVkZ2UudG9Ob2RlSWQgfHwgJycsXG4gICAgcHJvcGVydGllcyxcbiAgfTtcbn1cbiJdfQ==