() => {
			const r = document.createElement("script");
			r.type = "text/javascript";
			r.async = !0;
			r.src = "https://cdn.rudderlabs.com/v1/rudder-analytics.min.js";
			const a = document.getElementsByTagName("script")[0];
			if(a && a.parentNode) {
				a.parentNode.insertBefore(r, a);
			}
		}


class Telemetry {

	private get telemetry() {
		// @ts-ignore
		return window.rudderanalytics;
	}

	private userNodesPanelSession: IUserNodesPanelSession = {
		sessionId: '',
		data: {
			nodeFilter: '',
			resultsNodes: [],
			filterMode: 'Regular',
		},
	};

	init(options: ITelemetrySettings, instanceId: string) {
		if (options.enabled && !this.telemetry) {
			if(!options.config) {
				return;
			}

			this.loadTelemetryLibrary(options.config.key, options.config.url, { integrations: { All: false }, loadIntegration: false });
			this.telemetry.identify(instanceId);
		}
	}

	track(event: string, properties?: IDataObject) {
		if (this.telemetry) {
			this.telemetry.track(event, properties);
		}
	}

	trackNodesPanel(event: string, properties: IDataObject = {}) {
		if (this.telemetry) {
			properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
			switch (event) {
				case 'nodeView.createNodeActiveChanged':
					if (properties.createNodeActive !== false) {
						this.resetNodesPanelSession();
						properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
						this.telemetry.track('User opened nodes panel', properties);
					}
					break;
				case 'nodeCreateList.selectedTypeChanged':
					this.userNodesPanelSession.data.filterMode = properties.new_filter as string;
					this.telemetry.track('User changed nodes panel filter', properties);
					break;
				case 'nodeCreateList.destroyed':
					if(this.userNodesPanelSession.data.nodeFilter.length > 0 && this.userNodesPanelSession.data.nodeFilter !== '') {
						this.telemetry.track('User entered nodes panel search term', this.generateNodesPanelEvent());
					}
					break;
				case 'nodeCreateList.nodeFilterChanged':
					if((properties.newValue as string).length === 0 && this.userNodesPanelSession.data.nodeFilter.length > 0) {
						this.telemetry.track('User entered nodes panel search term', this.generateNodesPanelEvent());
					}

					if((properties.newValue as string).length > (properties.oldValue as string || '').length) {
						this.userNodesPanelSession.data.nodeFilter = properties.newValue as string;
						this.userNodesPanelSession.data.resultsNodes = ((properties.filteredNodes || []) as INodeCreateElement[]).map((node: INodeCreateElement) => node.key);
					}
					break;
				case 'nodeCreateList.onCategoryExpanded':
					properties.is_subcategory = false;
					this.telemetry.track('User viewed node category', properties);
					break;
				case 'nodeCreateList.onSubcategorySelected':
					const selectedProperties = (properties.selected as IDataObject).properties as IDataObject;
					if(selectedProperties && selectedProperties.subcategory) {
						properties.category_name = selectedProperties.subcategory;
					}
					properties.is_subcategory = true;
					delete properties.selected;
					this.telemetry.track('User viewed node category', properties);
					break;
				case 'nodeView.addNodeButton':
					this.telemetry.track('User added node to workflow canvas', properties);
					break;
				default:
					break;
			}
		}
	}

	private resetNodesPanelSession() {
		this.userNodesPanelSession.sessionId = `nodes_panel_session_${(new Date()).valueOf()}`;
		this.userNodesPanelSession.data = {
			nodeFilter: '',
			resultsNodes: [],
			filterMode: 'All',
		};
	}

	private generateNodesPanelEvent() {
		return {
			search_string: this.userNodesPanelSession.data.nodeFilter,
			results_count: this.userNodesPanelSession.data.resultsNodes.length,
			filter_mode: this.userNodesPanelSession.data.filterMode,
			nodes_panel_session_id: this.userNodesPanelSession.sessionId,
		};
	}

	private loadTelemetryLibrary(key: string, url: string, options: IDataObject) {
		// @ts-ignore
		window.rudderanalytics = window.rudderanalytics || [];

		this.telemetry.methods = ["load", "page", "track", "identify", "alias", "group", "ready", "reset", "getAnonymousId", "setAnonymousId"];
		this.telemetry.factory = (t: any) => { // tslint:disable-line:no-any
			return (...args: any[]) => { // tslint:disable-line:no-any
				const r = Array.prototype.slice.call(args);
				r.unshift(t);
				this.telemetry.push(r);
				return this.telemetry;
			};
		};

		for (let t = 0; t < this.telemetry.methods.length; t++) {
			const r = this.telemetry.methods[t];
			this.telemetry[r] = this.telemetry.factory(r);
		}

		this.telemetry.loadJS = () => {
			const r = document.createElement("script");
			r.type = "text/javascript";
			r.async = !0;
			r.src = "https://cdn.rudderlabs.com/v1/rudder-analytics.min.js";
			const a = document.getElementsByTagName("script")[0];
			if(a && a.parentNode) {
				a.parentNode.insertBefore(r, a);
			}
		};
		this.telemetry.loadJS();
		this.telemetry.load(key, url, options);
	}
}


interface Vue {
		$telemetry: Telemetry;
	}


interface IUserNodesPanelSessionData {
	nodeFilter: string;
	resultsNodes: string[];
	filterMode: string;
}


interface IUserNodesPanelSession {
	sessionId: string;
	data: IUserNodesPanelSessionData;
}


get() { return telemetry; }


init(options: ITelemetrySettings, instanceId: string) {
		if (options.enabled && !this.telemetry) {
			if(!options.config) {
				return;
			}

			this.loadTelemetryLibrary(options.config.key, options.config.url, { integrations: { All: false }, loadIntegration: false });
			this.telemetry.identify(instanceId);
		}
	}


track(event: string, properties?: IDataObject) {
		if (this.telemetry) {
			this.telemetry.track(event, properties);
		}
	}


trackNodesPanel(event: string, properties: IDataObject = {}) {
		if (this.telemetry) {
			properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
			switch (event) {
				case 'nodeView.createNodeActiveChanged':
					if (properties.createNodeActive !== false) {
						this.resetNodesPanelSession();
						properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
						this.telemetry.track('User opened nodes panel', properties);
					}
					break;
				case 'nodeCreateList.selectedTypeChanged':
					this.userNodesPanelSession.data.filterMode = properties.new_filter as string;
					this.telemetry.track('User changed nodes panel filter', properties);
					break;
				case 'nodeCreateList.destroyed':
					if(this.userNodesPanelSession.data.nodeFilter.length > 0 && this.userNodesPanelSession.data.nodeFilter !== '') {
						this.telemetry.track('User entered nodes panel search term', this.generateNodesPanelEvent());
					}
					break;
				case 'nodeCreateList.nodeFilterChanged':
					if((properties.newValue as string).length === 0 && this.userNodesPanelSession.data.nodeFilter.length > 0) {
						this.telemetry.track('User entered nodes panel search term', this.generateNodesPanelEvent());
					}

					if((properties.newValue as string).length > (properties.oldValue as string || '').length) {
						this.userNodesPanelSession.data.nodeFilter = properties.newValue as string;
						this.userNodesPanelSession.data.resultsNodes = ((properties.filteredNodes || []) as INodeCreateElement[]).map((node: INodeCreateElement) => node.key);
					}
					break;
				case 'nodeCreateList.onCategoryExpanded':
					properties.is_subcategory = false;
					this.telemetry.track('User viewed node category', properties);
					break;
				case 'nodeCreateList.onSubcategorySelected':
					const selectedProperties = (properties.selected as IDataObject).properties as IDataObject;
					if(selectedProperties && selectedProperties.subcategory) {
						properties.category_name = selectedProperties.subcategory;
					}
					properties.is_subcategory = true;
					delete properties.selected;
					this.telemetry.track('User viewed node category', properties);
					break;
				case 'nodeView.addNodeButton':
					this.telemetry.track('User added node to workflow canvas', properties);
					break;
				default:
					break;
			}
		}
	}


private resetNodesPanelSession() {
		this.userNodesPanelSession.sessionId = `nodes_panel_session_${(new Date()).valueOf()}`;
		this.userNodesPanelSession.data = {
			nodeFilter: '',
			resultsNodes: [],
			filterMode: 'All',
		};
	}


private generateNodesPanelEvent() {
		return {
			search_string: this.userNodesPanelSession.data.nodeFilter,
			results_count: this.userNodesPanelSession.data.resultsNodes.length,
			filter_mode: this.userNodesPanelSession.data.filterMode,
			nodes_panel_session_id: this.userNodesPanelSession.sessionId,
		};
	}


private loadTelemetryLibrary(key: string, url: string, options: IDataObject) {
		// @ts-ignore
		window.rudderanalytics = window.rudderanalytics || [];

		this.telemetry.methods = ["load", "page", "track", "identify", "alias", "group", "ready", "reset", "getAnonymousId", "setAnonymousId"];
		this.telemetry.factory = (t: any) => { // tslint:disable-line:no-any
			return (...args: any[]) => { // tslint:disable-line:no-any
				const r = Array.prototype.slice.call(args);
				r.unshift(t);
				this.telemetry.push(r);
				return this.telemetry;
			};
		};

		for (let t = 0; t < this.telemetry.methods.length; t++) {
			const r = this.telemetry.methods[t];
			this.telemetry[r] = this.telemetry.factory(r);
		}

		this.telemetry.loadJS = () => {
			const r = document.createElement("script");
			r.type = "text/javascript";
			r.async = !0;
			r.src = "https://cdn.rudderlabs.com/v1/rudder-analytics.min.js";
			const a = document.getElementsByTagName("script")[0];
			if(a && a.parentNode) {
				a.parentNode.insertBefore(r, a);
			}
		};
		this.telemetry.loadJS();
		this.telemetry.load(key, url, options);
	}


@EntityRepository(Transaction)
export class TransactionRepository extends Repository<Transaction> {
  async findWithInstances(
    transactionHash?: string,
    blockHash?: string,
  ): Promise<Transaction | null> {
    const transaction = await this.findOne({
      where: {
        hash: transactionHash,
        block: { hash: blockHash },
      },
      relations: FULL_JOINS,
    })
    return transaction || null
  }

  async getWithInstances(transactionHash?: string, blockHash?: string): Promise<Transaction> {
    return await this.findOneOrFail({
      where: {
        hash: transactionHash,
        block: { hash: blockHash },
      },
      relations: FULL_JOINS,
    })
  }

  async findByHashWithInstances(hash: string, limit: number): Promise<Transaction[]> {
    return (
      (await this.find({
        where: { hash: Like(`%${hash}%`) },
        take: limit,
        relations: FULL_JOINS,
      })) || []
    )
  }
}


async findWithInstances(
    transactionHash?: string,
    blockHash?: string,
  ): Promise<Transaction | null> {
    const transaction = await this.findOne({
      where: {
        hash: transactionHash,
        block: { hash: blockHash },
      },
      relations: FULL_JOINS,
    })
    return transaction || null
  }


async getWithInstances(transactionHash?: string, blockHash?: string): Promise<Transaction> {
    return await this.findOneOrFail({
      where: {
        hash: transactionHash,
        block: { hash: blockHash },
      },
      relations: FULL_JOINS,
    })
  }


async findByHashWithInstances(hash: string, limit: number): Promise<Transaction[]> {
    return (
      (await this.find({
        where: { hash: Like(`%${hash}%`) },
        take: limit,
        relations: FULL_JOINS,
      })) || []
    )
  }


/** Returns a list of all available group avatars for the signed-in user. */
export declare function getAvailableAvatars(
  http: HttpClient
): Promise<
  ServerResponse<{
    [key: number]: string;
  }>
>;


/** Returns a list of all available group themes. */
export declare function getAvailableThemes(http: HttpClient): Promise<ServerResponse<GroupTheme[]>>;


/**
 * Gets the state of the user's clan invite preferences for a particular membership
 * type - true if they wish to be invited to clans, false otherwise.
 */
export declare function getUserClanInviteSetting(
  http: HttpClient,
  params: GetUserClanInviteSettingParams
): Promise<ServerResponse<boolean>>;


/**
 * Gets groups recommended for you based on the groups to whom those you follow
 * belong.
 */
export declare function getRecommendedGroups(
  http: HttpClient,
  params: GetRecommendedGroupsParams
): Promise<ServerResponse<GroupV2Card[]>>;


/** Search for Groups. */
export declare function groupSearch(
  http: HttpClient,
  body: GroupQuery
): Promise<ServerResponse<GroupSearchResponse>>;


/** Get information about a specific group of the given ID. */
export declare function getGroup(
  http: HttpClient,
  params: GetGroupParams
): Promise<ServerResponse<GroupResponse>>;


/** Get information about a specific group with the given name and type. */
export declare function getGroupByName(
  http: HttpClient,
  params: GetGroupByNameParams
): Promise<ServerResponse<GroupResponse>>;


/**
 * Get information about a specific group with the given name and type. The POST
 * version.
 */
export declare function getGroupByNameV2(
  http: HttpClient,
  body: GroupNameSearchRequest
): Promise<ServerResponse<GroupResponse>>;


/** Gets a list of available optional conversation channels and their settings. */
export declare function getGroupOptionalConversations(
  http: HttpClient,
  params: GetGroupOptionalConversationsParams
): Promise<ServerResponse<GroupOptionalConversation[]>>;


/**
 * Edit an existing group. You must have suitable permissions in the group to
 * perform this operation. This latest revision will only edit the fields you pass
 * in - pass null for properties you want to leave unaltered.
 */
export declare function editGroup(
  http: HttpClient,
  params: EditGroupParams,
  body: GroupEditAction
): Promise<ServerResponse<number>>;


/**
 * Edit an existing group's clan banner. You must have suitable permissions in the
 * group to perform this operation. All fields are required.
 */
export declare function editClanBanner(
  http: HttpClient,
  params: EditClanBannerParams,
  body: ClanBanner
): Promise<ServerResponse<number>>;


/**
 * Edit group options only available to a founder. You must have suitable
 * permissions in the group to perform this operation.
 */
export declare function editFounderOptions(
  http: HttpClient,
  params: EditFounderOptionsParams,
  body: GroupOptionsEditAction
): Promise<ServerResponse<number>>;


/**
 * Add a new optional conversation/chat channel. Requires admin permissions to the
 * group.
 */
export declare function addOptionalConversation(
  http: HttpClient,
  params: AddOptionalConversationParams,
  body: GroupOptionalConversationAddRequest
): Promise<ServerResponse<string>>;


/**
 * Edit the settings of an optional conversation/chat channel. Requires admin
 * permissions to the group.
 */
export declare function editOptionalConversation(
  http: HttpClient,
  params: EditOptionalConversationParams,
  body: GroupOptionalConversationEditRequest
): Promise<ServerResponse<string>>;


/** Get the list of members in a given group. */
export declare function getMembersOfGroup(
  http: HttpClient,
  params: GetMembersOfGroupParams
): Promise<ServerResponse<SearchResultOfGroupMember>>;


/** Get the list of members in a given group who are of admin level or higher. */
export declare function getAdminsAndFounderOfGroup(
  http: HttpClient,
  params: GetAdminsAndFounderOfGroupParams
): Promise<ServerResponse<SearchResultOfGroupMember>>;


/**
 * Edit the membership type of a given member. You must have suitable permissions
 * in the group to perform this operation.
 */
export declare function editGroupMembership(
  http: HttpClient,
  params: EditGroupMembershipParams
): Promise<ServerResponse<number>>;


/**
 * Kick a member from the given group, forcing them to reapply if they wish to re-
 * join the group. You must have suitable permissions in the group to perform this
 * operation.
 */
export declare function kickMember(
  http: HttpClient,
  params: KickMemberParams
): Promise<ServerResponse<GroupMemberLeaveResult>>;


/**
 * Bans the requested member from the requested group for the specified period of
 * time.
 */
export declare function banMember(
  http: HttpClient,
  params: BanMemberParams,
  body: GroupBanRequest
): Promise<ServerResponse<number>>;


/** Unbans the requested member, allowing them to re-apply for membership. */
export declare function unbanMember(
  http: HttpClient,
  params: UnbanMemberParams
): Promise<ServerResponse<number>>;


/**
 * Get the list of banned members in a given group. Only accessible to group Admins
 * and above. Not applicable to all groups. Check group features.
 */
export declare function getBannedMembersOfGroup(
  http: HttpClient,
  params: GetBannedMembersOfGroupParams
): Promise<ServerResponse<SearchResultOfGroupBan>>;


/**
 * An administrative method to allow the founder of a group or clan to give up
 * their position to another admin permanently.
 */
export declare function abdicateFoundership(
  http: HttpClient,
  params: AbdicateFoundershipParams
): Promise<ServerResponse<boolean>>;


/**
 * Get the list of users who are awaiting a decision on their application to join a
 * given group. Modified to include application info.
 */
export declare function getPendingMemberships(
  http: HttpClient,
  params: GetPendingMembershipsParams
): Promise<ServerResponse<SearchResultOfGroupMemberApplication>>;


/** Get the list of users who have been invited into the group. */
export declare function getInvitedIndividuals(
  http: HttpClient,
  params: GetInvitedIndividualsParams
): Promise<ServerResponse<SearchResultOfGroupMemberApplication>>;


/** Approve all of the pending users for the given group. */
export declare function approveAllPending(
  http: HttpClient,
  params: ApproveAllPendingParams,
  body: GroupApplicationRequest
): Promise<ServerResponse<EntityActionResult[]>>;


/** Deny all of the pending users for the given group. */
export declare function denyAllPending(
  http: HttpClient,
  params: DenyAllPendingParams,
  body: GroupApplicationRequest
): Promise<ServerResponse<EntityActionResult[]>>;


/** Approve all of the pending users for the given group. */
export declare function approvePendingForList(
  http: HttpClient,
  params: ApprovePendingForListParams,
  body: GroupApplicationListRequest
): Promise<ServerResponse<EntityActionResult[]>>;


/**
 * Approve the given membershipId to join the group/clan as long as they have
 * applied.
 */
export declare function approvePending(
  http: HttpClient,
  params: ApprovePendingParams,
  body: GroupApplicationRequest
): Promise<ServerResponse<boolean>>;


/** Deny all of the pending users for the given group that match the passed-in . */
export declare function denyPendingForList(
  http: HttpClient,
  params: DenyPendingForListParams,
  body: GroupApplicationListRequest
): Promise<ServerResponse<EntityActionResult[]>>;


/** Get information about the groups that a given member has joined. */
export declare function getGroupsForMember(
  http: HttpClient,
  params: GetGroupsForMemberParams
): Promise<ServerResponse<GetGroupsForMemberResponse>>;


/**
 * Allows a founder to manually recover a group they can see in game but not on
 * bungie.net
 */
export declare function recoverGroupForFounder(
  http: HttpClient,
  params: RecoverGroupForFounderParams
): Promise<ServerResponse<GroupMembershipSearchResponse>>;


/**
 * Get information about the groups that a given member has applied to or been
 * invited to.
 */
export declare function getPotentialGroupsForMember(
  http: HttpClient,
  params: GetPotentialGroupsForMemberParams
): Promise<ServerResponse<GroupPotentialMembershipSearchResponse>>;


/** Invite a user to join this group. */
export declare function individualGroupInvite(
  http: HttpClient,
  params: IndividualGroupInviteParams,
  body: GroupApplicationRequest
): Promise<ServerResponse<GroupApplicationResponse>>;


/** Cancels a pending invitation to join a group. */
export declare function individualGroupInviteCancel(
  http: HttpClient,
  params: IndividualGroupInviteCancelParams
): Promise<ServerResponse<GroupApplicationResponse>>;


export interface GetUserClanInviteSettingParams {
  /** The Destiny membership type of the account we wish to access settings. */
  mType: BungieMembershipType;
}


export interface GetRecommendedGroupsParams {
  /** Requested range in which to pull recommended groups */
  createDateRange: GroupDateRange;
  /** Type of groups requested */
  groupType: GroupType;
}


export interface GetGroupParams {
  /** Requested group's id. */
  groupId: string;
}


export interface GetGroupByNameParams {
  /** Exact name of the group to find. */
  groupName: string;
  /** Type of group to find. */
  groupType: GroupType;
}


export interface GetGroupOptionalConversationsParams {
  /** Requested group's id. */
  groupId: string;
}


export interface EditGroupParams {
  /** Group ID of the group to edit. */
  groupId: string;
}


export interface EditClanBannerParams {
  /** Group ID of the group to edit. */
  groupId: string;
}


export interface EditFounderOptionsParams {
  /** Group ID of the group to edit. */
  groupId: string;
}


export interface AddOptionalConversationParams {
  /** Group ID of the group to edit. */
  groupId: string;
}


export interface EditOptionalConversationParams {
  /** Conversation Id of the channel being edited. */
  conversationId: string;
  /** Group ID of the group to edit. */
  groupId: string;
}


export interface GetMembersOfGroupParams {
  /** Page number (starting with 1). Each page has a fixed size of 50 items per page. */
  currentpage: number;
  /** The ID of the group. */
  groupId: string;
  /** Filter out other member types. Use None for all members. */
  memberType?: RuntimeGroupMemberType;
  /**
   * The name fragment upon which a search should be executed for members with
   * matching display or unique names.
   */
  nameSearch?: string;
}


export interface GetAdminsAndFounderOfGroupParams {
  /** Page number (starting with 1). Each page has a fixed size of 50 items per page. */
  currentpage: number;
  /** The ID of the group. */
  groupId: string;
}


export interface EditGroupMembershipParams {
  /** ID of the group to which the member belongs. */
  groupId: string;
  /** Membership ID to modify. */
  membershipId: string;
  /** Membership type of the provide membership ID. */
  membershipType: BungieMembershipType;
  /** New membertype for the specified member. */
  memberType: RuntimeGroupMemberType;
}


export interface KickMemberParams {
  /** Group ID to kick the user from. */
  groupId: string;
  /** Membership ID to kick. */
  membershipId: string;
  /** Membership type of the provided membership ID. */
  membershipType: BungieMembershipType;
}


export interface BanMemberParams {
  /** Group ID that has the member to ban. */
  groupId: string;
  /** Membership ID of the member to ban from the group. */
  membershipId: string;
  /** Membership type of the provided membership ID. */
  membershipType: BungieMembershipType;
}


export interface UnbanMemberParams {
  groupId: string;
  /** Membership ID of the member to unban from the group */
  membershipId: string;
  /** Membership type of the provided membership ID. */
  membershipType: BungieMembershipType;
}


export interface GetBannedMembersOfGroupParams {
  /** Page number (starting with 1). Each page has a fixed size of 50 entries. */
  currentpage: number;
  /** Group ID whose banned members you are fetching */
  groupId: string;
}


export interface AbdicateFoundershipParams {
  /** The new founder for this group. Must already be a group admin. */
  founderIdNew: string;
  /** The target group id. */
  groupId: string;
  /** Membership type of the provided founderIdNew. */
  membershipType: BungieMembershipType;
}


export interface GetPendingMembershipsParams {
  /** Page number (starting with 1). Each page has a fixed size of 50 items per page. */
  currentpage: number;
  /** ID of the group. */
  groupId: string;
}


export interface GetInvitedIndividualsParams {
  /** Page number (starting with 1). Each page has a fixed size of 50 items per page. */
  currentpage: number;
  /** ID of the group. */
  groupId: string;
}


export interface ApproveAllPendingParams {
  /** ID of the group. */
  groupId: string;
}


export interface DenyAllPendingParams {
  /** ID of the group. */
  groupId: string;
}


export interface ApprovePendingForListParams {
  /** ID of the group. */
  groupId: string;
}


export interface ApprovePendingParams {
  /** ID of the group. */
  groupId: string;
  /** The membership id being approved. */
  membershipId: string;
  /** Membership type of the supplied membership ID. */
  membershipType: BungieMembershipType;
}


export interface DenyPendingForListParams {
  /** ID of the group. */
  groupId: string;
}


export interface GetGroupsForMemberParams {
  /** Filter apply to list of joined groups. */
  filter: GroupsForMemberFilter;
  /** Type of group the supplied member founded. */
  groupType: GroupType;
  /** Membership ID to for which to find founded groups. */
  membershipId: string;
  /** Membership type of the supplied membership ID. */
  membershipType: BungieMembershipType;
}


export interface RecoverGroupForFounderParams {
  /** Type of group the supplied member founded. */
  groupType: GroupType;
  /** Membership ID to for which to find founded groups. */
  membershipId: string;
  /** Membership type of the supplied membership ID. */
  membershipType: BungieMembershipType;
}


export interface GetPotentialGroupsForMemberParams {
  /** Filter apply to list of potential joined groups. */
  filter: GroupPotentialMemberStatus;
  /** Type of group the supplied member applied. */
  groupType: GroupType;
  /** Membership ID to for which to find applied groups. */
  membershipId: string;
  /** Membership type of the supplied membership ID. */
  membershipType: BungieMembershipType;
}


export interface IndividualGroupInviteParams {
  /** ID of the group you would like to join. */
  groupId: string;
  /** Membership id of the account being invited. */
  membershipId: string;
  /** MembershipType of the account being invited. */
  membershipType: BungieMembershipType;
}


export interface IndividualGroupInviteCancelParams {
  /** ID of the group you would like to join. */
  groupId: string;
  /** Membership id of the account being cancelled. */
  membershipId: string;
  /** MembershipType of the account being cancelled. */
  membershipType: BungieMembershipType;
}


@Bean("agComponentUtils")
export class AgComponentUtils {
    @Autowired("componentMetadataProvider")
    private componentMetadataProvider:ComponentMetadataProvider;

    public adaptFunction <A extends IComponent<any> & B, B>(
        propertyName:string,
        hardcodedJsFunction: AgGridComponentFunctionInput,
        type:ComponentType,
        source:ComponentSource
    ):ResolvedComponent<A,B>{
        if (hardcodedJsFunction == null) return {
            component: null,
            type: type,
            source: source
        };

        let metadata:ComponentMetadata = this.componentMetadataProvider.retrieve(propertyName);
        if (metadata && metadata.functionAdapter){
            return {
                type: type,
                component: <{new(): A}>metadata.functionAdapter(hardcodedJsFunction),
                source: source
            }
        }
        console.error(`It seems like you are providing a function as a component: ${hardcodedJsFunction}, but this component: [${propertyName}] doesnt accept functions`)
        return null;
    }

    public adaptCellRendererFunction (callback:AgGridComponentFunctionInput):{new(): IComponent<any>}{
        class Adapter implements ICellRendererComp{
            private params: ICellRendererParams;

            refresh(params: any): boolean {
                return false;
            }

            getGui(): HTMLElement {
                let callbackResult: string | HTMLElement = callback(this.params);
                if (typeof callbackResult != 'string') return callbackResult;

                return _.loadTemplate('<span>' + callbackResult + '</span>');
            }

            init?(params: ICellRendererParams): void {
                this.params = params;
            }

        }
        return Adapter;
    }

    public doesImplementIComponent(candidate: AgGridRegisteredComponentInput<IComponent<any>>): boolean {
        if (!candidate) return false;
        return (<any>candidate).prototype && 'getGui' in (<any>candidate).prototype;
    }
}


class Adapter implements ICellRendererComp{
            private params: ICellRendererParams;

            refresh(params: any): boolean {
                return false;
            }

            getGui(): HTMLElement {
                let callbackResult: string | HTMLElement = callback(this.params);
                if (typeof callbackResult != 'string') return callbackResult;

                return _.loadTemplate('<span>' + callbackResult + '</span>');
            }

            init?(params: ICellRendererParams): void {
                this.params = params;
            }

        }


public adaptFunction <A extends IComponent<any> & B, B>(
        propertyName:string,
        hardcodedJsFunction: AgGridComponentFunctionInput,
        type:ComponentType,
        source:ComponentSource
    ):ResolvedComponent<A,B>{
        if (hardcodedJsFunction == null) return {
            component: null,
            type: type,
            source: source
        };

        let metadata:ComponentMetadata = this.componentMetadataProvider.retrieve(propertyName);
        if (metadata && metadata.functionAdapter){
            return {
                type: type,
                component: <{new(): A}>metadata.functionAdapter(hardcodedJsFunction),
                source: source
            }
        }
        console.error(`It seems like you are providing a function as a component: ${hardcodedJsFunction}, but this component: [${propertyName}] doesnt accept functions`)
        return null;
    }


public adaptCellRendererFunction (callback:AgGridComponentFunctionInput):{new(): IComponent<any>}{
        class Adapter implements ICellRendererComp{
            private params: ICellRendererParams;

            refresh(params: any): boolean {
                return false;
            }

            getGui(): HTMLElement {
                let callbackResult: string | HTMLElement = callback(this.params);
                if (typeof callbackResult != 'string') return callbackResult;

                return _.loadTemplate('<span>' + callbackResult + '</span>');
            }

            init?(params: ICellRendererParams): void {
                this.params = params;
            }

        }
        return Adapter;
    }


refresh(params: any): boolean {
                return false;
            }


getGui(): HTMLElement {
                let callbackResult: string | HTMLElement = callback(this.params);
                if (typeof callbackResult != 'string') return callbackResult;

                return _.loadTemplate('<span>' + callbackResult + '</span>');
            }


init?(params: ICellRendererParams): void {
                this.params = params;
            }


public doesImplementIComponent(candidate: AgGridRegisteredComponentInput<IComponent<any>>): boolean {
        if (!candidate) return false;
        return (<any>candidate).prototype && 'getGui' in (<any>candidate).prototype;
    }


() => {
  const classes = useStyles();
  const { t } = useTranslation();
  const projectID = getProjectID();
  const userRole = getProjectRole();
  const workflowAction = useActions(WorkflowActions);
  const template = useActions(TemplateSelectionActions);
  const workflowTabValue = useSelector(
    (state: RootState) => state.tabNumber.workflows
  );
  const tabs = useActions(TabActions);

  const theme = useTheme();

  const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
    tabs.changeWorkflowsTabs(newValue);
  };

  const handleScheduleWorkflow = () => {
    workflowAction.setWorkflowDetails({
      isCustomWorkflow: false,
      customWorkflows: [],
    });
    template.selectTemplate({ selectedTemplateID: 0, isDisable: true });
    history.push({
      pathname: '/create-workflow',
      search: `?projectID=${projectID}&projectRole=${userRole}`,
    });
  };

  return (
    <Scaffold>

          <Typography variant="h3">Chaos Workflows</Typography>

            <ButtonFilled onClick={handleScheduleWorkflow}>
              {t('workflows.scheduleAWorkflow')}
            </ButtonFilled>

      <AppBar position="static" color="default" className={classes.appBar}>
        <Tabs
          value={workflowTabValue}
          onChange={handleChange}
          TabIndicatorProps={{
            style: {
              backgroundColor: theme.palette.highlight,
            },
          }}


(state: RootState) => state.tabNumber.workflows


(event: React.ChangeEvent<{}>, newValue: number) => {
    tabs.changeWorkflowsTabs(newValue);
  }


() => {
    workflowAction.setWorkflowDetails({
      isCustomWorkflow: false,
      customWorkflows: [],
    });
    template.selectTemplate({ selectedTemplateID: 0, isDisable: true });
    history.push({
      pathname: '/create-workflow',
      search: `?projectID=${projectID}&projectRole=${userRole}`,
    });
  }


t('workflows.scheduleAWorkflow')


key => !('withEditor' in key) || key.withEditor === editorOpen


({ id, arrow, label, command, arrowLast }) => {
				const div = dom.append(this._overlay, $(`.key.${id}`));
				if (arrow && !arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
				dom.append(div, $('span.label')).textContent = label;
				if (command) {
					const shortcut = this.keybindingService.lookupKeybinding(command);
					if (shortcut) {
						dom.append(div, $('span.shortcut')).textContent = shortcut.getLabel();
					}
				}
				if (arrow && arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
			}


(theme, collector) => {
	const key = theme.getColor(foreground);
	if (key) {
		collector.addRule(`.monaco-workbench > .welcomeOverlay > .key { color: ${key}; }`);
	}
	const backgroundColor = Color.fromHex(theme.type === 'light' ? '#FFFFFF85' : '#00000085');
	if (backgroundColor) {
		collector.addRule(`.monaco-workbench > .welcomeOverlay { background: ${backgroundColor}; }`);
	}
	const shortcut = theme.getColor(textPreformatForeground);
	if (shortcut) {
		collector.addRule(`.monaco-workbench > .welcomeOverlay > .key > .shortcut { color: ${shortcut}; }`);
	}
}


export class WelcomeOverlayAction extends Action {

	public static readonly ID = 'workbench.action.showInterfaceOverview';
	public static readonly LABEL = localize('welcomeOverlay', "User Interface Overview");

	constructor(
		id: string,
		label: string,
		@IInstantiationService private readonly instantiationService: IInstantiationService
	) {
		super(id, label);
	}

	public run(): Promise<void> {
		if (!welcomeOverlay) {
			welcomeOverlay = this.instantiationService.createInstance(WelcomeOverlay);
		}
		welcomeOverlay.show();
		return Promise.resolve();
	}
}


export class HideWelcomeOverlayAction extends Action {

	public static readonly ID = 'workbench.action.hideInterfaceOverview';
	public static readonly LABEL = localize('hideWelcomeOverlay', "Hide Interface Overview");

	constructor(
		id: string,
		label: string
	) {
		super(id, label);
	}

	public run(): Promise<void> {
		if (welcomeOverlay) {
			welcomeOverlay.hide();
		}
		return Promise.resolve();
	}
}


class WelcomeOverlay extends Disposable {

	private _overlayVisible: IContextKey<boolean>;
	private _overlay!: HTMLElement;

	constructor(
		@ILayoutService private readonly layoutService: ILayoutService,
		@IEditorService private readonly editorService: IEditorService,
		@ICommandService private readonly commandService: ICommandService,
		@IContextKeyService private readonly _contextKeyService: IContextKeyService,
		@IKeybindingService private readonly keybindingService: IKeybindingService
	) {
		super();
		this._overlayVisible = OVERLAY_VISIBLE.bindTo(this._contextKeyService);
		this.create();
	}

	private create(): void {
		const offset = this.layoutService.offset?.top ?? 0;
		this._overlay = dom.append(this.layoutService.container, $('.welcomeOverlay'));
		this._overlay.style.top = `${offset}px`;
		this._overlay.style.height = `calc(100% - ${offset}px)`;
		this._overlay.style.display = 'none';
		this._overlay.tabIndex = -1;

		this._register(dom.addStandardDisposableListener(this._overlay, 'click', () => this.hide()));
		this.commandService.onWillExecuteCommand(() => this.hide());

		dom.append(this._overlay, $('.commandPalettePlaceholder'));

		const editorOpen = !!this.editorService.visibleEditors.length;
		keys.filter(key => !('withEditor' in key) || key.withEditor === editorOpen)
			.forEach(({ id, arrow, label, command, arrowLast }) => {
				const div = dom.append(this._overlay, $(`.key.${id}`));
				if (arrow && !arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
				dom.append(div, $('span.label')).textContent = label;
				if (command) {
					const shortcut = this.keybindingService.lookupKeybinding(command);
					if (shortcut) {
						dom.append(div, $('span.shortcut')).textContent = shortcut.getLabel();
					}
				}
				if (arrow && arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
			});
	}

	public show() {
		if (this._overlay.style.display !== 'block') {
			this._overlay.style.display = 'block';
			const workbench = document.querySelector('.monaco-workbench') as HTMLElement;
			dom.addClass(workbench, 'blur-background');
			this._overlayVisible.set(true);
			this.updateProblemsKey();
			this.updateActivityBarKeys();
			this._overlay.focus();
		}
	}

	private updateProblemsKey() {
		const problems = document.querySelector(`div[id="workbench.parts.statusbar"] .statusbar-item.left ${Codicon.warning.cssSelector}`);
		const key = this._overlay.querySelector('.key.problems') as HTMLElement;
		if (problems instanceof HTMLElement) {
			const target = problems.getBoundingClientRect();
			const bounds = this._overlay.getBoundingClientRect();
			const bottom = bounds.bottom - target.top + 3;
			const left = (target.left + target.right) / 2 - bounds.left;
			key.style.bottom = bottom + 'px';
			key.style.left = left + 'px';
		} else {
			key.style.bottom = '';
			key.style.left = '';
		}
	}

	private updateActivityBarKeys() {
		const ids = ['explorer', 'search', 'git', 'debug', 'extensions'];
		const activityBar = document.querySelector('.activitybar .composite-bar');
		if (activityBar instanceof HTMLElement) {
			const target = activityBar.getBoundingClientRect();
			const bounds = this._overlay.getBoundingClientRect();
			for (let i = 0; i < ids.length; i++) {
				const key = this._overlay.querySelector(`.key.${ids[i]}`) as HTMLElement;
				const top = target.top - bounds.top + 50 * i + 13;
				key.style.top = top + 'px';
			}
		} else {
			for (let i = 0; i < ids.length; i++) {
				const key = this._overlay.querySelector(`.key.${ids[i]}`) as HTMLElement;
				key.style.top = '';
			}
		}
	}

	public hide() {
		if (this._overlay.style.display !== 'none') {
			this._overlay.style.display = 'none';
			const workbench = document.querySelector('.monaco-workbench') as HTMLElement;
			dom.removeClass(workbench, 'blur-background');
			this._overlayVisible.reset();
		}
	}
}


interface Key {
	id: string;
	arrow?: string;
	label: string;
	command?: string;
	arrowLast?: boolean;
	withEditor?: boolean;
}


public run(): Promise<void> {
		if (!welcomeOverlay) {
			welcomeOverlay = this.instantiationService.createInstance(WelcomeOverlay);
		}
		welcomeOverlay.show();
		return Promise.resolve();
	}


public run(): Promise<void> {
		if (welcomeOverlay) {
			welcomeOverlay.hide();
		}
		return Promise.resolve();
	}


private create(): void {
		const offset = this.layoutService.offset?.top ?? 0;
		this._overlay = dom.append(this.layoutService.container, $('.welcomeOverlay'));
		this._overlay.style.top = `${offset}px`;
		this._overlay.style.height = `calc(100% - ${offset}px)`;
		this._overlay.style.display = 'none';
		this._overlay.tabIndex = -1;

		this._register(dom.addStandardDisposableListener(this._overlay, 'click', () => this.hide()));
		this.commandService.onWillExecuteCommand(() => this.hide());

		dom.append(this._overlay, $('.commandPalettePlaceholder'));

		const editorOpen = !!this.editorService.visibleEditors.length;
		keys.filter(key => !('withEditor' in key) || key.withEditor === editorOpen)
			.forEach(({ id, arrow, label, command, arrowLast }) => {
				const div = dom.append(this._overlay, $(`.key.${id}`));
				if (arrow && !arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
				dom.append(div, $('span.label')).textContent = label;
				if (command) {
					const shortcut = this.keybindingService.lookupKeybinding(command);
					if (shortcut) {
						dom.append(div, $('span.shortcut')).textContent = shortcut.getLabel();
					}
				}
				if (arrow && arrowLast) {
					dom.append(div, $('span.arrow')).innerHTML = arrow;
				}
			});
	}


public show() {
		if (this._overlay.style.display !== 'block') {
			this._overlay.style.display = 'block';
			const workbench = document.querySelector('.monaco-workbench') as HTMLElement;
			dom.addClass(workbench, 'blur-background');
			this._overlayVisible.set(true);
			this.updateProblemsKey();
			this.updateActivityBarKeys();
			this._overlay.focus();
		}
	}


private updateProblemsKey() {
		const problems = document.querySelector(`div[id="workbench.parts.statusbar"] .statusbar-item.left ${Codicon.warning.cssSelector}`);
		const key = this._overlay.querySelector('.key.problems') as HTMLElement;
		if (problems instanceof HTMLElement) {
			const target = problems.getBoundingClientRect();
			const bounds = this._overlay.getBoundingClientRect();
			const bottom = bounds.bottom - target.top + 3;
			const left = (target.left + target.right) / 2 - bounds.left;
			key.style.bottom = bottom + 'px';
			key.style.left = left + 'px';
		} else {
			key.style.bottom = '';
			key.style.left = '';
		}
	}


private updateActivityBarKeys() {
		const ids = ['explorer', 'search', 'git', 'debug', 'extensions'];
		const activityBar = document.querySelector('.activitybar .composite-bar');
		if (activityBar instanceof HTMLElement) {
			const target = activityBar.getBoundingClientRect();
			const bounds = this._overlay.getBoundingClientRect();
			for (let i = 0; i < ids.length; i++) {
				const key = this._overlay.querySelector(`.key.${ids[i]}`) as HTMLElement;
				const top = target.top - bounds.top + 50 * i + 13;
				key.style.top = top + 'px';
			}
		} else {
			for (let i = 0; i < ids.length; i++) {
				const key = this._overlay.querySelector(`.key.${ids[i]}`) as HTMLElement;
				key.style.top = '';
			}
		}
	}


public hide() {
		if (this._overlay.style.display !== 'none') {
			this._overlay.style.display = 'none';
			const workbench = document.querySelector('.monaco-workbench') as HTMLElement;
			dom.removeClass(workbench, 'blur-background');
			this._overlayVisible.reset();
		}
	}


() => {
    const context = new InlineContext(
        ToNodePath(`
        {
            'use foo';
            console.log("previous");
        }
    `)
    );
    expect(context.GetDSLName()).toEqual("foo");
}


() => {
    const context = new InlineContext(
        ToNodePath(`
        {
            console.log("previous");
        }
    `)
    );
    expect(context.GetDSLName()).toEqual("");
}


() => {
    //
    const context = new InlineContext(
        ToNodePath(`
        {
            'use foo';
            console.log("previous");
        }
    `)
    );

    //
    const expected = ToAst<Array<Statement>>(`
        'use foo';
        console.log("previous");
    `);
    expect(context.ToStatements()).toEqual(expected);
}


() => {
	suite('event ordering', () => {
		let adapter: MockDebugAdapter;
		let output: string[];
		setup(() => {
			adapter = new MockDebugAdapter();
			output = [];
			adapter.onEvent(ev => {
				output.push((ev as DebugProtocol.OutputEvent).body.output);
				Promise.resolve().then(() => output.push('--end microtask--'));
			});
		});

		const evaluate = async (expression: string) => {
			await new Promise(resolve => adapter.sendRequest('evaluate', { expression }, resolve));
			output.push(`=${expression}`);
			Promise.resolve().then(() => output.push('--end microtask--'));
		};

		test('inserts task boundary before response', async () => {
			await evaluate('before.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['before.foo', '--end microtask--', '=before.foo', '--end microtask--']);
		});

		test('inserts task boundary after response', async () => {
			await evaluate('after.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['=after.foo', '--end microtask--', 'after.foo', '--end microtask--']);
		});

		test('does not insert boundaries between events', async () => {
			adapter.sendEventBody('output', { output: 'a' });
			adapter.sendEventBody('output', { output: 'b' });
			adapter.sendEventBody('output', { output: 'c' });
			await timeout(0);

			assert.deepStrictEqual(output, ['a', 'b', 'c', '--end microtask--', '--end microtask--', '--end microtask--']);
		});
	});
}


() => {
		let adapter: MockDebugAdapter;
		let output: string[];
		setup(() => {
			adapter = new MockDebugAdapter();
			output = [];
			adapter.onEvent(ev => {
				output.push((ev as DebugProtocol.OutputEvent).body.output);
				Promise.resolve().then(() => output.push('--end microtask--'));
			});
		});

		const evaluate = async (expression: string) => {
			await new Promise(resolve => adapter.sendRequest('evaluate', { expression }, resolve));
			output.push(`=${expression}`);
			Promise.resolve().then(() => output.push('--end microtask--'));
		};

		test('inserts task boundary before response', async () => {
			await evaluate('before.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['before.foo', '--end microtask--', '=before.foo', '--end microtask--']);
		});

		test('inserts task boundary after response', async () => {
			await evaluate('after.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['=after.foo', '--end microtask--', 'after.foo', '--end microtask--']);
		});

		test('does not insert boundaries between events', async () => {
			adapter.sendEventBody('output', { output: 'a' });
			adapter.sendEventBody('output', { output: 'b' });
			adapter.sendEventBody('output', { output: 'c' });
			await timeout(0);

			assert.deepStrictEqual(output, ['a', 'b', 'c', '--end microtask--', '--end microtask--', '--end microtask--']);
		});
	}


() => {
			adapter = new MockDebugAdapter();
			output = [];
			adapter.onEvent(ev => {
				output.push((ev as DebugProtocol.OutputEvent).body.output);
				Promise.resolve().then(() => output.push('--end microtask--'));
			});
		}


ev => {
				output.push((ev as DebugProtocol.OutputEvent).body.output);
				Promise.resolve().then(() => output.push('--end microtask--'));
			}


() => output.push('--end microtask--')


async (expression: string) => {
			await new Promise(resolve => adapter.sendRequest('evaluate', { expression }, resolve));
			output.push(`=${expression}`);
			Promise.resolve().then(() => output.push('--end microtask--'));
		}


resolve => adapter.sendRequest('evaluate', { expression }, resolve)


async () => {
			await evaluate('before.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['before.foo', '--end microtask--', '=before.foo', '--end microtask--']);
		}


async () => {
			await evaluate('after.foo');
			await timeout(0);

			assert.deepStrictEqual(output, ['=after.foo', '--end microtask--', 'after.foo', '--end microtask--']);
		}


async () => {
			adapter.sendEventBody('output', { output: 'a' });
			adapter.sendEventBody('output', { output: 'b' });
			adapter.sendEventBody('output', { output: 'c' });
			await timeout(0);

			assert.deepStrictEqual(output, ['a', 'b', 'c', '--end microtask--', '--end microtask--', '--end microtask--']);
		}


/**
 * Initialize listeners that help with accessibility
 * @param panel the table panel
 * @param gridBody element containing the grid
 * @param tableOptions table options object
 */
export function initAccessibilityListeners(panel: HTMLElement, gridBody: HTMLElement, tableOptions: any) {
    onFocusOutOfView = (event: any) => {
        scrollIntoView(event, panel);
    }

    onGridTab = (event: any) => {
        tabToGrid(event, tableOptions, panel);
    }

    panel.addEventListener('focus', onFocusOutOfView, true);

    gridBody.addEventListener('focus', onGridTab, false);
    // Don't link last filter to first cell if using the mouse to focus grid
    gridBody.addEventListener('mousedown', onMousedown);
    gridBody.addEventListener('mouseup', onMouseup);
}


/**
 * Remove all accessibility listeners from the table
 * @param panel the table panel
 * @param gridBody element containing the grid
 */
export function removeAccessibilityListeners(panel:HTMLElement, gridBody: HTMLElement) {
    panel.removeEventListener('focus', onFocusOutOfView, true);
    gridBody.removeEventListener('focus', onGridTab, true);
    gridBody.removeEventListener('mousedown', onMousedown);
    gridBody.removeEventListener('mouseup', onMouseup);
}


/**
 * Helper function to handle the mousedown event
 * @param event event handler param
 */
function onMousedown(event: any) {
    mousedown = true;
}


/**
 * Helper function to handle the mouseup event
 * @param event event handler param
 */
function onMouseup(event: any) {
    mousedown = false;
}


/**
 * Function to ensure focused column filter is scrolled into view
 * @param element filter being focused
 * @param panel table panel with scrollbar
 */
function scrollIntoView(event: any, panel: HTMLElement) {
    let element = event.target;
    let container = <HTMLElement>panel.getElementsByClassName('ag-body-viewport')[0];
    const { elementRect, containerRect, offset } = getOffset(element, container);
    let offsetDelta: number = 0;
    if (offset.left < 0) {
        offsetDelta = offset.left;
    } else if (offset.left + elementRect.width > containerRect.width) {
        offsetDelta = offset.left + elementRect.width - containerRect.width;
    }

    if (offsetDelta !== 0) {
        container.scrollLeft += offsetDelta;
    }

    function getOffset(element: HTMLElement, container: HTMLElement): ElementOffset {
        const elementRect = element.getBoundingClientRect();
        const containerRect = container.getBoundingClientRect();

        return {
            elementRect,
            containerRect,
            offset: {
                top: elementRect.top - containerRect.top,
                left: elementRect.left - containerRect.left
            }
        };
    }
}


function getOffset(element: HTMLElement, container: HTMLElement): ElementOffset {
        const elementRect = element.getBoundingClientRect();
        const containerRect = container.getBoundingClientRect();

        return {
            elementRect,
            containerRect,
            offset: {
                top: elementRect.top - containerRect.top,
                left: elementRect.left - containerRect.left
            }
        };
    }


/**
 * Function to help enter and exit grid using the keyboard
 * @param element grid being focused
 * @param tableOptions provide access to table api
 * @param lastFilter final filter input before entering the grid
 */
function tabToGrid (event: any, tableOptions: any, panel: HTMLElement) {
    if (!mousedown) {
        if (event.relatedTarget !== null && event.relatedTarget.tagName === 'INPUT') {
            // scrolls to the first row
            tableOptions.api.ensureIndexVisible(0);

            // scrolls to the first column
            let firstCol = tableOptions.columnApi.getAllDisplayedColumns()[0];
            tableOptions.api.ensureColumnVisible(firstCol);

            // let firstCell = <HTMLElement>panel.getElementsByClassName('ag-cell')[0];

            // sets focus into the first grid cell
            // setTimeout(() => tableOptions.api.setFocusedCell(0, firstCol), 10);
            tableOptions.api.setFocusedCell(0, firstCol);

        } else {
            let headers = panel.getElementsByClassName('ag-header-cell');
            let filters = headers[headers.length - 1].getElementsByTagName('INPUT');
            let lastFilter = <HTMLElement>filters[filters.length - 1]; // final filter before grid
            lastFilter.focus();
        }
    }
}


(event: any) => {
        scrollIntoView(event, panel);
    }


(event: any) => {
        tabToGrid(event, tableOptions, panel);
    }


interface ElementOffset {
    elementRect: ClientRect|DOMRect;
    containerRect: ClientRect|DOMRect;
    offset: Offset;
}


interface Offset {
    top: number;
    left: number;
}


() => {
  const dispatch = useDispatch();

  const description = useSelector((state) => state.registerRoom.description);

  const onChangeDescription = (event: React.ChangeEvent<HTMLTextAreaElement>) =>
    dispatch(registerRoomActions.setDescription(event.target.value));
  return (
    <Container>

게스트에게 숙소에 대해 설명해 주세요.

8단계

        숙소의 장점, 특별한 편의 시설과 주변 지역의 매력을 소개해 주세요.

        <Textarea value={description} onChange={onChangeDescription} />

      <RegisterRoomFooter
        prevHref="/room/register/photo"
        nextHref="/room/register/title"
      />
    </Container>


(state) => state.registerRoom.description


(event: React.ChangeEvent<HTMLTextAreaElement>) =>
    dispatch(registerRoomActions.setDescription(event.target.value))


export class Test {
  public BeforeEUMK: boolean;
  public ForEUMK: boolean;
  public ForNN: boolean;
  public ForSelfStudy: boolean;
  public IsNecessary: boolean;
  public SetTimeForAllTest: boolean;
  public IsNew: boolean;
  public Unlocked: boolean;
  public CountOfQuestions: number;
  public SubjectId: number;
  public TimeForCompleting: number;
  public Id: number;
  public TestNumber: number;
  public Description: string;
  public Title: string;
  public Data: any;
  public Questions: any;
  public Subject: any;
  public TestUnlocks: any;
  public Percent: number;
  public Points: number;
  public Action: any;
  public HasQuestions: boolean;
  public Number: number;
  public tooltipTitle: string;
}


export enum TestType {
  BeforeEUMK,
  ForEUMK,
  ForNN,
  ForSelfStudy,
  Control
}


() => {
  it("should create an ASSIGN_DOCUMENT_ID action", () => {
    const expected: actionTypes.ASSIGN_DOCUMENT_ID = {
      type: "ASSIGN_DOCUMENT_ID",
      payload: {
        documentId: "document1",
        baseUrl: "http://some.url"
      }
    };

    expect(actionCreators.assignDocumentId("document1", "http://some.url")).toEqual(expected);
  });
}


() => {
    const expected: actionTypes.ASSIGN_DOCUMENT_ID = {
      type: "ASSIGN_DOCUMENT_ID",
      payload: {
        documentId: "document1",
        baseUrl: "http://some.url"
      }
    };

    expect(actionCreators.assignDocumentId("document1", "http://some.url")).toEqual(expected);
  }


/** Class representing a MeshNetwork. */
export class MeshNetwork {
  private readonly client: ServiceFabricClientContext;

  /**
   * Create a MeshNetwork.
   * @param {ServiceFabricClientContext} client Reference to the service client.
   */
  constructor(client: ServiceFabricClientContext) {
    this.client = client;
  }

  /**
   * Creates a Network resource with the specified name, description and properties. If Network
   * resource with the same name exists, then it is updated with the specified description and
   * properties. Network resource provides connectivity between application services.
   * @summary Creates or updates a Network resource.
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkCreateOrUpdateResponse>
   */
  createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkCreateOrUpdateResponse>;
  /**
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param callback The callback
   */
  createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;
  /**
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param options The optional parameters
   * @param callback The callback
   */
  createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;
  createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.NetworkResourceDescription>, callback?: msRest.ServiceCallback<Models.NetworkResourceDescription>): Promise<Models.MeshNetworkCreateOrUpdateResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        networkResourceDescription,
        options
      },
      createOrUpdateOperationSpec,
      callback) as Promise<Models.MeshNetworkCreateOrUpdateResponse>;
  }

  /**
   * Gets the information about the Network resource with the given name. The information include the
   * description and other properties of the Network.
   * @summary Gets the Network resource with the given name.
   * @param networkResourceName The identity of the network.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkGetResponse>
   */
  get(networkResourceName: string, options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkGetResponse>;
  /**
   * @param networkResourceName The identity of the network.
   * @param callback The callback
   */
  get(networkResourceName: string, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;
  /**
   * @param networkResourceName The identity of the network.
   * @param options The optional parameters
   * @param callback The callback
   */
  get(networkResourceName: string, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;
  get(networkResourceName: string, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.NetworkResourceDescription>, callback?: msRest.ServiceCallback<Models.NetworkResourceDescription>): Promise<Models.MeshNetworkGetResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        options
      },
      getOperationSpec,
      callback) as Promise<Models.MeshNetworkGetResponse>;
  }

  /**
   * Deletes the Network resource identified by the name.
   * @summary Deletes the Network resource.
   * @param networkResourceName The identity of the network.
   * @param [options] The optional parameters
   * @returns Promise<msRest.RestResponse>
   */
  deleteMethod(networkResourceName: string, options?: msRest.RequestOptionsBase): Promise<msRest.RestResponse>;
  /**
   * @param networkResourceName The identity of the network.
   * @param callback The callback
   */
  deleteMethod(networkResourceName: string, callback: msRest.ServiceCallback<void>): void;
  /**
   * @param networkResourceName The identity of the network.
   * @param options The optional parameters
   * @param callback The callback
   */
  deleteMethod(networkResourceName: string, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<void>): void;
  deleteMethod(networkResourceName: string, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<void>, callback?: msRest.ServiceCallback<void>): Promise<msRest.RestResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        options
      },
      deleteMethodOperationSpec,
      callback);
  }

  /**
   * Gets the information about all network resources in a given resource group. The information
   * include the description and other properties of the Network.
   * @summary Lists all the network resources.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkListResponse>
   */
  list(options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkListResponse>;
  /**
   * @param callback The callback
   */
  list(callback: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): void;
  /**
   * @param options The optional parameters
   * @param callback The callback
   */
  list(options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): void;
  list(options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>, callback?: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): Promise<Models.MeshNetworkListResponse> {
    return this.client.sendOperationRequest(
      {
        options
      },
      listOperationSpec,
      callback) as Promise<Models.MeshNetworkListResponse>;
  }
}


/**
   * Creates a Network resource with the specified name, description and properties. If Network
   * resource with the same name exists, then it is updated with the specified description and
   * properties. Network resource provides connectivity between application services.
   * @summary Creates or updates a Network resource.
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkCreateOrUpdateResponse>
   */
createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkCreateOrUpdateResponse>;


/**
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param callback The callback
   */
createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;


/**
   * @param networkResourceName The identity of the network.
   * @param networkResourceDescription Description for creating a Network resource.
   * @param options The optional parameters
   * @param callback The callback
   */
createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;


createOrUpdate(networkResourceName: string, networkResourceDescription: Models.NetworkResourceDescription, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.NetworkResourceDescription>, callback?: msRest.ServiceCallback<Models.NetworkResourceDescription>): Promise<Models.MeshNetworkCreateOrUpdateResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        networkResourceDescription,
        options
      },
      createOrUpdateOperationSpec,
      callback) as Promise<Models.MeshNetworkCreateOrUpdateResponse>;
  }


/**
   * Gets the information about the Network resource with the given name. The information include the
   * description and other properties of the Network.
   * @summary Gets the Network resource with the given name.
   * @param networkResourceName The identity of the network.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkGetResponse>
   */
get(networkResourceName: string, options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkGetResponse>;


/**
   * @param networkResourceName The identity of the network.
   * @param callback The callback
   */
get(networkResourceName: string, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;


/**
   * @param networkResourceName The identity of the network.
   * @param options The optional parameters
   * @param callback The callback
   */
get(networkResourceName: string, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.NetworkResourceDescription>): void;


get(networkResourceName: string, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.NetworkResourceDescription>, callback?: msRest.ServiceCallback<Models.NetworkResourceDescription>): Promise<Models.MeshNetworkGetResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        options
      },
      getOperationSpec,
      callback) as Promise<Models.MeshNetworkGetResponse>;
  }


/**
   * Deletes the Network resource identified by the name.
   * @summary Deletes the Network resource.
   * @param networkResourceName The identity of the network.
   * @param [options] The optional parameters
   * @returns Promise<msRest.RestResponse>
   */
deleteMethod(networkResourceName: string, options?: msRest.RequestOptionsBase): Promise<msRest.RestResponse>;


/**
   * @param networkResourceName The identity of the network.
   * @param callback The callback
   */
deleteMethod(networkResourceName: string, callback: msRest.ServiceCallback<void>): void;


/**
   * @param networkResourceName The identity of the network.
   * @param options The optional parameters
   * @param callback The callback
   */
deleteMethod(networkResourceName: string, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<void>): void;


deleteMethod(networkResourceName: string, options?: msRest.RequestOptionsBase | msRest.ServiceCallback<void>, callback?: msRest.ServiceCallback<void>): Promise<msRest.RestResponse> {
    return this.client.sendOperationRequest(
      {
        networkResourceName,
        options
      },
      deleteMethodOperationSpec,
      callback);
  }


/**
   * Gets the information about all network resources in a given resource group. The information
   * include the description and other properties of the Network.
   * @summary Lists all the network resources.
   * @param [options] The optional parameters
   * @returns Promise<Models.MeshNetworkListResponse>
   */
list(options?: msRest.RequestOptionsBase): Promise<Models.MeshNetworkListResponse>;


/**
   * @param callback The callback
   */
list(callback: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): void;


/**
   * @param options The optional parameters
   * @param callback The callback
   */
list(options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): void;


list(options?: msRest.RequestOptionsBase | msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>, callback?: msRest.ServiceCallback<Models.PagedNetworkResourceDescriptionList>): Promise<Models.MeshNetworkListResponse> {
    return this.client.sendOperationRequest(
      {
        options
      },
      listOperationSpec,
      callback) as Promise<Models.MeshNetworkListResponse>;
  }


() => DatetimePickerComponent


(_: D) => {}


(input) => input in changes


() => {
            this._setInput(this.date);
            this._calculateTimeOptions();
            this._changeDetRef.detectChanges();
        }


/** @hidden */
ngOnChanges(changes): void {
        if (changes.date) {
            this._setTempDateTime();
        }

        if (['displayHours', 'displayMinutes', 'displaySeconds', 'meridian'].some((input) => input in changes)) {
            this._calculateTimeOptions();
        }
    }


/** @hidden */
ngOnInit(): void {
        if (this.date) {
            this._setTempDateTime();
        }

        this._calculateTimeOptions();

        this._dateTimeAdapter.localeChanges.pipe(takeUntil(this._onDestroy$)).subscribe(() => {
            this._setInput(this.date);
            this._calculateTimeOptions();
            this._changeDetRef.detectChanges();
        });
    }


/** @hidden */
ngOnDestroy(): void {
        this._onDestroy$.next();
        this._onDestroy$.complete();
    }


/**
     * @hidden
     * Function that implements Validator Interface, adds validation support for forms
     */
validate(
        control: AbstractControl
    ): {
        [key: string]: any;
    } {
        return this.isCurrentModelValid() && !this._isInvalidDateInput
            ? null
            : {
                  dateValidation: {
                      valid: false
                  }
              };
    }


/** Toggles the popover. */
togglePopover(): void {
        this.onTouched();
        if (this.isOpen) {
            this.closePopover();
        } else {
            this.openPopover();
        }
    }


/**
     * Method that handle calendar active view change and throws event.
     */
handleCalendarActiveViewChange(activeView: FdCalendarView): void {
        this.activeViewChange.emit(activeView);
    }


/** Opens the popover. */
openPopover(): void {
        if (!this.isOpen && !this.disabled) {
            this.onTouched();
            this.isOpen = true;
            this.isOpenChange.emit(this.isOpen);
        }
    }


/** Closes the popover and refresh model */
closePopover(): void {
        if (this.isOpen) {
            this.handleInputChange(this._inputFieldDate);
            this.onClose.emit();
            this.isOpen = false;
            this.isOpenChange.emit(this.isOpen);
        }
    }


/** @hidden */
setInvalidDateInputHandler(isInvalid: boolean): void {
        this._isInvalidDateInput = isInvalid;
    }


/** @hidden */
registerOnChange(fn: (selected: any) => { void }): void {
        this.onChange = fn;
    }


/** @hidden */
setDisabledState(isDisabled: boolean): void {
        this.disabled = isDisabled;
        this._changeDetRef.detectChanges();
    }


/**
     * @hidden
     * Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms
     */
writeValue(selected: D): void {
        if (!this._dateTimeAdapter.isValid(selected)) {
            this._inputFieldDate = '';
            this._changeDetRef.detectChanges();
            return;
        }
        this.date = selected;
        this._setTempDateTime();
        if (this.isCurrentModelValid()) {
            this._refreshCurrentlyDisplayedCalendarDate(this.date);
            this._setInput(this.date);
        }
        this._changeDetRef.detectChanges();
    }


/**
     * @hidden
     * Method that is triggered by events from calendar component, when there is selected date changed.
     * If invalid time model is detected, it takes time model data from TimeComponent.
     */
handleDateChange(date: D): void {
        this._tempDate = date;
        if (!this.showFooter) {
            this.submit();
        }
    }


/**
     * @hidden
     * Method that is triggered by events from time component, when there is selected time changed
     */
handleTimeChange(time: D): void {
        this._tempTime = time;
        if (!this.showFooter) {
            this.submit();
        }
    }


/**
     * @hidden
     * Method that is triggered when 'OK' button is pressed.
     */
submit(): void {
        const currentDate = this._tempDate;
        const currentTime = this._tempTime;

        this.date = this._dateTimeAdapter.setTime(
            currentDate,
            this._dateTimeAdapter.getHours(currentTime),
            this._dateTimeAdapter.getMinutes(currentTime),
            this._dateTimeAdapter.getSeconds(currentTime)
        );

        this._isInvalidDateInput = !this.isCurrentModelValid();

        this._setInput(this.date);

        this.onChange(this.date);

        if (this.showFooter) {
            this.closePopover();
        }
    }


/**
     * @hidden
     * Function that is called when 'Cancel' button is pressed.
     */
cancel(): void {
        this._tempDate = this.date;
        this._tempTime = this.date;
        this.closePopover();
    }


/** @hidden */
focusArrowLeft(): void {
        if (this._elRef.nativeElement.querySelector('#' + this._calendarComponent.id + '-left-arrow')) {
            this._elRef.nativeElement.querySelector('#' + this._calendarComponent.id + '-left-arrow').focus();
        }
    }


/**
     * @hidden
     * Method, which is responsible for transforming string to datetime, depending on type or
     * validation the results are different. It also changes to state of isInvalidDateInput.
     */
handleInputChange(inputStr: string): void {
        const date = this._dateTimeAdapter.parse(inputStr, this._dateTimeFormats.parse.dateTimeInput);
        this._isInvalidDateInput = !this._isModelValid(date);

        if (!this._isInvalidDateInput) {
            this.date = date;
            this._setTempDateTime();
            this.onChange(date);
            this._refreshCurrentlyDisplayedCalendarDate(date);
        } else {
            this.onChange(this.date);
        }

        if (!inputStr && this.allowNull) {
            this._isInvalidDateInput = false;
            this.date = this._dateTimeAdapter.now();
            this._setTempDateTime();
            this._refreshCurrentlyDisplayedCalendarDate(this.date);
            this.onChange(null);
        } else if (!inputStr && !this.allowNull) {
            this._isInvalidDateInput = true;
        }
    }


/** Method that provides information if model selected date/dates have properly types and are valid */
public isCurrentModelValid(): boolean {
        return this._isModelValid(this.date);
    }


/** Method that provides information if FdDateTime passed as arg has properly types and is valid */
private _isModelValid(date: D): boolean {
        return this._dateTimeAdapter.isValid(date);
    }


private _setInput(dateTime: D): void {
        this._inputFieldDate = this._formatDateTime(dateTime);
        this._changeDetRef.detectChanges();
    }


/** @hidden */
private _refreshCurrentlyDisplayedCalendarDate(date: D): void {
        if (this._calendarComponent) {
            this._calendarComponent.setCurrentlyDisplayed(date);
        }
    }


/**
     * @hidden
     * Format date time entity.
     */
private _formatDateTime(dateTime: D): string {
        const formattedDate: string = this._dateTimeAdapter.format(
            dateTime,
            this._dateTimeFormats.display.dateTimeInput
        );
        return formattedDate || '';
    }


/** @hidden */
private _setTempDateTime(): void {
        this._tempDate = this.date;
        this._tempTime = this.date;
    }


/** @hidden */
private _calculateTimeOptions(): void {
        const format = this._dateTimeFormats.display.dateTimeInput;

        // default meridian option based on format option
        this._meridian =
            this.meridian != null ? this.meridian : this._dateTimeAdapter.isTimeFormatIncludesDayPeriod(format);

        // default seconds option based on format option
        this._displaySeconds =
            this.displaySeconds != null
                ? this.displaySeconds
                : this._dateTimeAdapter.isTimeFormatIncludesSeconds(format);

        // default minutes option based on format option
        this._displayMinutes =
            this.displayMinutes != null
                ? this.displayMinutes
                : this._dateTimeAdapter.isTimeFormatIncludesMinutes(format);

        // default hours option based on format option
        this._displayHours =
            this.displayHours != null ? this.displayHours : this._dateTimeAdapter.isTimeFormatIncludesHours(format);
    }


@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}


story => (
    <Screener
      steps={new Screener.Steps()
        .snapshot('default', { cropTo: '.testWrapper' })
        .hover('div.ms-ChoiceField:nth-of-type(1)')
        .snapshot('hover unselected', { cropTo: '.testWrapper' })
        .click('div.ms-ChoiceField:nth-of-type(1)')
        .snapshot('selected', { cropTo: '.testWrapper' })
        .click('div.ms-ChoiceField:nth-of-type(1)')
        .hover('div.ms-ChoiceField:nth-of-type(1)')
        .snapshot('hover selected', { cropTo: '.testWrapper' })
        .end()}
    >
      {story()}
    </Screener>


() =>
    // prettier-ignore
    <ChoiceGroup
      options


() => (
      <ChoiceGroup
        label="Pick one icon"


() => (
    <ChoiceGroup
      label="Pick one image"


story()


export default class GoStop extends React.Component<IconBaseProps, any> { }


declare function Eris(token: string, options: Eris.ClientOptions): Eris.Client;


class Base implements SimpleJSON {
    createdAt: number;
    id: string;
    constructor(id: string);
    static getCreatedAt(id: string): number;
    static getDiscordEpoch(id: string): number;
    inspect(): this;
    toString(): string;
    toJSON(props?: string[]): JSONCache;
  }


export class Bucket {
    interval: number;
    lastReset: number;
    lastSend: number;
    tokenLimit: number;
    tokens: number;
    constructor(tokenLimit: number, interval: number, options: { latencyRef: { latency: number }; reservedTokens: number });
    check(): void;
    queue(func: () => void, priority?: boolean): void;
  }


export class BrowserWebSocket extends EventEmitter {
    static CONNECTING: 0;
    static OPEN: 1;
    static CLOSING: 2;
    static CLOSED: 3;
    readyState: number;
    constructor(url: string);
    close(code?: number, reason?: string): void;
    removeEventListener(event: string | symbol, listener: (...args: any[]) => void): this;
    // @ts-ignore: DOM
    send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
    terminate(): void;
  }


export class BrowserWebSocketError extends Error {
    // @ts-ignore: DOM
    event: Event;
    // @ts-ignore: DOM
    constructor(message: string, event: Event);
  }


export class Call extends Base {
    channel: GroupChannel;
    createdAt: number;
    endedTimestamp: number | null;
    id: string;
    participants: string[];
    region: string | null;
    ringing: string[];
    unavailable: boolean;
    voiceStates: Collection<VoiceState>;
    constructor(data: BaseData, channel: GroupChannel);
  }


export class CategoryChannel extends GuildChannel {
    channels: Collection<Exclude<AnyGuildChannel, CategoryChannel>>;
    type: Constants["ChannelTypes"]["GUILD_CATEGORY"];
    edit(options: Omit<CreateChannelOptions, "permissionOverwrites" | "reason">, reason?: string): Promise<this>;
  }


export class Channel extends Base {
    client: Client;
    createdAt: number;
    id: string;
    mention: string;
    type: ChannelTypes;
    constructor(data: BaseData, client: Client);
    static from(data: BaseData, client: Client): AnyChannel;
  }


export class Collection<T extends { id: string | number }> extends Map<string | number, T> {
    baseObject: new (...args: any[]) => T;
    limit?: number;
    constructor(baseObject: new (...args: any[]) => T, limit?: number);
    add(obj: T, extra?: unknown, replace?: boolean): T;
    every(func: (i: T) => boolean): boolean;
    filter(func: (i: T) => boolean): T[];
    find(func: (i: T) => boolean): T | undefined;
    map<R>(func: (i: T) => R): R[];
    random(): T | undefined;
    reduce<U>(func: (accumulator: U, val: T) => U, initialValue?: U): U;
    remove(obj: T | Uncached): T | null;
    some(func: (i: T) => boolean): boolean;
    update(obj: T, extra?: unknown, replace?: boolean): T;
  }


export class Command implements CommandOptions, SimpleJSON {
    aliases: string[];
    argsRequired: boolean;
    caseInsensitive: boolean;
    cooldown: number;
    cooldownExclusions: CommandCooldownExclusions;
    cooldownMessage: MessageContent | false | GenericCheckFunction<MessageContent>;
    cooldownReturns: number;
    defaultSubcommandOptions: CommandOptions;
    deleteCommand: boolean;
    description: string;
    dmOnly: boolean;
    errorMessage: MessageContent | GenericCheckFunction<MessageContent>;
    fullDescription: string;
    fullLabel: string;
    guildOnly: boolean;
    hidden: boolean;
    hooks: Hooks;
    invalidUsageMessage: MessageContent | false | GenericCheckFunction<MessageContent>;
    label: string;
    parentCommand?: Command;
    permissionMessage: MessageContent | false | GenericCheckFunction<MessageContent>;
    reactionButtons: null | CommandReactionButtons[];
    reactionButtonTimeout: number;
    requirements: CommandRequirements;
    restartCooldown: boolean;
    subcommandAliases: { [alias: string]: string };
    subcommands: { [s: string]: Command };
    usage: string;
    constructor(label: string, generate: CommandGenerator, options?: CommandOptions);
    cooldownCheck(msg: Message): boolean;
    cooldownExclusionCheck(msg: Message): boolean;
    executeCommand(msg: Message, args: string[]): Promise<GeneratorFunctionReturn>;
    permissionCheck(msg: Message): Promise<boolean>;
    process(args: string[], msg: Message): Promise<void | GeneratorFunctionReturn>;
    registerSubcommand(label: string, generator: CommandGenerator, options?: CommandOptions): Command;
    registerSubcommandAlias(alias: string, label: string): void;
    unregisterSubcommand(label: string): void;
    toString(): string;
    toJSON(props?: string[]): JSONCache;
  }


export class CommandClient extends Client {
    activeMessages: { [s: string]: ActiveMessages };
    commandAliases: { [s: string]: string };
    commandOptions: CommandClientOptions;
    commands: { [s: string]: Command };
    guildPrefixes: { [s: string]: string | string[] };
    preReady?: true;
    constructor(token: string, options: ClientOptions, commandOptions?: CommandClientOptions);
    checkPrefix(msg: Message): string;
    onMessageCreate(msg: Message): Promise<void>;
    onMessageReactionEvent(msg: Message, emoji: Emoji, reactor: Member | Uncached | string): Promise<void>
    registerCommand(label: string, generator: CommandGenerator, options?: CommandOptions): Command;
    registerCommandAlias(alias: string, label: string): void;
    registerGuildPrefix(guildID: string, prefix: string[] | string): void;
    resolveCommand(label: string): Command;
    unregisterCommand(label: string): void;
    unwatchMessage(id: string, channelID: string): void;
    toString(): string;
  }


export class DiscordHTTPError extends Error {
    code: number;
    name: "DiscordHTTPError";
    req: ClientRequest;
    res: IncomingMessage;
    response: HTTPResponse;
    constructor(req: ClientRequest, res: IncomingMessage, response: HTTPResponse, stack: string);
    flattenErrors(errors: HTTPResponse, keyPrefix?: string): string[];
  }


export class DiscordRESTError extends Error {
    code: number;
    name: string;
    req: ClientRequest;
    res: IncomingMessage;
    response: HTTPResponse;
    constructor(req: ClientRequest, res: IncomingMessage, response: HTTPResponse, stack: string);
    flattenErrors(errors: HTTPResponse, keyPrefix?: string): string[];
  }


export class ExtendedUser extends User {
    email: string;
    mfaEnabled: boolean;
    premiumType: Constants["PremiumTypes"][keyof Constants["PremiumTypes"]];
    verified: boolean;
  }


export class GroupChannel extends PrivateChannel {
    icon: string | null;
    iconURL: string | null;
    name: string;
    ownerID: string;
    recipients: Collection<User>;
    type: Constants["ChannelTypes"]["GROUP_DM"];
    addRecipient(userID: string): Promise<void>;
    dynamicIconURL(format?: ImageFormat, size?: number): string | null;
    edit(options: { icon?: string; name?: string; ownerID?: string }): Promise<GroupChannel>;
    removeRecipient(userID: string): Promise<void>;
  }


export class GuildAuditLogEntry extends Base {
    actionType: number;
    after: { [key: string]: unknown } | null;
    before: { [key: string]: unknown } | null;
    channel?: AnyGuildChannel;
    count?: number;
    deleteMemberDays?: number;
    guild: Guild;
    id: string;
    member?: Member | Uncached;
    membersRemoved?: number;
    message?: Message<GuildTextableChannel>;
    reason: string | null;
    role?: Role | { id: string; name: string };
    target?: Guild | AnyGuildChannel | Member | Role | Invite | Emoji | Sticker | Message<GuildTextableChannel> | null;
    targetID: string;
    user: User;
    constructor(data: BaseData, guild: Guild);
  }


export class GuildChannel extends Channel {
    guild: Guild;
    name: string;
    nsfw: boolean;
    parentID: string | null;
    permissionOverwrites: Collection<PermissionOverwrite>;
    position: number;
    type: GuildChannelTypes;
    constructor(data: BaseData, client: Client);
    delete(reason?: string): Promise<void>;
    deletePermission(overwriteID: string, reason?: string): Promise<void>;
    edit(options: Omit<EditChannelOptions, "icon" | "ownerID">, reason?: string): Promise<this>;
    editPermission(
      overwriteID: string,
      allow: bigint | number,
      deny: bigint | number,
      type: PermissionType,
      reason?: string
    ): Promise<PermissionOverwrite>;
    editPosition(position: number, options?: EditChannelPositionOptions): Promise<void>;
    getInvites(): Promise<Invite[]>;
    permissionsOf(memberID: string | Member | MemberRoles): Permission;
  }


export class GuildIntegration extends Base {
    account: { id: string; name: string };
    application?: IntegrationApplication;
    createdAt: number;
    enabled: boolean;
    enableEmoticons?: boolean;
    expireBehavior?: GuildIntegrationExpireBehavior;
    expireGracePeriod?: number;
    id: string;
    name: string;
    revoked?: boolean;
    roleID?: string;
    subscriberCount?: number;
    syncedAt?: number;
    syncing?: boolean;
    type: GuildIntegrationTypes;
    user?: User;
    constructor(data: BaseData, guild: Guild);
    delete(): Promise<void>;
    edit(options: IntegrationOptions): Promise<void>;
    sync(): Promise<void>;
  }


export class GuildPreview extends Base {
    approximateMemberCount: number;
    approximatePresenceCount: number;
    description: string | null;
    discoverySplash: string | null;
    discoverySplashURL: string | null;
    emojis: Emoji[];
    features: GuildFeatures[];
    icon: string | null;
    iconURL: string | null;
    id: string;
    name: string;
    splash: string | null;
    splashURL: string | null;
    constructor(data: BaseData, client: Client);
    dynamicDiscoverySplashURL(format?: ImageFormat, size?: number): string | null;
    dynamicIconURL(format?: ImageFormat, size?: number): string | null;
    dynamicSplashURL(format?: ImageFormat, size?: number): string | null;
  }


export class GuildTemplate {
    code: string;
    createdAt: number;
    creator: User;
    description: string | null;
    isDirty: string | null;
    name: string;
    serializedSourceGuild: Guild;
    sourceGuild: Guild | Uncached;
    updatedAt: number;
    usageCount: number;
    constructor(data: BaseData, client: Client);
    createGuild(name: string, icon?: string): Promise<Guild>;
    delete(): Promise<GuildTemplate>;
    edit(options: GuildTemplateOptions): Promise<GuildTemplate>;
    sync(): Promise<GuildTemplate>;
    toJSON(props?: string[]): JSONCache;
  }


//Interaction
export class Interaction extends Base {
    acknowledged: boolean;
    applicationID: string;
    id: string;
    token: string;
    type: number;
    version: number;
  }


export class PingInteraction extends Interaction {
    type: Constants["InteractionTypes"]["PING"];
    acknowledge(): Promise<void>;
    pong(): Promise<void>;
  }


export class CommandInteraction<T extends PossiblyUncachedTextable = TextableChannel> extends Interaction {
    channel: T;
    data: {
      id: string;
      name: string;
      type: Constants["ApplicationCommandTypes"][keyof Constants["ApplicationCommandTypes"]];
      target_id?: string;
      resolved?: {
        users?: Collection<User>;
        members?: Collection<Omit<Member, "user" | "deaf" | "mute">>;
        roles?: Collection<Role>;
        channels?: Collection<PartialChannel>;
        messages?: Collection<Message>;
      };
      options?: InteractionDataOptions[];
    };
    guildID?: string;
    member?: Member;
    type: Constants["InteractionTypes"]["APPLICATION_COMMAND"];
    user?: User;
    acknowledge(flags?: number): Promise<void>;
    createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise<Message>;
    createMessage(content: string | InteractionContent , file?: FileContent | FileContent[]): Promise<void>;
    defer(flags?: number): Promise<void>;
    deleteMessage(messageID: string): Promise<void>;
    deleteOriginalMessage(): Promise<void>;
    editMessage(messageID: string, content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    editOriginalMessage(content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    getOriginalMessage(): Promise<Message>
  }


export class ComponentInteraction<T extends PossiblyUncachedTextable = TextableChannel> extends Interaction {
    channel: T;
    data: ComponentInteractionButtonData | ComponentInteractionSelectMenuData;
    guildID?: string;
    member?: Member;
    message: Message;
    type: Constants["InteractionTypes"]["MESSAGE_COMPONENT"];
    user?: User;
    acknowledge(): Promise<void>;
    createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise<Message>;
    createMessage(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise<void>;
    defer(flags?: number): Promise<void>;
    deferUpdate(): Promise<void>;
    deleteMessage(messageID: string): Promise<void>;
    deleteOriginalMessage(): Promise<void>;
    editMessage(messageID: string, content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    editOriginalMessage(content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    editParent(content: InteractionEditContent, file?: FileContent | FileContent[]): Promise<void>;
    getOriginalMessage(): Promise<Message>
  }


export class AutocompleteInteraction<T extends PossiblyUncachedTextable = TextableChannel> extends Interaction {
    channel: T;
    data: {
      id: string;
      name: string;
      type: Constants["ApplicationCommandTypes"][keyof Constants["ApplicationCommandTypes"]];
      target_id?: string;
      options?: InteractionDataOptions[];
    };
    guildID?: string;
    member?: Member;
    type: Constants["InteractionTypes"]["APPLICATION_COMMAND_AUTOCOMPLETE"];
    user?: User;
    acknowledge(choices: ApplicationCommandOptionChoice[]): Promise<void>;
    result(choices: ApplicationCommandOptionChoice[]): Promise<void>;
  }


export class UnknownInteraction<T extends PossiblyUncachedTextable = TextableChannel> extends Interaction {
    channel?: T;
    data?: unknown;
    guildID?: string;
    member?: Member;
    message?: Message;
    type: number;
    user?: User;
    acknowledge(data: InteractionOptions): Promise<void>;
    createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise<Message>;
    createMessage(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise<void>;
    defer(flags?: number): Promise<void>;
    deferUpdate(): Promise<void>;
    deleteMessage(messageID: string): Promise<void>;
    deleteOriginalMessage(): Promise<void>;
    editMessage(messageID: string, content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    editOriginalMessage(content: string | InteractionEditContent, file?: FileContent | FileContent[]): Promise<Message>;
    editParent(content: InteractionEditContent, file?: FileContent | FileContent[]): Promise<void>;
    getOriginalMessage(): Promise<Message>
    pong(): Promise<void>;
    result(choices: ApplicationCommandOptionChoice[]): Promise<void>;
  }


// If CT (count) is "withMetadata", it will not have count properties
export class Invite<CT extends "withMetadata" | "withCount" | "withoutCount" = "withMetadata", CH extends InviteChannel = InviteChannel> extends Base {
    channel: CH;
    code: string;
    // @ts-ignore: Property is only not null when invite metadata is supplied
    createdAt: CT extends "withMetadata" ? number : null;
    guild: CT extends "withMetadata"
      ? Guild // Invite with Metadata always has guild prop
      : CH extends Extract<InviteChannel, GroupChannel> // Invite without Metadata
        ? never // If the channel is GroupChannel, there is no guild
        : CH extends Exclude<InviteChannel, InvitePartialChannel> // Invite without Metadata and not GroupChanel
          ? Guild // If the invite channel is not partial
          : Guild | undefined; // If the invite channel is partial
    inviter?: User;
    maxAge: CT extends "withMetadata" ? number : null;
    maxUses: CT extends "withMetadata" ? number : null;
    memberCount: CT extends "withMetadata" | "withoutCount" ? null : number;
    presenceCount: CT extends "withMetadata" | "withoutCount" ? null : number;
    stageInstance: CH extends StageChannel ? InviteStageInstance : null;
    temporary: CT extends "withMetadata" ? boolean : null;
    uses: CT extends "withMetadata" ? number : null;
    constructor(data: BaseData, client: Client);
    delete(reason?: string): Promise<void>;
  }


export class Member extends Base implements Presence {
    accentColor?: number | null;
    activities?: Activity[];
    avatar: string | null;
    avatarURL: string;
    banner?: string | null;
    bannerURL: string | null;
    bot: boolean;
    clientStatus?: ClientStatus;
    createdAt: number;
    defaultAvatar: string;
    defaultAvatarURL: string;
    discriminator: string;
    game: Activity | null;
    guild: Guild;
    id: string;
    joinedAt: number | null;
    mention: string;
    nick: string | null;
    pending?: boolean;
    /** @deprecated */
    permission: Permission;
    permissions: Permission;
    premiumSince: number;
    roles: string[];
    staticAvatarURL: string;
    status?: Status;
    user: User;
    username: string;
    voiceState: VoiceState;
    constructor(data: BaseData, guild?: Guild, client?: Client);
    addRole(roleID: string, reason?: string): Promise<void>;
    ban(deleteMessageDays?: number, reason?: string): Promise<void>;
    edit(options: MemberOptions, reason?: string): Promise<void>;
    kick(reason?: string): Promise<void>;
    removeRole(roleID: string, reason?: string): Promise<void>;
    unban(reason?: string): Promise<void>;
  }


export class Message<T extends PossiblyUncachedTextable = TextableChannel> extends Base {
    activity?: MessageActivity;
    application?: MessageApplication;
    applicationID?: string;
    attachments: Attachment[];
    author: User;
    channel: T;
    channelMentions: string[];
    /** @deprecated */
    cleanContent: string;
    command?: Command;
    components?: ActionRow[];
    content: string;
    createdAt: number;
    editedTimestamp?: number;
    embeds: Embed[];
    flags: number;
    guildID: T extends GuildTextableWithThread ? string : undefined;
    id: string;
    interaction: MessageInteraction | null;
    jumpLink: string;
    member: T extends GuildTextableWithThread ? Member : null;
    mentionEveryone: boolean;
    mentions: User[];
    messageReference: MessageReference | null;
    pinned: boolean;
    prefix?: string;
    reactions: { [s: string]: { count: number; me: boolean } };
    referencedMessage?: Message | null;
    roleMentions: string[];
    stickerItems?: StickerItems[];
    /** @deprecated */
    stickers?: Sticker[];
    timestamp: number;
    tts: boolean;
    type: number;
    webhookID: T extends GuildTextableWithThread ? string | undefined : undefined;
    constructor(data: BaseData, client: Client);
    addReaction(reaction: string): Promise<void>;
    /** @deprecated */
    addReaction(reaction: string, userID: string): Promise<void>;
    createThreadWithMessage(messageID: string, options: CreateThreadOptions): Promise<NewsThreadChannel | PublicThreadChannel>;
    crosspost(): Promise<T extends NewsChannel ? Message<NewsChannel> : never>;
    delete(reason?: string): Promise<void>;
    deleteWebhook(token: string): Promise<void>;
    edit(content: MessageContent): Promise<Message<T>>;
    editWebhook(token: string, options: MessageWebhookContent): Promise<Message<T>>;
    getReaction(reaction: string, options?: GetMessageReactionOptions): Promise<User[]>;
    /** @deprecated */
    getReaction(reaction: string, limit?: number, before?: string, after?: string): Promise<User[]>;
    pin(): Promise<void>;
    removeReaction(reaction: string, userID?: string): Promise<void>;
    removeReactionEmoji(reaction: string): Promise<void>;
    removeReactions(): Promise<void>;
    unpin(): Promise<void>;
  }


// News channel rate limit is always 0
export class NewsChannel extends TextChannel {
    rateLimitPerUser: 0;
    type: Constants["ChannelTypes"]["GUILD_NEWS"];
    createInvite(options?: CreateInviteOptions, reason?: string): Promise<Invite<"withMetadata", NewsChannel>>;
    createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise<Message<NewsChannel>>;
    createThreadWithMessage(messageID: string, options: CreateThreadOptions): Promise<NewsThreadChannel>;
    crosspostMessage(messageID: string): Promise<Message<NewsChannel>>;
    editMessage(messageID: string, content: MessageContentEdit): Promise<Message<NewsChannel>>;
    follow(webhookChannelID: string): Promise<ChannelFollow>;
    getInvites(): Promise<(Invite<"withMetadata", NewsChannel>)[]>;
    getMessage(messageID: string): Promise<Message<NewsChannel>>;
    getMessages(options?: GetMessagesOptions): Promise<Message<NewsChannel>[]>;
    /** @deprecated */
    getMessages(limit?: number, before?: string, after?: string, around?: string): Promise<Message<NewsChannel>[]>;
    getPins(): Promise<Message<NewsChannel>[]>;
  }


export class NewsThreadChannel extends ThreadChannel {
    type: Constants["ChannelTypes"]["GUILD_NEWS_THREAD"];
    createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise<Message<NewsThreadChannel>>;
    edit(options: Pick<EditChannelOptions, "archived" | "autoArchiveDuration" | "locked" | "name" | "rateLimitPerUser">, reason?: string): Promise<this>;
    editMessage(messageID: string, content: MessageContentEdit): Promise<Message<NewsThreadChannel>>;
    getMessage(messageID: string): Promise<Message<NewsThreadChannel>>;
    getMessages(options?: GetMessagesOptions): Promise<Message<NewsThreadChannel>[]>;
    getPins(): Promise<Message<NewsThreadChannel>[]>;
  }


export class Permission extends Base {
    allow: bigint;
    deny: bigint;
    json: Record<keyof Constants["Permissions"], boolean>;
    constructor(allow: number | string | bigint, deny?: number | string | bigint);
    has(permission: keyof Constants["Permissions"]): boolean;
  }


export class PermissionOverwrite extends Permission {
    id: string;
    type: PermissionType;
    constructor(data: Overwrite);
  }