@decaf-ts/for-postgres
Version:
template for ts projects
182 lines • 18.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PostgresPaginator = void 0;
const core_1 = require("@decaf-ts/core");
/**
* @description Paginator for PostgreSQL query results
* @summary Implements pagination for PostgreSQL queries using LIMIT and OFFSET for efficient navigation through result sets
* @template M - The model type that extends Model
* @template R - The result type
* @param {PostgresAdapter<any, any, any>} adapter - The PostgreSQL adapter
* @param {PostgresQuery} query - The PostgresSQL query to paginate
* @param {number} size - The page size
* @param {Constructor<M>} clazz - The model constructor
* @class PostgresPaginator
* @example
* // Example of using PostgreSQLPaginator
* const adapter = new MyPostgreSQLAdapter(pool);
* const query = { table: "users" };
* const paginator = new PostgreSQLPaginator(adapter, query, 10, User);
*
* // Get the first page
* const page1 = await paginator.page(1);
*
* // Get the next page
* const page2 = await paginator.page(2);
*/
class PostgresPaginator extends core_1.Paginator {
/**
* @description Gets the total number of pages
* @summary Returns the total number of pages based on the record count and page size
* @return {number} The total number of pages
*/
get total() {
return this._totalPages;
}
/**
* @description Gets the total record count
* @summary Returns the total number of records matching the query
* @return {number} The total record count
*/
get count() {
return this._recordCount;
}
/**
* @description Creates a new PostgreSQLPaginator instance
* @summary Initializes a paginator for PostgreSQL query results
* @param {PostgresAdapter} adapter - The PostgreSQL adapter
* @param {PostgreSQLQuery} query - The PostgreSQL query to paginate
* @param {number} size - The page size
* @param {Constructor<M>} clazz - The model constructor
*/
constructor(adapter, query, size, clazz) {
super(adapter, query, size, clazz);
}
/**
* @description Prepares a query for pagination
* @summary Modifies the raw query to include pagination parameters
* @param {PostgresQuery} rawStatement - The original PostgreSQL query
* @return {PostgresQuery} The prepared query with pagination parameters
*/
prepare(rawStatement) {
const query = { ...rawStatement };
return query;
}
/**
* @description Retrieves a specific page of results
* @summary Executes the query with pagination and processes the results
* @param {number} [page=1] - The page number to retrieve
* @return {Promise<R[]>} A promise that resolves to an array of results
* @throws {PagingError} If trying to access an invalid page or if no class is defined
* @mermaid
* sequenceDiagram
* participant Client
* participant PostgreSQLPaginator
* participant Adapter
* participant PostgreSQL
*
* Client->>PostgreSQLPaginator: page(pageNumber)
* Note over PostgreSQLPaginator: Clone statement
*
* alt First time or need count
* PostgreSQLPaginator->>Adapter: Get total count
* Adapter->>PostgreSQL: Execute COUNT query
* PostgreSQL-->>Adapter: Return count
* Adapter-->>PostgreSQLPaginator: Return count
* PostgreSQLPaginator->>PostgreSQLPaginator: Calculate total pages
* end
*
* PostgreSQLPaginator->>PostgreSQLPaginator: validatePage(page)
* PostgreSQLPaginator->>PostgreSQLPaginator: Calculate offset
* PostgreSQLPaginator->>PostgreSQLPaginator: Add limit and offset to query
*
* PostgreSQLPaginator->>Adapter: raw(statement, false)
* Adapter->>PostgreSQL: Execute query
* PostgreSQL-->>Adapter: Return results
* Adapter-->>PostgreSQLPaginator: Return PostgreSQLResponse
*
* Note over PostgreSQLPaginator: Process results
*
* PostgreSQLPaginator->>PostgreSQLPaginator: Check for clazz
*
* alt No clazz
* PostgreSQLPaginator-->>Client: Throw PagingError
* else Has clazz
* PostgreSQLPaginator->>PostgreSQLPaginator: Find primary key
*
* alt Has columns in statement
* PostgreSQLPaginator->>PostgreSQLPaginator: Use rows directly
* else No columns
* PostgreSQLPaginator->>PostgreSQLPaginator: Process each row
* loop For each row
* PostgreSQLPaginator->>Adapter: revert(row, clazz, pkDef.id, id)
* end
* end
*
* PostgreSQLPaginator->>PostgreSQLPaginator: Update currentPage
* PostgreSQLPaginator-->>Client: Return results
* end
*/
async page(page = 1) {
throw new Error(`Not implemented yet`);
// const statement = { ...this.statement };
//
// // Get total count if not already calculated
// if (!this._recordCount || !this._totalPages) {
// this._totalPages = this._recordCount = 0;
//
// // Create a count query based on the original query
// const countQuery: PostgresQuery = {
// ...statement,
// count: true,
// limit: undefined,
// offset: undefined,
// };
//
// const countResult: QueryResult = await this.adapter.raw(
// countQuery,
// false
// );
// this._recordCount = parseInt(countResult.rows[0]?.count || "0", 10);
//
// if (this._recordCount > 0) {
// const size = statement?.limit || this.size;
// this._totalPages = Math.ceil(this._recordCount / size);
// }
// }
//
// this.validatePage(page);
//
// // Calculate offset based on page number
// const offset = (page - 1) * this.size;
// statement.limit = this.size;
// statement.offset = offset;
//
// const result: PostgreSQLResponse<any> = await this.adapter.raw(
// statement,
// false
// );
//
// if (!this.clazz) throw new PagingError("No statement target defined");
//
// const pkDef = findPrimaryKey(new this.clazz());
// const rows = result.rows || [];
//
// const results =
// statement.columns && statement.columns.length
// ? rows // has columns means it's not full model
// : rows.map((row: any) => {
// return this.adapter.revert(
// row,
// this.clazz,
// pkDef.id,
// Sequence.parseValue(pkDef.props.type, row[PostgreSQLKeys.ID])
// );
// });
//
// this._currentPage = page;
// return results as R[];
}
}
exports.PostgresPaginator = PostgresPaginator;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFnaW5hdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3F1ZXJ5L1BhZ2luYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBMkM7QUFLM0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsaUJBQXNDLFNBQVEsZ0JBSTFEO0lBQ0M7Ozs7T0FJRztJQUNILElBQWEsS0FBSztRQUNoQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFhLEtBQUs7UUFDaEIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsWUFDRSxPQUF3QixFQUN4QixLQUFvQixFQUNwQixJQUFZLEVBQ1osS0FBcUI7UUFFckIsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLE9BQU8sQ0FBQyxZQUEyQjtRQUMzQyxNQUFNLEtBQUssR0FBa0IsRUFBRSxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQ2pELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzREc7SUFDSCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQWUsQ0FBQztRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDdkMsMkNBQTJDO1FBQzNDLEVBQUU7UUFDRiwrQ0FBK0M7UUFDL0MsaURBQWlEO1FBQ2pELDhDQUE4QztRQUM5QyxFQUFFO1FBQ0Ysd0RBQXdEO1FBQ3hELHdDQUF3QztRQUN4QyxvQkFBb0I7UUFDcEIsbUJBQW1CO1FBQ25CLHdCQUF3QjtRQUN4Qix5QkFBeUI7UUFDekIsT0FBTztRQUNQLEVBQUU7UUFDRiw2REFBNkQ7UUFDN0Qsa0JBQWtCO1FBQ2xCLFlBQVk7UUFDWixPQUFPO1FBQ1AseUVBQXlFO1FBQ3pFLEVBQUU7UUFDRixpQ0FBaUM7UUFDakMsa0RBQWtEO1FBQ2xELDhEQUE4RDtRQUM5RCxNQUFNO1FBQ04sSUFBSTtRQUNKLEVBQUU7UUFDRiwyQkFBMkI7UUFDM0IsRUFBRTtRQUNGLDJDQUEyQztRQUMzQyx5Q0FBeUM7UUFDekMsK0JBQStCO1FBQy9CLDZCQUE2QjtRQUM3QixFQUFFO1FBQ0Ysa0VBQWtFO1FBQ2xFLGVBQWU7UUFDZixVQUFVO1FBQ1YsS0FBSztRQUNMLEVBQUU7UUFDRix5RUFBeUU7UUFDekUsRUFBRTtRQUNGLGtEQUFrRDtRQUNsRCxrQ0FBa0M7UUFDbEMsRUFBRTtRQUNGLGtCQUFrQjtRQUNsQixrREFBa0Q7UUFDbEQsc0RBQXNEO1FBQ3RELGlDQUFpQztRQUNqQyxzQ0FBc0M7UUFDdEMsaUJBQWlCO1FBQ2pCLHdCQUF3QjtRQUN4QixzQkFBc0I7UUFDdEIsMEVBQTBFO1FBQzFFLGFBQWE7UUFDYixZQUFZO1FBQ1osRUFBRTtRQUNGLDRCQUE0QjtRQUM1Qix5QkFBeUI7SUFDM0IsQ0FBQztDQUNGO0FBdEtELDhDQXNLQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhZ2luYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgUG9zdGdyZXNRdWVyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUG9zdGdyZXNBZGFwdGVyIH0gZnJvbSBcIi4uL2FkYXB0ZXJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGFnaW5hdG9yIGZvciBQb3N0Z3JlU1FMIHF1ZXJ5IHJlc3VsdHNcbiAqIEBzdW1tYXJ5IEltcGxlbWVudHMgcGFnaW5hdGlvbiBmb3IgUG9zdGdyZVNRTCBxdWVyaWVzIHVzaW5nIExJTUlUIGFuZCBPRkZTRVQgZm9yIGVmZmljaWVudCBuYXZpZ2F0aW9uIHRocm91Z2ggcmVzdWx0IHNldHNcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXN1bHQgdHlwZVxuICogQHBhcmFtIHtQb3N0Z3Jlc0FkYXB0ZXI8YW55LCBhbnksIGFueT59IGFkYXB0ZXIgLSBUaGUgUG9zdGdyZVNRTCBhZGFwdGVyXG4gKiBAcGFyYW0ge1Bvc3RncmVzUXVlcnl9IHF1ZXJ5IC0gVGhlIFBvc3RncmVzU1FMIHF1ZXJ5IHRvIHBhZ2luYXRlXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBwYWdlIHNpemVcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IGNsYXp6IC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9yXG4gKiBAY2xhc3MgUG9zdGdyZXNQYWdpbmF0b3JcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIG9mIHVzaW5nIFBvc3RncmVTUUxQYWdpbmF0b3JcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgTXlQb3N0Z3JlU1FMQWRhcHRlcihwb29sKTtcbiAqIGNvbnN0IHF1ZXJ5ID0geyB0YWJsZTogXCJ1c2Vyc1wiIH07XG4gKiBjb25zdCBwYWdpbmF0b3IgPSBuZXcgUG9zdGdyZVNRTFBhZ2luYXRvcihhZGFwdGVyLCBxdWVyeSwgMTAsIFVzZXIpO1xuICpcbiAqIC8vIEdldCB0aGUgZmlyc3QgcGFnZVxuICogY29uc3QgcGFnZTEgPSBhd2FpdCBwYWdpbmF0b3IucGFnZSgxKTtcbiAqXG4gKiAvLyBHZXQgdGhlIG5leHQgcGFnZVxuICogY29uc3QgcGFnZTIgPSBhd2FpdCBwYWdpbmF0b3IucGFnZSgyKTtcbiAqL1xuZXhwb3J0IGNsYXNzIFBvc3RncmVzUGFnaW5hdG9yPE0gZXh0ZW5kcyBNb2RlbCwgUj4gZXh0ZW5kcyBQYWdpbmF0b3I8XG4gIE0sXG4gIFIsXG4gIFBvc3RncmVzUXVlcnlcbj4ge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiBwYWdlc1xuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgcGFnZXMgYmFzZWQgb24gdGhlIHJlY29yZCBjb3VudCBhbmQgcGFnZSBzaXplXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIHRvdGFsIG51bWJlciBvZiBwYWdlc1xuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0IHRvdGFsKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3RvdGFsUGFnZXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHRvdGFsIHJlY29yZCBjb3VudFxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgcmVjb3JkcyBtYXRjaGluZyB0aGUgcXVlcnlcbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgdG90YWwgcmVjb3JkIGNvdW50XG4gICAqL1xuICBvdmVycmlkZSBnZXQgY291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcmVjb3JkQ291bnQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgUG9zdGdyZVNRTFBhZ2luYXRvciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBJbml0aWFsaXplcyBhIHBhZ2luYXRvciBmb3IgUG9zdGdyZVNRTCBxdWVyeSByZXN1bHRzXG4gICAqIEBwYXJhbSB7UG9zdGdyZXNBZGFwdGVyfSBhZGFwdGVyIC0gVGhlIFBvc3RncmVTUUwgYWRhcHRlclxuICAgKiBAcGFyYW0ge1Bvc3RncmVTUUxRdWVyeX0gcXVlcnkgLSBUaGUgUG9zdGdyZVNRTCBxdWVyeSB0byBwYWdpbmF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBwYWdlIHNpemVcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gY2xhenogLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIGFkYXB0ZXI6IFBvc3RncmVzQWRhcHRlcixcbiAgICBxdWVyeTogUG9zdGdyZXNRdWVyeSxcbiAgICBzaXplOiBudW1iZXIsXG4gICAgY2xheno6IENvbnN0cnVjdG9yPE0+XG4gICkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIHF1ZXJ5LCBzaXplLCBjbGF6eik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGEgcXVlcnkgZm9yIHBhZ2luYXRpb25cbiAgICogQHN1bW1hcnkgTW9kaWZpZXMgdGhlIHJhdyBxdWVyeSB0byBpbmNsdWRlIHBhZ2luYXRpb24gcGFyYW1ldGVyc1xuICAgKiBAcGFyYW0ge1Bvc3RncmVzUXVlcnl9IHJhd1N0YXRlbWVudCAtIFRoZSBvcmlnaW5hbCBQb3N0Z3JlU1FMIHF1ZXJ5XG4gICAqIEByZXR1cm4ge1Bvc3RncmVzUXVlcnl9IFRoZSBwcmVwYXJlZCBxdWVyeSB3aXRoIHBhZ2luYXRpb24gcGFyYW1ldGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIHByZXBhcmUocmF3U3RhdGVtZW50OiBQb3N0Z3Jlc1F1ZXJ5KTogUG9zdGdyZXNRdWVyeSB7XG4gICAgY29uc3QgcXVlcnk6IFBvc3RncmVzUXVlcnkgPSB7IC4uLnJhd1N0YXRlbWVudCB9O1xuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgc3BlY2lmaWMgcGFnZSBvZiByZXN1bHRzXG4gICAqIEBzdW1tYXJ5IEV4ZWN1dGVzIHRoZSBxdWVyeSB3aXRoIHBhZ2luYXRpb24gYW5kIHByb2Nlc3NlcyB0aGUgcmVzdWx0c1xuICAgKiBAcGFyYW0ge251bWJlcn0gW3BhZ2U9MV0gLSBUaGUgcGFnZSBudW1iZXIgdG8gcmV0cmlldmVcbiAgICogQHJldHVybiB7UHJvbWlzZTxSW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByZXN1bHRzXG4gICAqIEB0aHJvd3Mge1BhZ2luZ0Vycm9yfSBJZiB0cnlpbmcgdG8gYWNjZXNzIGFuIGludmFsaWQgcGFnZSBvciBpZiBubyBjbGFzcyBpcyBkZWZpbmVkXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvc3RncmVTUUxQYWdpbmF0b3JcbiAgICogICBwYXJ0aWNpcGFudCBBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG9zdGdyZVNRTFxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvc3RncmVTUUxQYWdpbmF0b3I6IHBhZ2UocGFnZU51bWJlcilcbiAgICogICBOb3RlIG92ZXIgUG9zdGdyZVNRTFBhZ2luYXRvcjogQ2xvbmUgc3RhdGVtZW50XG4gICAqXG4gICAqICAgYWx0IEZpcnN0IHRpbWUgb3IgbmVlZCBjb3VudFxuICAgKiAgICAgUG9zdGdyZVNRTFBhZ2luYXRvci0+PkFkYXB0ZXI6IEdldCB0b3RhbCBjb3VudFxuICAgKiAgICAgQWRhcHRlci0+PlBvc3RncmVTUUw6IEV4ZWN1dGUgQ09VTlQgcXVlcnlcbiAgICogICAgIFBvc3RncmVTUUwtLT4+QWRhcHRlcjogUmV0dXJuIGNvdW50XG4gICAqICAgICBBZGFwdGVyLS0+PlBvc3RncmVTUUxQYWdpbmF0b3I6IFJldHVybiBjb3VudFxuICAgKiAgICAgUG9zdGdyZVNRTFBhZ2luYXRvci0+PlBvc3RncmVTUUxQYWdpbmF0b3I6IENhbGN1bGF0ZSB0b3RhbCBwYWdlc1xuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5Qb3N0Z3JlU1FMUGFnaW5hdG9yOiB2YWxpZGF0ZVBhZ2UocGFnZSlcbiAgICogICBQb3N0Z3JlU1FMUGFnaW5hdG9yLT4+UG9zdGdyZVNRTFBhZ2luYXRvcjogQ2FsY3VsYXRlIG9mZnNldFxuICAgKiAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5Qb3N0Z3JlU1FMUGFnaW5hdG9yOiBBZGQgbGltaXQgYW5kIG9mZnNldCB0byBxdWVyeVxuICAgKlxuICAgKiAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5BZGFwdGVyOiByYXcoc3RhdGVtZW50LCBmYWxzZSlcbiAgICogICBBZGFwdGVyLT4+UG9zdGdyZVNRTDogRXhlY3V0ZSBxdWVyeVxuICAgKiAgIFBvc3RncmVTUUwtLT4+QWRhcHRlcjogUmV0dXJuIHJlc3VsdHNcbiAgICogICBBZGFwdGVyLS0+PlBvc3RncmVTUUxQYWdpbmF0b3I6IFJldHVybiBQb3N0Z3JlU1FMUmVzcG9uc2VcbiAgICpcbiAgICogICBOb3RlIG92ZXIgUG9zdGdyZVNRTFBhZ2luYXRvcjogUHJvY2VzcyByZXN1bHRzXG4gICAqXG4gICAqICAgUG9zdGdyZVNRTFBhZ2luYXRvci0+PlBvc3RncmVTUUxQYWdpbmF0b3I6IENoZWNrIGZvciBjbGF6elxuICAgKlxuICAgKiAgIGFsdCBObyBjbGF6elxuICAgKiAgICAgUG9zdGdyZVNRTFBhZ2luYXRvci0tPj5DbGllbnQ6IFRocm93IFBhZ2luZ0Vycm9yXG4gICAqICAgZWxzZSBIYXMgY2xhenpcbiAgICogICAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5Qb3N0Z3JlU1FMUGFnaW5hdG9yOiBGaW5kIHByaW1hcnkga2V5XG4gICAqXG4gICAqICAgICBhbHQgSGFzIGNvbHVtbnMgaW4gc3RhdGVtZW50XG4gICAqICAgICAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5Qb3N0Z3JlU1FMUGFnaW5hdG9yOiBVc2Ugcm93cyBkaXJlY3RseVxuICAgKiAgICAgZWxzZSBObyBjb2x1bW5zXG4gICAqICAgICAgIFBvc3RncmVTUUxQYWdpbmF0b3ItPj5Qb3N0Z3JlU1FMUGFnaW5hdG9yOiBQcm9jZXNzIGVhY2ggcm93XG4gICAqICAgICAgIGxvb3AgRm9yIGVhY2ggcm93XG4gICAqICAgICAgICAgUG9zdGdyZVNRTFBhZ2luYXRvci0+PkFkYXB0ZXI6IHJldmVydChyb3csIGNsYXp6LCBwa0RlZi5pZCwgaWQpXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZW5kXG4gICAqXG4gICAqICAgICBQb3N0Z3JlU1FMUGFnaW5hdG9yLT4+UG9zdGdyZVNRTFBhZ2luYXRvcjogVXBkYXRlIGN1cnJlbnRQYWdlXG4gICAqICAgICBQb3N0Z3JlU1FMUGFnaW5hdG9yLS0+PkNsaWVudDogUmV0dXJuIHJlc3VsdHNcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIHBhZ2UocGFnZTogbnVtYmVyID0gMSk6IFByb21pc2U8UltdPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBOb3QgaW1wbGVtZW50ZWQgeWV0YCk7XG4gICAgLy8gY29uc3Qgc3RhdGVtZW50ID0geyAuLi50aGlzLnN0YXRlbWVudCB9O1xuICAgIC8vXG4gICAgLy8gLy8gR2V0IHRvdGFsIGNvdW50IGlmIG5vdCBhbHJlYWR5IGNhbGN1bGF0ZWRcbiAgICAvLyBpZiAoIXRoaXMuX3JlY29yZENvdW50IHx8ICF0aGlzLl90b3RhbFBhZ2VzKSB7XG4gICAgLy8gICB0aGlzLl90b3RhbFBhZ2VzID0gdGhpcy5fcmVjb3JkQ291bnQgPSAwO1xuICAgIC8vXG4gICAgLy8gICAvLyBDcmVhdGUgYSBjb3VudCBxdWVyeSBiYXNlZCBvbiB0aGUgb3JpZ2luYWwgcXVlcnlcbiAgICAvLyAgIGNvbnN0IGNvdW50UXVlcnk6IFBvc3RncmVzUXVlcnkgPSB7XG4gICAgLy8gICAgIC4uLnN0YXRlbWVudCxcbiAgICAvLyAgICAgY291bnQ6IHRydWUsXG4gICAgLy8gICAgIGxpbWl0OiB1bmRlZmluZWQsXG4gICAgLy8gICAgIG9mZnNldDogdW5kZWZpbmVkLFxuICAgIC8vICAgfTtcbiAgICAvL1xuICAgIC8vICAgY29uc3QgY291bnRSZXN1bHQ6IFF1ZXJ5UmVzdWx0ID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJhdyhcbiAgICAvLyAgICAgY291bnRRdWVyeSxcbiAgICAvLyAgICAgZmFsc2VcbiAgICAvLyAgICk7XG4gICAgLy8gICB0aGlzLl9yZWNvcmRDb3VudCA9IHBhcnNlSW50KGNvdW50UmVzdWx0LnJvd3NbMF0/LmNvdW50IHx8IFwiMFwiLCAxMCk7XG4gICAgLy9cbiAgICAvLyAgIGlmICh0aGlzLl9yZWNvcmRDb3VudCA+IDApIHtcbiAgICAvLyAgICAgY29uc3Qgc2l6ZSA9IHN0YXRlbWVudD8ubGltaXQgfHwgdGhpcy5zaXplO1xuICAgIC8vICAgICB0aGlzLl90b3RhbFBhZ2VzID0gTWF0aC5jZWlsKHRoaXMuX3JlY29yZENvdW50IC8gc2l6ZSk7XG4gICAgLy8gICB9XG4gICAgLy8gfVxuICAgIC8vXG4gICAgLy8gdGhpcy52YWxpZGF0ZVBhZ2UocGFnZSk7XG4gICAgLy9cbiAgICAvLyAvLyBDYWxjdWxhdGUgb2Zmc2V0IGJhc2VkIG9uIHBhZ2UgbnVtYmVyXG4gICAgLy8gY29uc3Qgb2Zmc2V0ID0gKHBhZ2UgLSAxKSAqIHRoaXMuc2l6ZTtcbiAgICAvLyBzdGF0ZW1lbnQubGltaXQgPSB0aGlzLnNpemU7XG4gICAgLy8gc3RhdGVtZW50Lm9mZnNldCA9IG9mZnNldDtcbiAgICAvL1xuICAgIC8vIGNvbnN0IHJlc3VsdDogUG9zdGdyZVNRTFJlc3BvbnNlPGFueT4gPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmF3KFxuICAgIC8vICAgc3RhdGVtZW50LFxuICAgIC8vICAgZmFsc2VcbiAgICAvLyApO1xuICAgIC8vXG4gICAgLy8gaWYgKCF0aGlzLmNsYXp6KSB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXCJObyBzdGF0ZW1lbnQgdGFyZ2V0IGRlZmluZWRcIik7XG4gICAgLy9cbiAgICAvLyBjb25zdCBwa0RlZiA9IGZpbmRQcmltYXJ5S2V5KG5ldyB0aGlzLmNsYXp6KCkpO1xuICAgIC8vIGNvbnN0IHJvd3MgPSByZXN1bHQucm93cyB8fCBbXTtcbiAgICAvL1xuICAgIC8vIGNvbnN0IHJlc3VsdHMgPVxuICAgIC8vICAgc3RhdGVtZW50LmNvbHVtbnMgJiYgc3RhdGVtZW50LmNvbHVtbnMubGVuZ3RoXG4gICAgLy8gICAgID8gcm93cyAvLyBoYXMgY29sdW1ucyBtZWFucyBpdCdzIG5vdCBmdWxsIG1vZGVsXG4gICAgLy8gICAgIDogcm93cy5tYXAoKHJvdzogYW55KSA9PiB7XG4gICAgLy8gICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAvLyAgICAgICAgICAgcm93LFxuICAgIC8vICAgICAgICAgICB0aGlzLmNsYXp6LFxuICAgIC8vICAgICAgICAgICBwa0RlZi5pZCxcbiAgICAvLyAgICAgICAgICAgU2VxdWVuY2UucGFyc2VWYWx1ZShwa0RlZi5wcm9wcy50eXBlLCByb3dbUG9zdGdyZVNRTEtleXMuSURdKVxuICAgIC8vICAgICAgICAgKTtcbiAgICAvLyAgICAgICB9KTtcbiAgICAvL1xuICAgIC8vIHRoaXMuX2N1cnJlbnRQYWdlID0gcGFnZTtcbiAgICAvLyByZXR1cm4gcmVzdWx0cyBhcyBSW107XG4gIH1cbn1cbiJdfQ==