import { Buffer } from "buffer";
import { Address } from '@stellar/stellar-sdk';
import {
  AssembledTransaction,
  AssembledTransactionOptions,
  Client as ContractClient,
  ClientOptions as ContractClientOptions,
  MethodOptions,
  Result,
  Spec as ContractSpec,
} from '@stellar/stellar-sdk/contract';
import type {
  u32,
  i32,
  u64,
  i64,
  u128,
  i128,
  u256,
  i256,
  Option,
  Typepoint,
  Duration,
} from '@stellar/stellar-sdk/contract';
export * from '@stellar/stellar-sdk'
export * as contract from '@stellar/stellar-sdk/contract'
export * as rpc from '@stellar/stellar-sdk/rpc'

/**
 * Embedded WASM bytecode (base64-encoded)
 * Size: 24101 bytes (23.54 KB)
 */
export const WASM_BASE64 = " ";

/**
 * Pre-computed WASM hash (SHA-256)
 * Use this when the WASM is already uploaded on-chain
 */
export const WASM_HASH = "bf9358ac2e188d74a695cd6009929735f90e8c891f922a9de5fcdc7037af255e";

/**
 * Get the WASM bytecode as a Buffer
 * Use this to upload the WASM to the network
 */
export function getWasmBuffer(): Buffer {
  return Buffer.from(WASM_BASE64, 'base64');
}

export type SACManagerStorage = {tag: "SacToken", values: void};

/**
 * BufferReaderError: 1000-1009
 */
export const BufferReaderError = {
  1000: {message:"InvalidLength"},
  1001: {message:"InvalidAddressPayload"}
}

/**
 * BufferWriterError: 1010-1019
 */
export const BufferWriterError = {
  1010: {message:"InvalidAddressPayload"}
}

/**
 * TtlConfigurableError: 1020-1029
 */
export const TtlConfigurableError = {
  1020: {message:"InvalidTtlConfig"},
  1021: {message:"TtlConfigFrozen"},
  1022: {message:"TtlConfigAlreadyFrozen"}
}

/**
 * OwnableError: 1030-1039
 */
export const OwnableError = {
  1030: {message:"InvalidAuthorizer"},
  1031: {message:"InvalidPendingOwner"},
  1032: {message:"InvalidTtl"},
  1033: {message:"NoPendingTransfer"},
  1034: {message:"OwnerAlreadySet"},
  1035: {message:"OwnerNotSet"},
  1036: {message:"TransferInProgress"}
}

/**
 * BytesExtError: 1040-1049
 */
export const BytesExtError = {
  1040: {message:"LengthMismatch"}
}

/**
 * UpgradeableError: 1050-1059
 */
export const UpgradeableError = {
  1050: {message:"InvalidMigrationData"},
  1051: {message:"MigrationNotAllowed"}
}

/**
 * MultiSigError: 1060-1069
 */
export const MultiSigError = {
  1060: {message:"AlreadyInitialized"},
  1061: {message:"InvalidAuthorizer"},
  1062: {message:"InvalidSigner"},
  1063: {message:"SignatureError"},
  1064: {message:"SignerAlreadyExists"},
  1065: {message:"SignerNotFound"},
  1066: {message:"TotalSignersLessThanThreshold"},
  1067: {message:"UnsortedSigners"},
  1068: {message:"ZeroThreshold"}
}

/**
 * AuthError: 1070-1079
 */
export const AuthError = {
  1070: {message:"AuthorizerNotFound"}
}

/**
 * RbacError: 1080-1089
 */
export const RbacError = {
  1080: {message:"AdminRoleNotFound"},
  1081: {message:"IndexOutOfBounds"},
  1082: {message:"MaxRolesExceeded"},
  1083: {message:"RoleIsEmpty"},
  1084: {message:"RoleNotFound"},
  1085: {message:"RoleNotHeld"},
  1086: {message:"Unauthorized"}
}



export type MultiSigStorage = {tag: "Signers", values: void} | {tag: "Threshold", values: void};





export type OwnableStorage = {tag: "Owner", values: void} | {tag: "PendingOwner", values: void};




export type RbacStorage = {tag: "ExistingRoles", values: void} | {tag: "RoleIndexToAccount", values: readonly [string, u32]} | {tag: "RoleAccountToIndex", values: readonly [string, string]} | {tag: "RoleAccountsCount", values: readonly [string]} | {tag: "RoleAdmin", values: readonly [string]};


/**
 * TTL configuration: threshold (when to extend) and extend_to (target TTL).
 */
export interface TtlConfig {
  /**
 * Target TTL after extension (in ledgers).
 */
extend_to: u32;
  /**
 * TTL threshold that triggers extension (in ledgers).
 */
threshold: u32;
}



export type TtlConfigStorage = {tag: "Frozen", values: void} | {tag: "Instance", values: void} | {tag: "Persistent", values: void};

export type UpgradeableStorage = {tag: "Migrating", values: void};

export interface Client {
  /**
   * Construct and simulate a grant_role transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Grants a role to an account. Caller must be owner or have the role's admin role.
   * 
   * # Arguments
   * * `account` - The account to grant the role to.
   * * `role` - The role to grant.
   * * `caller` - The account that is granting the role. Must be owner or have the role's admin role.
   */
  grant_role: ({account, role, caller}: {account: string, role: string, caller: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a revoke_role transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Revokes a role from an account. Caller must be owner or have the role's admin role.
   * 
   * # Arguments
   * * `account` - The account to revoke the role from.
   * * `role` - The role to revoke.
   * * `caller` - The account that is revoking the role. Must be owner or have the role's admin role.
   */
  revoke_role: ({account, role, caller}: {account: string, role: string, caller: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a renounce_role transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Allows an account to renounce a role assigned to itself.
   * Users can only renounce roles for their own account.
   * 
   * # Arguments
   * * `role` - The role to renounce.
   * * `caller` - The account that is renouncing the role. Must be the account itself.
   */
  renounce_role: ({role, caller}: {role: string, caller: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a set_role_admin transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Sets `admin_role` as the admin role of `role`. Caller must be the authorizer.
   * 
   * # Arguments
   * * `role` - The role to set the admin for.
   * * `admin_role` - The admin role to set for the role.
   * 
   * # Notes
   * 
   * The admin role can be any `Symbol`, including one with no members. If the admin
   * role has no members, only the authorizer can grant/revoke the role.
   */
  set_role_admin: ({role, admin_role}: {role: string, admin_role: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a remove_role_admin transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Removes the admin role for a specified role. Caller must be the authorizer.
   * 
   * # Arguments
   * * `role` - The role to remove the admin for.
   * 
   * # Errors
   * * `RbacError::AdminRoleNotFound` - If no admin role is set for the role.
   */
  remove_role_admin: ({role}: {role: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a has_role transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns `Some(index)` if the account has the specified role, where `index`
   * is the index of the account in the role. Returns `None` if not.
   * 
   * # Arguments
   * * `account` - The account to check the role for.
   * * `role` - The role to check the account for.
   */
  has_role: ({account, role}: {account: string, role: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<Option<u32>>>

  /**
   * Construct and simulate a get_role_admin transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the admin role for a specific role, or None if not set.
   * 
   * # Arguments
   * * `role` - The role to get the admin for.
   */
  get_role_admin: ({role}: {role: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<Option<string>>>

  /**
   * Construct and simulate a get_role_member_count transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the number of accounts that have the specified role.
   * 
   * # Arguments
   * * `role` - The role to get the member count for.
   */
  get_role_member_count: ({role}: {role: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<u32>>

  /**
   * Construct and simulate a get_role_member transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the account at the specified index for a given role.
   * 
   * # Arguments
   * * `role` - The role to get the member for.
   * * `index` - The index of the member to get.
   * 
   * # Errors
   * * `RbacError::IndexOutOfBounds` if the index is out of bounds.
   */
  get_role_member: ({role, index}: {role: string, index: u32}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<string>>

  /**
   * Construct and simulate a get_existing_roles transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns all roles that currently have at least one member.
   * Defaults to empty vector if no roles exist.
   * 
   * # Notes
   * 
   * This function returns all roles that currently have at least one member.
   * The maximum number of roles is limited by [`MAX_ROLES`].
   */
  get_existing_roles: (options?: MethodOptions) => Promise<AssembledTransaction<Array<string>>>

  /**
   * Construct and simulate a set_admin transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   */
  set_admin: ({new_admin, operator}: {new_admin: string, operator: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a set_authorized transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   */
  set_authorized: ({id, authorize, operator}: {id: string, authorize: boolean, operator: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a clawback transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   */
  clawback: ({from, amount, operator}: {from: string, amount: i128, operator: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a mint transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   */
  mint: ({to, amount, operator}: {to: string, amount: i128, operator: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a underlying_sac transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the underlying SAC (Stellar Asset Contract) address.
   */
  underlying_sac: (options?: MethodOptions) => Promise<AssembledTransaction<string>>

  /**
   * Construct and simulate a authorizer transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   */
  authorizer: (options?: MethodOptions) => Promise<AssembledTransaction<Option<string>>>

  /**
   * Construct and simulate a owner transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the current owner address, or None if no owner is set.
   */
  owner: (options?: MethodOptions) => Promise<AssembledTransaction<Option<string>>>

  /**
   * Construct and simulate a pending_owner transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the pending owner address for 2-step transfer, or None if no transfer is pending.
   */
  pending_owner: (options?: MethodOptions) => Promise<AssembledTransaction<Option<string>>>

  /**
   * Construct and simulate a transfer_ownership transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Transfers ownership immediately to a new address.
   * 
   * Use with caution - if you transfer to a wrong address, ownership is lost forever.
   * Consider using `begin_ownership_transfer` instead.
   * 
   * # Panics
   * - `OwnerNotSet` if no owner is currently set
   * - `TransferInProgress` if a 2-step transfer is in progress
   */
  transfer_ownership: ({new_owner}: {new_owner: string}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a begin_ownership_transfer transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Begins an ownership transfer to a new address.
   * 
   * The new owner must call `accept_ownership()` within `ttl` ledgers
   * to complete the transfer. The pending transfer will automatically expire after.
   * 
   * # Arguments
   * - `new_owner` - The proposed new owner
   * - `ttl` - Number of ledgers the new owner has to accept.
   * Use `0` to cancel a pending transfer (new_owner must match pending).
   * 
   * # Panics
   * - `OwnerNotSet` if no owner is currently set
   * - `NoPendingTransfer` when cancelling and no pending transfer exists
   * - `InvalidTtl` if ttl exceeds max TTL
   * - `InvalidPendingOwner` when cancelling with wrong new_owner address
   */
  begin_ownership_transfer: ({new_owner, ttl}: {new_owner: string, ttl: u32}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a accept_ownership transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Accepts a pending 2-step ownership transfer.
   * 
   * Must be called by the pending owner before the TTL expires.
   * 
   * # Panics
   * - `NoPendingTransfer` if there is no pending transfer (or it expired)
   */
  accept_ownership: (options?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a renounce_ownership transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Permanently renounces ownership.
   * 
   * # Panics
   * - `OwnerNotSet` if no owner is currently set
   * - `TransferInProgress` if a 2-step transfer is in progress (cancel it first)
   */
  renounce_ownership: (options?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a extend_instance_ttl transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Extends the instance TTL.
   * 
   * # Arguments
   * 
   * * `threshold` - The threshold to extend the TTL (if current TTL is below this, extend).
   * * `extend_to` - The TTL to extend to.
   */
  extend_instance_ttl: ({threshold, extend_to}: {threshold: u32, extend_to: u32}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a set_ttl_configs transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Sets TTL configs for instance and persistent storage.
   * 
   * - `None` values remove the corresponding config (disables auto-extension for that type)
   * - Validates that `threshold <= extend_to <= MAX_TTL`
   * 
   * # Arguments
   * - `instance` - TTL config for instance storage
   * - `persistent` - TTL config for persistent storage
   * 
   * # Panics
   * - `TtlConfigFrozen` if configs are frozen
   * - `InvalidTtlConfig` if validation fails
   */
  set_ttl_configs: ({instance, persistent}: {instance: Option<TtlConfig>, persistent: Option<TtlConfig>}, txnOptions?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a ttl_configs transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns the current TTL configs as (instance_config, persistent_config).
   */
  ttl_configs: (options?: MethodOptions) => Promise<AssembledTransaction<readonly [Option<TtlConfig>, Option<TtlConfig>]>>

  /**
   * Construct and simulate a freeze_ttl_configs transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Permanently freezes TTL configs, preventing any future modifications.
   * 
   * This is irreversible and provides immutability guarantees to users.
   * Emits `TtlConfigsFrozen` event.
   * 
   * # Panics
   * - `TtlConfigAlreadyFrozen` if already frozen
   */
  freeze_ttl_configs: (options?: MethodOptions) => Promise<AssembledTransaction<null>>

  /**
   * Construct and simulate a is_ttl_configs_frozen transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object.
   * Returns whether TTL configs are frozen.
   */
  is_ttl_configs_frozen: (options?: MethodOptions) => Promise<AssembledTransaction<boolean>>

}
export class Client extends ContractClient {
  static async deploy<T = Client>(
        /** Constructor/Initialization Args for the contract's `__constructor` method */
        {sac_token, owner}: {sac_token: string, owner: string},
    /** Options for initializing a Client as well as for calling a method, with extras specific to deploying. */
    options: MethodOptions &
      Omit<ContractClientOptions, "contractId"> & {
        /** The hash of the Wasm blob, which must already be installed on-chain. */
        wasmHash: Buffer | string;
        /** Salt used to generate the contract's ID. Passed through to {@link Operation.createCustomContract}. Default: random. */
        salt?: Buffer | Uint8Array;
        /** The format used to decode `wasmHash`, if it's provided as a string. */
        format?: "hex" | "base64";
      }
  ): Promise<AssembledTransaction<T>> {
    return ContractClient.deploy({sac_token, owner}, options)
  }
  constructor(public readonly options: ContractClientOptions) {
    super(
      new ContractSpec([ "AAAAAAAAAQxHcmFudHMgYSByb2xlIHRvIGFuIGFjY291bnQuIENhbGxlciBtdXN0IGJlIG93bmVyIG9yIGhhdmUgdGhlIHJvbGUncyBhZG1pbiByb2xlLgoKIyBBcmd1bWVudHMKKiBgYWNjb3VudGAgLSBUaGUgYWNjb3VudCB0byBncmFudCB0aGUgcm9sZSB0by4KKiBgcm9sZWAgLSBUaGUgcm9sZSB0byBncmFudC4KKiBgY2FsbGVyYCAtIFRoZSBhY2NvdW50IHRoYXQgaXMgZ3JhbnRpbmcgdGhlIHJvbGUuIE11c3QgYmUgb3duZXIgb3IgaGF2ZSB0aGUgcm9sZSdzIGFkbWluIHJvbGUuAAAACmdyYW50X3JvbGUAAAAAAAMAAAAAAAAAB2FjY291bnQAAAAAEwAAAAAAAAAEcm9sZQAAABEAAAAAAAAABmNhbGxlcgAAAAAAEwAAAAA=",
        "AAAAAAAAARNSZXZva2VzIGEgcm9sZSBmcm9tIGFuIGFjY291bnQuIENhbGxlciBtdXN0IGJlIG93bmVyIG9yIGhhdmUgdGhlIHJvbGUncyBhZG1pbiByb2xlLgoKIyBBcmd1bWVudHMKKiBgYWNjb3VudGAgLSBUaGUgYWNjb3VudCB0byByZXZva2UgdGhlIHJvbGUgZnJvbS4KKiBgcm9sZWAgLSBUaGUgcm9sZSB0byByZXZva2UuCiogYGNhbGxlcmAgLSBUaGUgYWNjb3VudCB0aGF0IGlzIHJldm9raW5nIHRoZSByb2xlLiBNdXN0IGJlIG93bmVyIG9yIGhhdmUgdGhlIHJvbGUncyBhZG1pbiByb2xlLgAAAAALcmV2b2tlX3JvbGUAAAAAAwAAAAAAAAAHYWNjb3VudAAAAAATAAAAAAAAAARyb2xlAAAAEQAAAAAAAAAGY2FsbGVyAAAAAAATAAAAAA==",
        "AAAAAAAAAO1BbGxvd3MgYW4gYWNjb3VudCB0byByZW5vdW5jZSBhIHJvbGUgYXNzaWduZWQgdG8gaXRzZWxmLgpVc2VycyBjYW4gb25seSByZW5vdW5jZSByb2xlcyBmb3IgdGhlaXIgb3duIGFjY291bnQuCgojIEFyZ3VtZW50cwoqIGByb2xlYCAtIFRoZSByb2xlIHRvIHJlbm91bmNlLgoqIGBjYWxsZXJgIC0gVGhlIGFjY291bnQgdGhhdCBpcyByZW5vdW5jaW5nIHRoZSByb2xlLiBNdXN0IGJlIHRoZSBhY2NvdW50IGl0c2VsZi4AAAAAAAANcmVub3VuY2Vfcm9sZQAAAAAAAAIAAAAAAAAABHJvbGUAAAARAAAAAAAAAAZjYWxsZXIAAAAAABMAAAAA",
        "AAAAAAAAAVdTZXRzIGBhZG1pbl9yb2xlYCBhcyB0aGUgYWRtaW4gcm9sZSBvZiBgcm9sZWAuIENhbGxlciBtdXN0IGJlIHRoZSBhdXRob3JpemVyLgoKIyBBcmd1bWVudHMKKiBgcm9sZWAgLSBUaGUgcm9sZSB0byBzZXQgdGhlIGFkbWluIGZvci4KKiBgYWRtaW5fcm9sZWAgLSBUaGUgYWRtaW4gcm9sZSB0byBzZXQgZm9yIHRoZSByb2xlLgoKIyBOb3RlcwoKVGhlIGFkbWluIHJvbGUgY2FuIGJlIGFueSBgU3ltYm9sYCwgaW5jbHVkaW5nIG9uZSB3aXRoIG5vIG1lbWJlcnMuIElmIHRoZSBhZG1pbgpyb2xlIGhhcyBubyBtZW1iZXJzLCBvbmx5IHRoZSBhdXRob3JpemVyIGNhbiBncmFudC9yZXZva2UgdGhlIHJvbGUuAAAAAA5zZXRfcm9sZV9hZG1pbgAAAAAAAgAAAAAAAAAEcm9sZQAAABEAAAAAAAAACmFkbWluX3JvbGUAAAAAABEAAAAA",
        "AAAAAAAAANhSZW1vdmVzIHRoZSBhZG1pbiByb2xlIGZvciBhIHNwZWNpZmllZCByb2xlLiBDYWxsZXIgbXVzdCBiZSB0aGUgYXV0aG9yaXplci4KCiMgQXJndW1lbnRzCiogYHJvbGVgIC0gVGhlIHJvbGUgdG8gcmVtb3ZlIHRoZSBhZG1pbiBmb3IuCgojIEVycm9ycwoqIGBSYmFjRXJyb3I6OkFkbWluUm9sZU5vdEZvdW5kYCAtIElmIG5vIGFkbWluIHJvbGUgaXMgc2V0IGZvciB0aGUgcm9sZS4AAAARcmVtb3ZlX3JvbGVfYWRtaW4AAAAAAAABAAAAAAAAAARyb2xlAAAAEQAAAAA=",
        "AAAAAAAAAPZSZXR1cm5zIGBTb21lKGluZGV4KWAgaWYgdGhlIGFjY291bnQgaGFzIHRoZSBzcGVjaWZpZWQgcm9sZSwgd2hlcmUgYGluZGV4YAppcyB0aGUgaW5kZXggb2YgdGhlIGFjY291bnQgaW4gdGhlIHJvbGUuIFJldHVybnMgYE5vbmVgIGlmIG5vdC4KCiMgQXJndW1lbnRzCiogYGFjY291bnRgIC0gVGhlIGFjY291bnQgdG8gY2hlY2sgdGhlIHJvbGUgZm9yLgoqIGByb2xlYCAtIFRoZSByb2xlIHRvIGNoZWNrIHRoZSBhY2NvdW50IGZvci4AAAAAAAhoYXNfcm9sZQAAAAIAAAAAAAAAB2FjY291bnQAAAAAEwAAAAAAAAAEcm9sZQAAABEAAAABAAAD6AAAAAQ=",
        "AAAAAAAAAHZSZXR1cm5zIHRoZSBhZG1pbiByb2xlIGZvciBhIHNwZWNpZmljIHJvbGUsIG9yIE5vbmUgaWYgbm90IHNldC4KCiMgQXJndW1lbnRzCiogYHJvbGVgIC0gVGhlIHJvbGUgdG8gZ2V0IHRoZSBhZG1pbiBmb3IuAAAAAAAOZ2V0X3JvbGVfYWRtaW4AAAAAAAEAAAAAAAAABHJvbGUAAAARAAAAAQAAA+gAAAAR",
        "AAAAAAAAAHpSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWNjb3VudHMgdGhhdCBoYXZlIHRoZSBzcGVjaWZpZWQgcm9sZS4KCiMgQXJndW1lbnRzCiogYHJvbGVgIC0gVGhlIHJvbGUgdG8gZ2V0IHRoZSBtZW1iZXIgY291bnQgZm9yLgAAAAAAFWdldF9yb2xlX21lbWJlcl9jb3VudAAAAAAAAAEAAAAAAAAABHJvbGUAAAARAAAAAQAAAAQ=",
        "AAAAAAAAAOlSZXR1cm5zIHRoZSBhY2NvdW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggZm9yIGEgZ2l2ZW4gcm9sZS4KCiMgQXJndW1lbnRzCiogYHJvbGVgIC0gVGhlIHJvbGUgdG8gZ2V0IHRoZSBtZW1iZXIgZm9yLgoqIGBpbmRleGAgLSBUaGUgaW5kZXggb2YgdGhlIG1lbWJlciB0byBnZXQuCgojIEVycm9ycwoqIGBSYmFjRXJyb3I6OkluZGV4T3V0T2ZCb3VuZHNgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgYm91bmRzLgAAAAAAAA9nZXRfcm9sZV9tZW1iZXIAAAAAAgAAAAAAAAAEcm9sZQAAABEAAAAAAAAABWluZGV4AAAAAAAABAAAAAEAAAAT",
        "AAAAAAAAAPJSZXR1cm5zIGFsbCByb2xlcyB0aGF0IGN1cnJlbnRseSBoYXZlIGF0IGxlYXN0IG9uZSBtZW1iZXIuCkRlZmF1bHRzIHRvIGVtcHR5IHZlY3RvciBpZiBubyByb2xlcyBleGlzdC4KCiMgTm90ZXMKClRoaXMgZnVuY3Rpb24gcmV0dXJucyBhbGwgcm9sZXMgdGhhdCBjdXJyZW50bHkgaGF2ZSBhdCBsZWFzdCBvbmUgbWVtYmVyLgpUaGUgbWF4aW11bSBudW1iZXIgb2Ygcm9sZXMgaXMgbGltaXRlZCBieSBbYE1BWF9ST0xFU2BdLgAAAAAAEmdldF9leGlzdGluZ19yb2xlcwAAAAAAAAAAAAEAAAPqAAAAEQ==",
        "AAAAAAAAAAAAAAAJc2V0X2FkbWluAAAAAAAAAgAAAAAAAAAJbmV3X2FkbWluAAAAAAAAEwAAAAAAAAAIb3BlcmF0b3IAAAATAAAAAA==",
        "AAAAAAAAAAAAAAAOc2V0X2F1dGhvcml6ZWQAAAAAAAMAAAAAAAAAAmlkAAAAAAATAAAAAAAAAAlhdXRob3JpemUAAAAAAAABAAAAAAAAAAhvcGVyYXRvcgAAABMAAAAA",
        "AAAAAAAAAAAAAAAIY2xhd2JhY2sAAAADAAAAAAAAAARmcm9tAAAAEwAAAAAAAAAGYW1vdW50AAAAAAALAAAAAAAAAAhvcGVyYXRvcgAAABMAAAAA",
        "AAAAAAAAAAAAAAAEbWludAAAAAMAAAAAAAAAAnRvAAAAAAATAAAAAAAAAAZhbW91bnQAAAAAAAsAAAAAAAAACG9wZXJhdG9yAAAAEwAAAAA=",
        "AAAAAAAAALdDb25zdHJ1Y3RzIHRoZSBTQUMgbWFuYWdlciBjb250cmFjdC4KCiMgQXJndW1lbnRzCiogYHNhY190b2tlbmAgLSBUaGUgdW5kZXJseWluZyBTdGVsbGFyIEFzc2V0IENvbnRyYWN0IGFkZHJlc3MKKiBgb3duZXJgIC0gVGhlIGluaXRpYWwgb3duZXIgYWRkcmVzcyAoZm9yIFRUTCBtYW5hZ2VtZW50LCByb2xlIGdyYW50cykAAAAADV9fY29uc3RydWN0b3IAAAAAAAACAAAAAAAAAAlzYWNfdG9rZW4AAAAAAAATAAAAAAAAAAVvd25lcgAAAAAAABMAAAAA",
        "AAAAAAAAADxSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIFNBQyAoU3RlbGxhciBBc3NldCBDb250cmFjdCkgYWRkcmVzcy4AAAAOdW5kZXJseWluZ19zYWMAAAAAAAAAAAABAAAAEw==",
        "AAAAAAAAAAAAAAAKYXV0aG9yaXplcgAAAAAAAAAAAAEAAAPoAAAAEw==",
        "AAAAAAAAAD5SZXR1cm5zIHRoZSBjdXJyZW50IG93bmVyIGFkZHJlc3MsIG9yIE5vbmUgaWYgbm8gb3duZXIgaXMgc2V0LgAAAAAABW93bmVyAAAAAAAAAAAAAAEAAAPoAAAAEw==",
        "AAAAAAAAAFlSZXR1cm5zIHRoZSBwZW5kaW5nIG93bmVyIGFkZHJlc3MgZm9yIDItc3RlcCB0cmFuc2Zlciwgb3IgTm9uZSBpZiBubyB0cmFuc2ZlciBpcyBwZW5kaW5nLgAAAAAAAA1wZW5kaW5nX293bmVyAAAAAAAAAAAAAAEAAAPoAAAAEw==",
        "AAAAAAAAASlUcmFuc2ZlcnMgb3duZXJzaGlwIGltbWVkaWF0ZWx5IHRvIGEgbmV3IGFkZHJlc3MuCgpVc2Ugd2l0aCBjYXV0aW9uIC0gaWYgeW91IHRyYW5zZmVyIHRvIGEgd3JvbmcgYWRkcmVzcywgb3duZXJzaGlwIGlzIGxvc3QgZm9yZXZlci4KQ29uc2lkZXIgdXNpbmcgYGJlZ2luX293bmVyc2hpcF90cmFuc2ZlcmAgaW5zdGVhZC4KCiMgUGFuaWNzCi0gYE93bmVyTm90U2V0YCBpZiBubyBvd25lciBpcyBjdXJyZW50bHkgc2V0Ci0gYFRyYW5zZmVySW5Qcm9ncmVzc2AgaWYgYSAyLXN0ZXAgdHJhbnNmZXIgaXMgaW4gcHJvZ3Jlc3MAAAAAAAASdHJhbnNmZXJfb3duZXJzaGlwAAAAAAABAAAAAAAAAAluZXdfb3duZXIAAAAAAAATAAAAAA==",
        "AAAAAAAAAlpCZWdpbnMgYW4gb3duZXJzaGlwIHRyYW5zZmVyIHRvIGEgbmV3IGFkZHJlc3MuCgpUaGUgbmV3IG93bmVyIG11c3QgY2FsbCBgYWNjZXB0X293bmVyc2hpcCgpYCB3aXRoaW4gYHR0bGAgbGVkZ2Vycwp0byBjb21wbGV0ZSB0aGUgdHJhbnNmZXIuIFRoZSBwZW5kaW5nIHRyYW5zZmVyIHdpbGwgYXV0b21hdGljYWxseSBleHBpcmUgYWZ0ZXIuCgojIEFyZ3VtZW50cwotIGBuZXdfb3duZXJgIC0gVGhlIHByb3Bvc2VkIG5ldyBvd25lcgotIGB0dGxgIC0gTnVtYmVyIG9mIGxlZGdlcnMgdGhlIG5ldyBvd25lciBoYXMgdG8gYWNjZXB0LgpVc2UgYDBgIHRvIGNhbmNlbCBhIHBlbmRpbmcgdHJhbnNmZXIgKG5ld19vd25lciBtdXN0IG1hdGNoIHBlbmRpbmcpLgoKIyBQYW5pY3MKLSBgT3duZXJOb3RTZXRgIGlmIG5vIG93bmVyIGlzIGN1cnJlbnRseSBzZXQKLSBgTm9QZW5kaW5nVHJhbnNmZXJgIHdoZW4gY2FuY2VsbGluZyBhbmQgbm8gcGVuZGluZyB0cmFuc2ZlciBleGlzdHMKLSBgSW52YWxpZFR0bGAgaWYgdHRsIGV4Y2VlZHMgbWF4IFRUTAotIGBJbnZhbGlkUGVuZGluZ093bmVyYCB3aGVuIGNhbmNlbGxpbmcgd2l0aCB3cm9uZyBuZXdfb3duZXIgYWRkcmVzcwAAAAAAGGJlZ2luX293bmVyc2hpcF90cmFuc2ZlcgAAAAIAAAAAAAAACW5ld19vd25lcgAAAAAAABMAAAAAAAAAA3R0bAAAAAAEAAAAAA==",
        "AAAAAAAAALlBY2NlcHRzIGEgcGVuZGluZyAyLXN0ZXAgb3duZXJzaGlwIHRyYW5zZmVyLgoKTXVzdCBiZSBjYWxsZWQgYnkgdGhlIHBlbmRpbmcgb3duZXIgYmVmb3JlIHRoZSBUVEwgZXhwaXJlcy4KCiMgUGFuaWNzCi0gYE5vUGVuZGluZ1RyYW5zZmVyYCBpZiB0aGVyZSBpcyBubyBwZW5kaW5nIHRyYW5zZmVyIChvciBpdCBleHBpcmVkKQAAAAAAABBhY2NlcHRfb3duZXJzaGlwAAAAAAAAAAA=",
        "AAAAAAAAAKRQZXJtYW5lbnRseSByZW5vdW5jZXMgb3duZXJzaGlwLgoKIyBQYW5pY3MKLSBgT3duZXJOb3RTZXRgIGlmIG5vIG93bmVyIGlzIGN1cnJlbnRseSBzZXQKLSBgVHJhbnNmZXJJblByb2dyZXNzYCBpZiBhIDItc3RlcCB0cmFuc2ZlciBpcyBpbiBwcm9ncmVzcyAoY2FuY2VsIGl0IGZpcnN0KQAAABJyZW5vdW5jZV9vd25lcnNoaXAAAAAAAAAAAAAA",
        "AAAAAAAAAKVFeHRlbmRzIHRoZSBpbnN0YW5jZSBUVEwuCgojIEFyZ3VtZW50cwoKKiBgdGhyZXNob2xkYCAtIFRoZSB0aHJlc2hvbGQgdG8gZXh0ZW5kIHRoZSBUVEwgKGlmIGN1cnJlbnQgVFRMIGlzIGJlbG93IHRoaXMsIGV4dGVuZCkuCiogYGV4dGVuZF90b2AgLSBUaGUgVFRMIHRvIGV4dGVuZCB0by4AAAAAAAATZXh0ZW5kX2luc3RhbmNlX3R0bAAAAAACAAAAAAAAAAl0aHJlc2hvbGQAAAAAAAAEAAAAAAAAAAlleHRlbmRfdG8AAAAAAAAEAAAAAA==",
        "AAAAAAAAAY9TZXRzIFRUTCBjb25maWdzIGZvciBpbnN0YW5jZSBhbmQgcGVyc2lzdGVudCBzdG9yYWdlLgoKLSBgTm9uZWAgdmFsdWVzIHJlbW92ZSB0aGUgY29ycmVzcG9uZGluZyBjb25maWcgKGRpc2FibGVzIGF1dG8tZXh0ZW5zaW9uIGZvciB0aGF0IHR5cGUpCi0gVmFsaWRhdGVzIHRoYXQgYHRocmVzaG9sZCA8PSBleHRlbmRfdG8gPD0gTUFYX1RUTGAKCiMgQXJndW1lbnRzCi0gYGluc3RhbmNlYCAtIFRUTCBjb25maWcgZm9yIGluc3RhbmNlIHN0b3JhZ2UKLSBgcGVyc2lzdGVudGAgLSBUVEwgY29uZmlnIGZvciBwZXJzaXN0ZW50IHN0b3JhZ2UKCiMgUGFuaWNzCi0gYFR0bENvbmZpZ0Zyb3plbmAgaWYgY29uZmlncyBhcmUgZnJvemVuCi0gYEludmFsaWRUdGxDb25maWdgIGlmIHZhbGlkYXRpb24gZmFpbHMAAAAAD3NldF90dGxfY29uZmlncwAAAAACAAAAAAAAAAhpbnN0YW5jZQAAA+gAAAfQAAAACVR0bENvbmZpZwAAAAAAAAAAAAAKcGVyc2lzdGVudAAAAAAD6AAAB9AAAAAJVHRsQ29uZmlnAAAAAAAAAA==",
        "AAAAAAAAAEhSZXR1cm5zIHRoZSBjdXJyZW50IFRUTCBjb25maWdzIGFzIChpbnN0YW5jZV9jb25maWcsIHBlcnNpc3RlbnRfY29uZmlnKS4AAAALdHRsX2NvbmZpZ3MAAAAAAAAAAAEAAAPtAAAAAgAAA+gAAAfQAAAACVR0bENvbmZpZwAAAAAAA+gAAAfQAAAACVR0bENvbmZpZwAAAA==",
        "AAAAAAAAAOFQZXJtYW5lbnRseSBmcmVlemVzIFRUTCBjb25maWdzLCBwcmV2ZW50aW5nIGFueSBmdXR1cmUgbW9kaWZpY2F0aW9ucy4KClRoaXMgaXMgaXJyZXZlcnNpYmxlIGFuZCBwcm92aWRlcyBpbW11dGFiaWxpdHkgZ3VhcmFudGVlcyB0byB1c2Vycy4KRW1pdHMgYFR0bENvbmZpZ3NGcm96ZW5gIGV2ZW50LgoKIyBQYW5pY3MKLSBgVHRsQ29uZmlnQWxyZWFkeUZyb3plbmAgaWYgYWxyZWFkeSBmcm96ZW4AAAAAAAASZnJlZXplX3R0bF9jb25maWdzAAAAAAAAAAAAAA==",
        "AAAAAAAAACdSZXR1cm5zIHdoZXRoZXIgVFRMIGNvbmZpZ3MgYXJlIGZyb3plbi4AAAAAFWlzX3R0bF9jb25maWdzX2Zyb3plbgAAAAAAAAAAAAABAAAAAQ==",
        "AAAAAgAAAAAAAAAAAAAAEVNBQ01hbmFnZXJTdG9yYWdlAAAAAAAAAQAAAAAAAAAAAAAACFNhY1Rva2Vu",
        "AAAABAAAABxCdWZmZXJSZWFkZXJFcnJvcjogMTAwMC0xMDA5AAAAAAAAABFCdWZmZXJSZWFkZXJFcnJvcgAAAAAAAAIAAAAAAAAADUludmFsaWRMZW5ndGgAAAAAAAPoAAAAAAAAABVJbnZhbGlkQWRkcmVzc1BheWxvYWQAAAAAAAPp",
        "AAAABAAAABxCdWZmZXJXcml0ZXJFcnJvcjogMTAxMC0xMDE5AAAAAAAAABFCdWZmZXJXcml0ZXJFcnJvcgAAAAAAAAEAAAAAAAAAFUludmFsaWRBZGRyZXNzUGF5bG9hZAAAAAAAA/I=",
        "AAAABAAAAB9UdGxDb25maWd1cmFibGVFcnJvcjogMTAyMC0xMDI5AAAAAAAAAAAUVHRsQ29uZmlndXJhYmxlRXJyb3IAAAADAAAAAAAAABBJbnZhbGlkVHRsQ29uZmlnAAAD/AAAAAAAAAAPVHRsQ29uZmlnRnJvemVuAAAAA/0AAAAAAAAAFlR0bENvbmZpZ0FscmVhZHlGcm96ZW4AAAAAA/4=",
        "AAAABAAAABdPd25hYmxlRXJyb3I6IDEwMzAtMTAzOQAAAAAAAAAADE93bmFibGVFcnJvcgAAAAcAAAAAAAAAEUludmFsaWRBdXRob3JpemVyAAAAAAAEBgAAAAAAAAATSW52YWxpZFBlbmRpbmdPd25lcgAAAAQHAAAAAAAAAApJbnZhbGlkVHRsAAAAAAQIAAAAAAAAABFOb1BlbmRpbmdUcmFuc2ZlcgAAAAAABAkAAAAAAAAAD093bmVyQWxyZWFkeVNldAAAAAQKAAAAAAAAAAtPd25lck5vdFNldAAAAAQLAAAAAAAAABJUcmFuc2ZlckluUHJvZ3Jlc3MAAAAABAw=",
        "AAAABAAAABhCeXRlc0V4dEVycm9yOiAxMDQwLTEwNDkAAAAAAAAADUJ5dGVzRXh0RXJyb3IAAAAAAAABAAAAAAAAAA5MZW5ndGhNaXNtYXRjaAAAAAAEEA==",
        "AAAABAAAABtVcGdyYWRlYWJsZUVycm9yOiAxMDUwLTEwNTkAAAAAAAAAABBVcGdyYWRlYWJsZUVycm9yAAAAAgAAAAAAAAAUSW52YWxpZE1pZ3JhdGlvbkRhdGEAAAQaAAAAAAAAABNNaWdyYXRpb25Ob3RBbGxvd2VkAAAABBs=",
        "AAAABAAAABhNdWx0aVNpZ0Vycm9yOiAxMDYwLTEwNjkAAAAAAAAADU11bHRpU2lnRXJyb3IAAAAAAAAJAAAAAAAAABJBbHJlYWR5SW5pdGlhbGl6ZWQAAAAABCQAAAAAAAAAEUludmFsaWRBdXRob3JpemVyAAAAAAAEJQAAAAAAAAANSW52YWxpZFNpZ25lcgAAAAAABCYAAAAAAAAADlNpZ25hdHVyZUVycm9yAAAAAAQnAAAAAAAAABNTaWduZXJBbHJlYWR5RXhpc3RzAAAABCgAAAAAAAAADlNpZ25lck5vdEZvdW5kAAAAAAQpAAAAAAAAAB1Ub3RhbFNpZ25lcnNMZXNzVGhhblRocmVzaG9sZAAAAAAABCoAAAAAAAAAD1Vuc29ydGVkU2lnbmVycwAAAAQrAAAAAAAAAA1aZXJvVGhyZXNob2xkAAAAAAAELA==",
        "AAAABAAAABRBdXRoRXJyb3I6IDEwNzAtMTA3OQAAAAAAAAAJQXV0aEVycm9yAAAAAAAAAQAAAAAAAAASQXV0aG9yaXplck5vdEZvdW5kAAAAAAQu",
        "AAAABAAAABRSYmFjRXJyb3I6IDEwODAtMTA4OQAAAAAAAAAJUmJhY0Vycm9yAAAAAAAABwAAAAAAAAARQWRtaW5Sb2xlTm90Rm91bmQAAAAAAAQ4AAAAAAAAABBJbmRleE91dE9mQm91bmRzAAAEOQAAAAAAAAAQTWF4Um9sZXNFeGNlZWRlZAAABDoAAAAAAAAAC1JvbGVJc0VtcHR5AAAABDsAAAAAAAAADFJvbGVOb3RGb3VuZAAABDwAAAAAAAAAC1JvbGVOb3RIZWxkAAAABD0AAAAAAAAADFVuYXV0aG9yaXplZAAABD4=",
        "AAAABQAAADBFdmVudCBlbWl0dGVkIHdoZW4gYSBzaWduZXIgaXMgYWRkZWQgb3IgcmVtb3ZlZC4AAAAAAAAACVNpZ25lclNldAAAAAAAAAEAAAAKc2lnbmVyX3NldAAAAAAAAgAAAAAAAAAGc2lnbmVyAAAAAAPuAAAAFAAAAAEAAAAAAAAABmFjdGl2ZQAAAAAAAQAAAAAAAAAC",
        "AAAABQAAADZFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHNpZ25hdHVyZSB0aHJlc2hvbGQgaXMgY2hhbmdlZC4AAAAAAAAAAAAMVGhyZXNob2xkU2V0AAAAAQAAAA10aHJlc2hvbGRfc2V0AAAAAAAAAQAAAAAAAAAJdGhyZXNob2xkAAAAAAAABAAAAAAAAAAC",
        "AAAAAgAAAAAAAAAAAAAAD011bHRpU2lnU3RvcmFnZQAAAAACAAAAAAAAAAAAAAAHU2lnbmVycwAAAAAAAAAAAAAAAAlUaHJlc2hvbGQAAAA=",
        "AAAABQAAAFdFdmVudCBlbWl0dGVkIHdoZW4gb3duZXJzaGlwIGlzIHRyYW5zZmVycmVkIChib3RoIHNpbmdsZS1zdGVwIGFuZCB0d28tc3RlcCBjb21wbGV0aW9uKS4AAAAAAAAAABRPd25lcnNoaXBUcmFuc2ZlcnJlZAAAAAEAAAAVb3duZXJzaGlwX3RyYW5zZmVycmVkAAAAAAAAAgAAAAAAAAAJb2xkX293bmVyAAAAAAAAEwAAAAAAAAAAAAAACW5ld19vd25lcgAAAAAAABMAAAAAAAAAAg==",
        "AAAABQAAADtFdmVudCBlbWl0dGVkIHdoZW4gYSAyLXN0ZXAgb3duZXJzaGlwIHRyYW5zZmVyIGlzIHByb3Bvc2VkLgAAAAAAAAAAFU93bmVyc2hpcFRyYW5zZmVycmluZwAAAAAAAAEAAAAWb3duZXJzaGlwX3RyYW5zZmVycmluZwAAAAAAAwAAAAAAAAAJb2xkX293bmVyAAAAAAAAEwAAAAAAAAAAAAAACW5ld19vd25lcgAAAAAAABMAAAAAAAAAAAAAAAN0dGwAAAAABAAAAAAAAAAC",
        "AAAABQAAADxFdmVudCBlbWl0dGVkIHdoZW4gYSAyLXN0ZXAgb3duZXJzaGlwIHRyYW5zZmVyIGlzIGNhbmNlbGxlZC4AAAAAAAAAGk93bmVyc2hpcFRyYW5zZmVyQ2FuY2VsbGVkAAAAAAABAAAAHG93bmVyc2hpcF90cmFuc2Zlcl9jYW5jZWxsZWQAAAACAAAAAAAAAAVvd25lcgAAAAAAABMAAAAAAAAAAAAAABdjYW5jZWxsZWRfcGVuZGluZ19vd25lcgAAAAATAAAAAAAAAAI=",
        "AAAABQAAACpFdmVudCBlbWl0dGVkIHdoZW4gb3duZXJzaGlwIGlzIHJlbm91bmNlZC4AAAAAAAAAAAAST3duZXJzaGlwUmVub3VuY2VkAAAAAAABAAAAE293bmVyc2hpcF9yZW5vdW5jZWQAAAAAAQAAAAAAAAAJb2xkX293bmVyAAAAAAAAEwAAAAAAAAAC",
        "AAAAAgAAAAAAAAAAAAAADk93bmFibGVTdG9yYWdlAAAAAAACAAAAAAAAAAAAAAAFT3duZXIAAAAAAAAAAAAAAAAAAAxQZW5kaW5nT3duZXI=",
        "AAAABQAAACVFdmVudCBlbWl0dGVkIHdoZW4gYSByb2xlIGlzIGdyYW50ZWQuAAAAAAAAAAAAAAtSb2xlR3JhbnRlZAAAAAABAAAADHJvbGVfZ3JhbnRlZAAAAAMAAAAAAAAABHJvbGUAAAARAAAAAQAAAAAAAAAHYWNjb3VudAAAAAATAAAAAQAAAAAAAAAGY2FsbGVyAAAAAAATAAAAAAAAAAI=",
        "AAAABQAAACVFdmVudCBlbWl0dGVkIHdoZW4gYSByb2xlIGlzIHJldm9rZWQuAAAAAAAAAAAAAAtSb2xlUmV2b2tlZAAAAAABAAAADHJvbGVfcmV2b2tlZAAAAAMAAAAAAAAABHJvbGUAAAARAAAAAQAAAAAAAAAHYWNjb3VudAAAAAATAAAAAQAAAAAAAAAGY2FsbGVyAAAAAAATAAAAAAAAAAI=",
        "AAAABQAAACtFdmVudCBlbWl0dGVkIHdoZW4gYSByb2xlIGFkbWluIGlzIGNoYW5nZWQuAAAAAAAAAAAQUm9sZUFkbWluQ2hhbmdlZAAAAAEAAAAScm9sZV9hZG1pbl9jaGFuZ2VkAAAAAAADAAAAAAAAAARyb2xlAAAAEQAAAAEAAAAAAAAAE3ByZXZpb3VzX2FkbWluX3JvbGUAAAAD6AAAABEAAAAAAAAAAAAAAA5uZXdfYWRtaW5fcm9sZQAAAAAD6AAAABEAAAAAAAAAAg==",
        "AAAAAgAAAAAAAAAAAAAAC1JiYWNTdG9yYWdlAAAAAAUAAAAAAAAAAAAAAA1FeGlzdGluZ1JvbGVzAAAAAAAAAQAAAAAAAAASUm9sZUluZGV4VG9BY2NvdW50AAAAAAACAAAAEQAAAAQAAAABAAAAAAAAABJSb2xlQWNjb3VudFRvSW5kZXgAAAAAAAIAAAARAAAAEwAAAAEAAAAAAAAAEVJvbGVBY2NvdW50c0NvdW50AAAAAAAAAQAAABEAAAABAAAAAAAAAAlSb2xlQWRtaW4AAAAAAAABAAAAEQ==",
        "AAAAAQAAAElUVEwgY29uZmlndXJhdGlvbjogdGhyZXNob2xkICh3aGVuIHRvIGV4dGVuZCkgYW5kIGV4dGVuZF90byAodGFyZ2V0IFRUTCkuAAAAAAAAAAAAAAlUdGxDb25maWcAAAAAAAACAAAAKFRhcmdldCBUVEwgYWZ0ZXIgZXh0ZW5zaW9uIChpbiBsZWRnZXJzKS4AAAAJZXh0ZW5kX3RvAAAAAAAABAAAADNUVEwgdGhyZXNob2xkIHRoYXQgdHJpZ2dlcnMgZXh0ZW5zaW9uIChpbiBsZWRnZXJzKS4AAAAACXRocmVzaG9sZAAAAAAAAAQ=",
        "AAAABQAAACdFdmVudCBlbWl0dGVkIHdoZW4gVFRMIGNvbmZpZ3MgYXJlIHNldC4AAAAAAAAAAA1UdGxDb25maWdzU2V0AAAAAAAAAQAAAA90dGxfY29uZmlnc19zZXQAAAAAAgAAAAAAAAAIaW5zdGFuY2UAAAPoAAAH0AAAAAlUdGxDb25maWcAAAAAAAAAAAAAAAAAAApwZXJzaXN0ZW50AAAAAAPoAAAH0AAAAAlUdGxDb25maWcAAAAAAAAAAAAAAg==",
        "AAAABQAAACpFdmVudCBlbWl0dGVkIHdoZW4gVFRMIGNvbmZpZ3MgYXJlIGZyb3plbi4AAAAAAAAAAAAQVHRsQ29uZmlnc0Zyb3plbgAAAAEAAAASdHRsX2NvbmZpZ3NfZnJvemVuAAAAAAAAAAAAAg==",
        "AAAAAgAAAAAAAAAAAAAAEFR0bENvbmZpZ1N0b3JhZ2UAAAADAAAAAAAAAAAAAAAGRnJvemVuAAAAAAAAAAAAAAAAAAhJbnN0YW5jZQAAAAAAAAAAAAAAClBlcnNpc3RlbnQAAA==",
        "AAAAAgAAAAAAAAAAAAAAElVwZ3JhZGVhYmxlU3RvcmFnZQAAAAAAAQAAAAAAAAAAAAAACU1pZ3JhdGluZwAAAA==" ]),
      options
    )
  }
  public readonly fromJSON = {
    grant_role: this.txFromJSON<null>,
        revoke_role: this.txFromJSON<null>,
        renounce_role: this.txFromJSON<null>,
        set_role_admin: this.txFromJSON<null>,
        remove_role_admin: this.txFromJSON<null>,
        has_role: this.txFromJSON<Option<u32>>,
        get_role_admin: this.txFromJSON<Option<string>>,
        get_role_member_count: this.txFromJSON<u32>,
        get_role_member: this.txFromJSON<string>,
        get_existing_roles: this.txFromJSON<Array<string>>,
        set_admin: this.txFromJSON<null>,
        set_authorized: this.txFromJSON<null>,
        clawback: this.txFromJSON<null>,
        mint: this.txFromJSON<null>,
        underlying_sac: this.txFromJSON<string>,
        authorizer: this.txFromJSON<Option<string>>,
        owner: this.txFromJSON<Option<string>>,
        pending_owner: this.txFromJSON<Option<string>>,
        transfer_ownership: this.txFromJSON<null>,
        begin_ownership_transfer: this.txFromJSON<null>,
        accept_ownership: this.txFromJSON<null>,
        renounce_ownership: this.txFromJSON<null>,
        extend_instance_ttl: this.txFromJSON<null>,
        set_ttl_configs: this.txFromJSON<null>,
        ttl_configs: this.txFromJSON<readonly [Option<TtlConfig>, Option<TtlConfig>]>,
        freeze_ttl_configs: this.txFromJSON<null>,
        is_ttl_configs_frozen: this.txFromJSON<boolean>
  }
}