export interface NavigateToNextCellParams {
    /** The keycode for the arrow key pressed:
     *  left = 37, up = 38, right = 39, down = 40 */
    key: number;
    /** The cell that currently has focus */
    previousCellPosition: CellPosition;
    /** The cell the grid would normally pick as the next cell for navigation */
    nextCellPosition: CellPosition | null;

    event: KeyboardEvent | null;
    api: GridApi;
    columnApi: ColumnApi;
}


export interface TabToNextCellParams {
    /** True if the Shift key is also down */
    backwards: boolean;
    /** True if the current cell is editing
     * (you may want to skip cells that are not editable, as the grid will enter the next cell in editing mode also if tabbing) */
    editing: boolean;
    /** The cell that currently has focus */
    previousCellPosition: CellPosition;
    /** The cell the grid would normally pick as the next cell for navigation.  */
    nextCellPosition: CellPosition | null;
    api: GridApi;
    columnApi: ColumnApi;
}


export interface PostProcessPopupParams {
    /** If popup is for a column, this gives the Column */
    column?: Column | null;
    /** If popup is for a row, this gives the RowNode */
    rowNode?: RowNode | null;
    /** The popup we are showing */
    ePopup: HTMLElement;
    /** The different types are:
     *  'contextMenu', 'columnMenu', 'aggFuncSelect', 'popupCellEditor' */
    type: string;
    /** If the popup is as a result of a button click (eg menu button),
     *  this is the component that the user clicked */
    eventSource?: HTMLElement | null;
    /** If the popup is as a result of a click or touch,
     *  this is the event - eg user showing context menu */
    mouseEvent?: MouseEvent | Touch | null;
}


export interface PaginationNumberFormatterParams {
    value: number;
}


export interface ProcessDataFromClipboardParams {
    /** 2D array of all cells from the clipboard */
    data: string[][];
}


export interface ChartRef {
    /** The id of the created chart. */
    chartId: string;
    /** The chart instance that is produced by AG Charts which can be used to interact with the chart directly. */
    chart: any;
    /** The chart DOM element, which the application is responsible for placing into the DOM. */
    chartElement: HTMLElement;
    /** The application is responsible for calling this when the chart is no longer needed. */
    destroyChart: () => void;
}


export interface ServerSideStoreParams {
    /**
     * What store type to use.
     * If missing, then defaults to grid option `serverSideStoreType`.
     *  */
    storeType?: ServerSideStoreType;
    /**
     * For Partial Store only.
     * How many blocks to keep in cache.
     * If missing, defaults to grid options `maxBlocksInCache`.
     */
    maxBlocksInCache?: number;
    /**
     * For Partial Store only.
     * Cache block size.
     * If missing, defaults to grid options `cacheBlockSize`.
     */
    cacheBlockSize?: number;
}


export interface GetServerSideStoreParamsParams {
    /** The level of the store. Top level is 0. */
    level: number;
    /** The Row Node for the group that got expanded, or undefined if top level (ie no parent) */
    parentRowNode?: RowNode;
    /** Active Row Group Columns, if any. */
    rowGroupColumns: Column[];
    /** Active Pivot Columns, if any. */
    pivotColumns: Column[];
    /** true if pivot mode is active. */
    pivotMode: boolean;
}


export interface IsServerSideGroupOpenByDefaultParams {
    data: any;
    rowNode: RowNode;
}


export interface IsGroupOpenByDefaultParams {
    /** The row node being considered. */
    rowNode: RowNode;
    /** The Column for which this row is grouping. */
    rowGroupColumn: Column;
    /** Same as `rowNode.level` - what level the group is at, e.g. 0 for top level, 1 for second etc */
    level: number;
    /** Same as `rowNode.field` - the field we are grouping on, e.g. 'country' */
    field: string;
    /** Same as `rowNode.key`, the value of this group, e.g. 'Ireland' */
    key: string;
}


export interface LoadingCellRendererSelectorFunc {
    (params: ILoadingCellRendererParams): LoadingCellRendererSelectorResult | undefined;
}


export interface LoadingCellRendererSelectorResult {
    /** Equivalent of setting `loadingCellRenderer` */
    component?: { new(): ICellRenderer; } | string;
    /** Equivalent of setting `loadingCellRendererFramework` */
    frameworkComponent?: any;
    /** Equivalent of setting `loadingCellRendererParams` */
    params?: any;
}


export type RowGroupingDisplayType = 'singleColumn' | 'multipleColumns' | 'groupRows' | 'custom';


export type TreeDataDisplayType = 'auto' | 'custom';


export type ServerSideStoreType = 'full' | 'partial';


(props: Props) => {
  const tenantContextData = useContext(TenantContext);
  const initState: State = {
    data: props.data || [],
    current: {},
    visible: false,
  };

  const [visible, setVisible] = useState(initState.visible);
  const [data, setData] = useState(initState.data);
  const [current, setCurrent] = useState(initState.current);

  useEffect(() => {
    setData(tenantContextData.tags || [])
  }, [tenantContextData]);
  const editItem = (item: any) => {
    setVisible(true);
    setCurrent(item);
  };

  const deleteItem = (item: any) => {
    const temp = data.filter(e => e.id !== item.id);
    setData(temp);
    props.save(temp);
  };

  const columns: ColumnProps<TagsMeta>[] = [
    {
      title: '属性标识',
      dataIndex: 'id',
    },
    {
      title: '属性名称',
      dataIndex: 'name',
    },
    {
      title: '数据类型',
      dataIndex: 'valueType',
      render: text => text.type,
    },
    {
      title: '是否只读',
      dataIndex: 'expands.readOnly',
      render: text => (text === 'true' ? '是' : '否'),
    },
    {
      title: '说明',
      dataIndex: 'description',
      width:'30%',
      ellipsis:true
    },
    {
      title: '操作',
      render: (text, record) => (
        <Fragment>
          <a onClick={()


() => {
    setData(tenantContextData.tags || [])
  }


(item: any) => {
    setVisible(true);
    setCurrent(item);
  }


(item: any) => {
    const temp = data.filter(e => e.id !== item.id);
    setData(temp);
    props.save(temp);
  }


e => e.id !== item.id


text => text.type


text => (text === 'true' ? '是' : '否')


(text, record) => (
        <Fragment>
          <a onClick={()


() => deleteItem(record)


(item: TagsMeta) => {
    if (!data) {
      setData([]);
    }
    const i = data.findIndex((j: any) => j.id === item.id);
    if (i > -1) {
      data[i] = item;
    } else {
      data.push(item);
    }
    setVisible(false);
    setData(data);
    props.save(data);
  }


(j: any) => j.id === item.id


interface Props extends FormComponentProps {
  save: Function;
  data: any[];
  unitsData: any;
}


interface State {
  data: TagsMeta[];
  current: Partial<TagsMeta>;
  visible: boolean;
}


@Crud({
    model:User,
})
@Controller('users')
@ApiTags('用户')
export class UsersController {
    constructor(
        @InjectModel(User) private readonly model:ReturnModelType<typeof User>
    ) {
    }
}


<A, B>(tx: TxLike<A, B>): ((x: A) => B | B[]) => {
    const { 1: complete, 2: reduce } = ensureTransducer(tx)(push());
    let done = false;
    return (x: A) => {
        if (!done) {
            let acc = reduce([], x);
            done = isReduced(acc);
            if (done) {
                acc = complete(acc.deref());
            }
            return acc.length === 1 ? acc[0] : acc.length > 0 ? acc : undefined;
        }
    };
}


(x: A) => {
        if (!done) {
            let acc = reduce([], x);
            done = isReduced(acc);
            if (done) {
                acc = complete(acc.deref());
            }
            return acc.length === 1 ? acc[0] : acc.length > 0 ? acc : undefined;
        }
    }


export function doRectanglesOverlap(a: Rect, b: Rect): boolean {
  return a.x < b.x2 && a.x2 > b.x && a.y < b.y2 && a.y2 > b.y;
}


export function doAnyOverlap(arrayOfRects: Rect[]): boolean {
  for (let i = 0; i < arrayOfRects.length - 1; i++) {
    if (doRectanglesOverlap(arrayOfRects[i], arrayOfRects[i + 1])) {
      return true;
    }
  }

  return false;
}


export function computeRectOverlap(a: Rect, b: Rect): Rect {
  const result = createEmptyRect();

  // Take the greater of the x and y values;
  result.x = a.x > b.x ? a.x : b.x;
  result.y = a.y > b.y ? a.y : b.y;

  // Take the lesser of the x2 and y2 values
  result.x2 = a.x2 < b.x2 ? a.x2 : b.x2;
  result.y2 = a.y2 < b.y2 ? a.y2 : b.y2;

  // Set our width and height here
  result.w = result.x2 - result.x;
  result.h = result.y2 - result.y;

  return result;
}


// subtracts b from a and returns from 0 - 4 remaining rectangles after doing it
export function subtractRectangles(a: Rect, b: Rect): Rect[] {
  if (!doRectanglesOverlap(a, b)) {
    return [a];
  }

  const result = new Array<Rect>();
  let leftX = a.x;
  let rightX = a.x2;

  // Check the left side first
  if (a.x < b.x) {
    const leftOverlap: Rect = {
      x: a.x,
      x2: b.x,
      y: a.y,
      y2: a.y2,
      h: a.h,
      w: b.x - a.x
    };

    leftX = leftOverlap.x2;
    result.push(leftOverlap);
  }

  // Check the right side next
  if (a.x2 > b.x2) {
    const rightOverlap = {
      x: b.x2,
      x2: a.x2,
      y: a.y,
      y2: a.y2,
      h: a.h,
      w: a.x2 - b.x2
    };

    rightX = rightOverlap.x;
    result.push(rightOverlap);
  }

  // Top side
  if (a.y < b.y) {
    const topOverlap = {
      x: leftX,
      x2: rightX,
      w: rightX - leftX,
      y: a.y,
      y2: b.y,
      h: b.y - a.y
    };

    result.push(topOverlap);
  }

  // Bottom side
  if (a.y2 > b.y2) {
    const bottomOverlap = {
      x: leftX,
      x2: rightX,
      w: rightX - leftX,
      y: b.y2,
      y2: a.y2,
      h: 0
    };

    bottomOverlap.h = bottomOverlap.y2 - bottomOverlap.y;
    result.push(bottomOverlap);
  }

  return result;
}


/**
 * This will insert the reset styles as first in the head ( fallback to body if head is not available ).
 * We need to do this because css-reset is a js file now which gives us all the reset styles in string format
 * and thus we need to insert them as styles manually.
 * We cannot use injectGlobal from styled components as it inserts styles at the end of head which defeats the
 * purpose of styles component
 */
export default function insertStyleSheetInHead(cssResetStyles: string) {
  const parentElement = document.head || document.body;
  if (parentElement) {
    const insertBeforeElement =
      parentElement.getElementsByTagName('style')[0] ||
      parentElement.firstChild;

    const style = document.createElement('style');
    style.innerHTML = cssResetStyles;
    parentElement.insertBefore(style, insertBeforeElement);
  }
}


({
  placeholder = "Choose a language",
  onChange,
  options,
  ...props
}) => {
  const [open, setOpen] = useState(false);
  const [value, setValue] = useState("");
  const [label, setLabel] = useState("");

  return (
    <div className={styles.root}>
      <button className={styles.button} onClick={()


option => (
          <li
            className={styles.listItem}


classnames(styles


onChange(option


setOpen(false);


setLabel(option


setValue(option


export function Content(props: ContentProps) {
  return (

          {props.movies.map((movie) => (
            <MovieCard
              key={movie.imdbID}
              title={movie.Title}
              poster={movie.Poster}
              runtime={movie.Runtime}
              rating={movie.Ratings[0].Value}
            />
          ))}

  );
}


(movie) => (
            <MovieCard
              key={movie.imdbID}


interface Movie {
  imdbID: string;
  Title: string;
  Poster: string;
  Ratings: Array<{
    Source: string;
    Value: string;
  }>;
  Runtime: string;
}


interface ContentProps {
  selectedGenre: {
    title: string;
  };
  movies: Array<Movie>;
}


(resolve: (result: GetBarsResult) => void, reject: (reason: string) => void) => {
			this._requester.sendRequest<HistoryResponse>(this._datafeedUrl, 'history', requestParams)
				.then((response: HistoryResponse | UdfErrorResponse) => {
					if (response.s !== 'ok' && response.s !== 'no_data') {
						reject(response.errmsg);
						return;
					}

					const bars: Bar[] = [];
					const meta: HistoryMetadata = {
						noData: false,
					};

					if (response.s === 'no_data') {
						meta.noData = true;
						meta.nextTime = response.nextTime;
					} else {
						const volumePresent = response.v !== undefined;
						const ohlPresent = response.o !== undefined;

						for (let i = 0; i < response.t.length; ++i) {
							const barValue: Bar = {
								time: response.t[i] * 1000,
								close: Number(response.c[i]),
								open: Number(response.c[i]),
								high: Number(response.c[i]),
								low: Number(response.c[i]),
							};

							if (ohlPresent) {
								barValue.open = Number((response as HistoryFullDataResponse).o[i]);
								barValue.high = Number((response as HistoryFullDataResponse).h[i]);
								barValue.low = Number((response as HistoryFullDataResponse).l[i]);
							}

							if (volumePresent) {
								barValue.volume = Number((response as HistoryFullDataResponse).v[i]);
							}

							bars.push(barValue);
						}
					}

					resolve({
						bars: bars,
						meta: meta,
					});
				})
				.catch((reason?: string | Error) => {
					const reasonString = getErrorMessage(reason);
					console.warn(`HistoryProvider: getBars() failed, error=${reasonString}`);
					reject(reasonString);
				});
		}


(response: HistoryResponse | UdfErrorResponse) => {
					if (response.s !== 'ok' && response.s !== 'no_data') {
						reject(response.errmsg);
						return;
					}

					const bars: Bar[] = [];
					const meta: HistoryMetadata = {
						noData: false,
					};

					if (response.s === 'no_data') {
						meta.noData = true;
						meta.nextTime = response.nextTime;
					} else {
						const volumePresent = response.v !== undefined;
						const ohlPresent = response.o !== undefined;

						for (let i = 0; i < response.t.length; ++i) {
							const barValue: Bar = {
								time: response.t[i] * 1000,
								close: Number(response.c[i]),
								open: Number(response.c[i]),
								high: Number(response.c[i]),
								low: Number(response.c[i]),
							};

							if (ohlPresent) {
								barValue.open = Number((response as HistoryFullDataResponse).o[i]);
								barValue.high = Number((response as HistoryFullDataResponse).h[i]);
								barValue.low = Number((response as HistoryFullDataResponse).l[i]);
							}

							if (volumePresent) {
								barValue.volume = Number((response as HistoryFullDataResponse).v[i]);
							}

							bars.push(barValue);
						}
					}

					resolve({
						bars: bars,
						meta: meta,
					});
				}


(reason?: string | Error) => {
					const reasonString = getErrorMessage(reason);
					console.warn(`HistoryProvider: getBars() failed, error=${reasonString}`);
					reject(reasonString);
				}


export class HistoryProvider {
	private _datafeedUrl: string;
	private readonly _requester: Requester;

	public constructor(datafeedUrl: string, requester: Requester) {
		this._datafeedUrl = datafeedUrl;
		this._requester = requester;
	}

	public getBars(symbolInfo: LibrarySymbolInfo, resolution: string, rangeStartDate: number, rangeEndDate: number): Promise<GetBarsResult> {
		const requestParams: RequestParams = {
			symbol: symbolInfo.ticker || '',
			resolution: resolution,
			from: rangeStartDate,
			to: rangeEndDate,
		};

		return new Promise((resolve: (result: GetBarsResult) => void, reject: (reason: string) => void) => {
			this._requester.sendRequest<HistoryResponse>(this._datafeedUrl, 'history', requestParams)
				.then((response: HistoryResponse | UdfErrorResponse) => {
					if (response.s !== 'ok' && response.s !== 'no_data') {
						reject(response.errmsg);
						return;
					}

					const bars: Bar[] = [];
					const meta: HistoryMetadata = {
						noData: false,
					};

					if (response.s === 'no_data') {
						meta.noData = true;
						meta.nextTime = response.nextTime;
					} else {
						const volumePresent = response.v !== undefined;
						const ohlPresent = response.o !== undefined;

						for (let i = 0; i < response.t.length; ++i) {
							const barValue: Bar = {
								time: response.t[i] * 1000,
								close: Number(response.c[i]),
								open: Number(response.c[i]),
								high: Number(response.c[i]),
								low: Number(response.c[i]),
							};

							if (ohlPresent) {
								barValue.open = Number((response as HistoryFullDataResponse).o[i]);
								barValue.high = Number((response as HistoryFullDataResponse).h[i]);
								barValue.low = Number((response as HistoryFullDataResponse).l[i]);
							}

							if (volumePresent) {
								barValue.volume = Number((response as HistoryFullDataResponse).v[i]);
							}

							bars.push(barValue);
						}
					}

					resolve({
						bars: bars,
						meta: meta,
					});
				})
				.catch((reason?: string | Error) => {
					const reasonString = getErrorMessage(reason);
					console.warn(`HistoryProvider: getBars() failed, error=${reasonString}`);
					reject(reasonString);
				});
		});
	}
}


interface HistoryPartialDataResponse extends UdfOkResponse {
	t: number[];
	c: number[];
	o?: never;
	h?: never;
	l?: never;
	v?: never;
}


interface HistoryFullDataResponse extends UdfOkResponse {
	t: number[];
	c: number[];
	o: number[];
	h: number[];
	l: number[];
	v: number[];
}


interface HistoryNoDataResponse extends UdfResponse {
	s: 'no_data';
	nextTime?: number;
}


export interface GetBarsResult {
	bars: Bar[];
	meta: HistoryMetadata;
}


type HistoryResponse = HistoryFullDataResponse | HistoryPartialDataResponse | HistoryNoDataResponse;


public getBars(symbolInfo: LibrarySymbolInfo, resolution: string, rangeStartDate: number, rangeEndDate: number): Promise<GetBarsResult> {
		const requestParams: RequestParams = {
			symbol: symbolInfo.ticker || '',
			resolution: resolution,
			from: rangeStartDate,
			to: rangeEndDate,
		};

		return new Promise((resolve: (result: GetBarsResult) => void, reject: (reason: string) => void) => {
			this._requester.sendRequest<HistoryResponse>(this._datafeedUrl, 'history', requestParams)
				.then((response: HistoryResponse | UdfErrorResponse) => {
					if (response.s !== 'ok' && response.s !== 'no_data') {
						reject(response.errmsg);
						return;
					}

					const bars: Bar[] = [];
					const meta: HistoryMetadata = {
						noData: false,
					};

					if (response.s === 'no_data') {
						meta.noData = true;
						meta.nextTime = response.nextTime;
					} else {
						const volumePresent = response.v !== undefined;
						const ohlPresent = response.o !== undefined;

						for (let i = 0; i < response.t.length; ++i) {
							const barValue: Bar = {
								time: response.t[i] * 1000,
								close: Number(response.c[i]),
								open: Number(response.c[i]),
								high: Number(response.c[i]),
								low: Number(response.c[i]),
							};

							if (ohlPresent) {
								barValue.open = Number((response as HistoryFullDataResponse).o[i]);
								barValue.high = Number((response as HistoryFullDataResponse).h[i]);
								barValue.low = Number((response as HistoryFullDataResponse).l[i]);
							}

							if (volumePresent) {
								barValue.volume = Number((response as HistoryFullDataResponse).v[i]);
							}

							bars.push(barValue);
						}
					}

					resolve({
						bars: bars,
						meta: meta,
					});
				})
				.catch((reason?: string | Error) => {
					const reasonString = getErrorMessage(reason);
					console.warn(`HistoryProvider: getBars() failed, error=${reasonString}`);
					reject(reasonString);
				});
		});
	}


(Standard: System Locale)


export class MsalCommon extends Observable {}


export interface AuthenticationResult {
	scope: Array<string>;
	tenantId: string;
	accessToken: string;
	account: IAccount;
	idToken: string;
	expiresOn: Date;
}


export interface IAccount {
	id: string;
	username: string;
	object?: any;
}


export interface MSALException {
	message: string;
	errorCode: string | number;
}


export interface InitOptions {
	useConfig?: boolean;
	clientId?: string;
	authority?: string;
	redirectUri?: string;
	multiple?: boolean;
}


export interface AcquireOptions {
	scopes: Array<any>;
	onSuccess: (result: AuthenticationResult) => void;
	onError: (error: MSALException) => void;
	onCancel?: () => void;
}


export interface AcquireTokenSilentAsyncOptions {
	scopes: Array<any>;
	account: any;
	onSuccess: (result: AuthenticationResult) => void;
	onError: (error: MSALException) => void;
	onCancel?: () => void;
}


export declare enum UiBehavior {
	SELECT_ACCOUNT = 0,
	FORCE_LOGIN = 1,
	CONSENT = 2,
}


export function Cpf() {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            name: 'cpf',
            target: object.constructor,
            propertyName: propertyName,
            options: {
                message: 'CPF must be valid.',
            },
            validator: {
                validate(value: any) {
                    return cpf.isValid(value);
                },
            },
        });
    };
}


validate(value: any) {
                    return cpf.isValid(value);
                }


@Component({ template: `<ion-content></ion-content>` })
export class TabNone { }


@Component({
  selector: 'seed-layout [type="tab"]',
  template:
  `
    <seed-header [showLeftMenuButton]="false" [showRightMenuButton]="true">
      <ion-tabs [hidden]="showToolbarTab" layout-tabs tabsLayout="icon-top" tabsPlacement="top">
        <ion-tab [root]="dummyTab" layout-tab *ngFor="let menuItem of menuItems; let i = index;" (ionSelect)="navigateTo(menuItem.link)" tabTitle="{{menuItem.title}}" tabIcon="{{menuItem.icon}}"></ion-tab>
      </ion-tabs>
    </seed-header>

    <div [hidden]="true">
      <ng-content select="[menu-items]"></ng-content>
    </div>

    <ion-toolbar [hidden]="!showToolbarTab">
      <ion-tabs tabsLayout="icon-top" tabsPlacement="top">
        <ion-tab [root]="dummyTab" *ngFor="let menuItem of menuItems; let i = index;" (ionSelect)="navigateTo(menuItem.link)" tabTitle="{{menuItem.title}}" tabIcon="{{menuItem.icon}}"></ion-tab>
      </ion-tabs>
    </ion-toolbar>

    <ion-content main #content>
      <div padding>
        <ng-content></ng-content>
      </div>
    </ion-content>
  `,
})
export class LayoutTabComponent extends LayoutComponent {

  @Input() showMenuItemsAtHeader?: boolean = true;

  protected dummyTab;

  @ContentChildren(MenuItemComponent) menuItems: QueryList<MenuItemComponent>;

  get showToolbarTab() {
    if (this.showMenuItemsAtHeader == true) {
      if (this.platform.width() < 768) {
        return true;
      }
      return false;
    } else {
      return true;
    }
  }

  constructor(private router: Router, public platform: Platform) {
    super();
    this.dummyTab = TabNone;
  }

  navigateTo(link: string) {
    const routerLink = JSON.parse(link.replace(/'/g, '"'));
    this.router.navigate(routerLink);
  }
}


navigateTo(link: string) {
    const routerLink = JSON.parse(link.replace(/'/g, '"'));
    this.router.navigate(routerLink);
  }


/**
 * An Azure Cosmos DB storedProcedure.
 */
export class SqlResourceSqlStoredProcedure extends pulumi.CustomResource {
    /**
     * Get an existing SqlResourceSqlStoredProcedure resource's state with the given name, ID, and optional extra
     * properties used to qualify the lookup.
     *
     * @param name The _unique_ name of the resulting resource.
     * @param id The _unique_ provider ID of the resource to lookup.
     * @param opts Optional settings to control the behavior of the CustomResource.
     */
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): SqlResourceSqlStoredProcedure {
        return new SqlResourceSqlStoredProcedure(name, undefined as any, { ...opts, id: id });
    }

    /** @internal */
    public static readonly __pulumiType = 'azure-native:documentdb/v20210301preview:SqlResourceSqlStoredProcedure';

    /**
     * Returns true if the given object is an instance of SqlResourceSqlStoredProcedure.  This is designed to work even
     * when multiple copies of the Pulumi SDK have been loaded into the same process.
     */
    public static isInstance(obj: any): obj is SqlResourceSqlStoredProcedure {
        if (obj === undefined || obj === null) {
            return false;
        }
        return obj['__pulumiType'] === SqlResourceSqlStoredProcedure.__pulumiType;
    }

    /**
     * Identity for the resource.
     */
    public readonly identity!: pulumi.Output<outputs.documentdb.v20210301preview.ManagedServiceIdentityResponse | undefined>;
    /**
     * The location of the resource group to which the resource belongs.
     */
    public readonly location!: pulumi.Output<string | undefined>;
    /**
     * The name of the ARM resource.
     */
    public /*out*/ readonly name!: pulumi.Output<string>;
    public readonly resource!: pulumi.Output<outputs.documentdb.v20210301preview.SqlStoredProcedureGetPropertiesResponseResource | undefined>;
    /**
     * Tags are a list of key-value pairs that describe the resource. These tags can be used in viewing and grouping this resource (across resource groups). A maximum of 15 tags can be provided for a resource. Each tag must have a key no greater than 128 characters and value no greater than 256 characters. For example, the default experience for a template type is set with "defaultExperience": "Cassandra". Current "defaultExperience" values also include "Table", "Graph", "DocumentDB", and "MongoDB".
     */
    public readonly tags!: pulumi.Output<{[key: string]: string} | undefined>;
    /**
     * The type of Azure resource.
     */
    public /*out*/ readonly type!: pulumi.Output<string>;

    /**
     * Create a SqlResourceSqlStoredProcedure resource with the given unique name, arguments, and options.
     *
     * @param name The _unique_ name of the resource.
     * @param args The arguments to use to populate this resource's properties.
     * @param opts A bag of options that control this resource's behavior.
     */
    constructor(name: string, args: SqlResourceSqlStoredProcedureArgs, opts?: pulumi.CustomResourceOptions) {
        let inputs: pulumi.Inputs = {};
        opts = opts || {};
        if (!opts.id) {
            if ((!args || args.accountName === undefined) && !opts.urn) {
                throw new Error("Missing required property 'accountName'");
            }
            if ((!args || args.containerName === undefined) && !opts.urn) {
                throw new Error("Missing required property 'containerName'");
            }
            if ((!args || args.databaseName === undefined) && !opts.urn) {
                throw new Error("Missing required property 'databaseName'");
            }
            if ((!args || args.resource === undefined) && !opts.urn) {
                throw new Error("Missing required property 'resource'");
            }
            if ((!args || args.resourceGroupName === undefined) && !opts.urn) {
                throw new Error("Missing required property 'resourceGroupName'");
            }
            inputs["accountName"] = args ? args.accountName : undefined;
            inputs["containerName"] = args ? args.containerName : undefined;
            inputs["databaseName"] = args ? args.databaseName : undefined;
            inputs["identity"] = args ? args.identity : undefined;
            inputs["location"] = args ? args.location : undefined;
            inputs["options"] = args ? args.options : undefined;
            inputs["resource"] = args ? args.resource : undefined;
            inputs["resourceGroupName"] = args ? args.resourceGroupName : undefined;
            inputs["storedProcedureName"] = args ? args.storedProcedureName : undefined;
            inputs["tags"] = args ? args.tags : undefined;
            inputs["name"] = undefined /*out*/;
            inputs["type"] = undefined /*out*/;
        } else {
            inputs["identity"] = undefined /*out*/;
            inputs["location"] = undefined /*out*/;
            inputs["name"] = undefined /*out*/;
            inputs["resource"] = undefined /*out*/;
            inputs["tags"] = undefined /*out*/;
            inputs["type"] = undefined /*out*/;
        }
        if (!opts.version) {
            opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()});
        }
        const aliasOpts = { aliases: [{ type: "azure-nextgen:documentdb/v20210301preview:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/latest:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/latest:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20190801:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20190801:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20191212:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20191212:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20200301:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20200301:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20200401:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20200401:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20200601preview:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20200601preview:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20200901:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20200901:SqlResourceSqlStoredProcedure" }, { type: "azure-native:documentdb/v20210115:SqlResourceSqlStoredProcedure" }, { type: "azure-nextgen:documentdb/v20210115:SqlResourceSqlStoredProcedure" }] };
        opts = pulumi.mergeOptions(opts, aliasOpts);
        super(SqlResourceSqlStoredProcedure.__pulumiType, name, inputs, opts);
    }
}


/**
 * The set of arguments for constructing a SqlResourceSqlStoredProcedure resource.
 */
export interface SqlResourceSqlStoredProcedureArgs {
    /**
     * Cosmos DB database account name.
     */
    readonly accountName: pulumi.Input<string>;
    /**
     * Cosmos DB container name.
     */
    readonly containerName: pulumi.Input<string>;
    /**
     * Cosmos DB database name.
     */
    readonly databaseName: pulumi.Input<string>;
    /**
     * Identity for the resource.
     */
    readonly identity?: pulumi.Input<inputs.documentdb.v20210301preview.ManagedServiceIdentity>;
    /**
     * The location of the resource group to which the resource belongs.
     */
    readonly location?: pulumi.Input<string>;
    /**
     * A key-value pair of options to be applied for the request. This corresponds to the headers sent with the request.
     */
    readonly options?: pulumi.Input<inputs.documentdb.v20210301preview.CreateUpdateOptions>;
    /**
     * The standard JSON format of a storedProcedure
     */
    readonly resource: pulumi.Input<inputs.documentdb.v20210301preview.SqlStoredProcedureResource>;
    /**
     * The name of the resource group. The name is case insensitive.
     */
    readonly resourceGroupName: pulumi.Input<string>;
    /**
     * Cosmos DB storedProcedure name.
     */
    readonly storedProcedureName?: pulumi.Input<string>;
    /**
     * Tags are a list of key-value pairs that describe the resource. These tags can be used in viewing and grouping this resource (across resource groups). A maximum of 15 tags can be provided for a resource. Each tag must have a key no greater than 128 characters and value no greater than 256 characters. For example, the default experience for a template type is set with "defaultExperience": "Cassandra". Current "defaultExperience" values also include "Table", "Graph", "DocumentDB", and "MongoDB".
     */
    readonly tags?: pulumi.Input<{[key: string]: pulumi.Input<string>}>;
}


/**
     * Get an existing SqlResourceSqlStoredProcedure resource's state with the given name, ID, and optional extra
     * properties used to qualify the lookup.
     *
     * @param name The _unique_ name of the resulting resource.
     * @param id The _unique_ provider ID of the resource to lookup.
     * @param opts Optional settings to control the behavior of the CustomResource.
     */
public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): SqlResourceSqlStoredProcedure {
        return new SqlResourceSqlStoredProcedure(name, undefined as any, { ...opts, id: id });
    }


/**
     * Returns true if the given object is an instance of SqlResourceSqlStoredProcedure.  This is designed to work even
     * when multiple copies of the Pulumi SDK have been loaded into the same process.
     */
public static isInstance(obj: any): obj is SqlResourceSqlStoredProcedure {
        if (obj === undefined || obj === null) {
            return false;
        }
        return obj['__pulumiType'] === SqlResourceSqlStoredProcedure.__pulumiType;
    }


(p) => {
                this.updateChunkProgress(p.loaded, chunkInfo.index);
            }


export default class Local extends Chunk {
    protected async uploadChunk(chunkInfo: ChunkInfo) {
        return localUploadChunk(
            this.task.session?.sessionID!,
            chunkInfo,
            (p) => {
                this.updateChunkProgress(p.loaded, chunkInfo.index);
            },
            this.cancelToken.token
        );
    }
}


protected async uploadChunk(chunkInfo: ChunkInfo) {
        return localUploadChunk(
            this.task.session?.sessionID!,
            chunkInfo,
            (p) => {
                this.updateChunkProgress(p.loaded, chunkInfo.index);
            },
            this.cancelToken.token
        );
    }


export function SideBar(props: SideBarProps) {
  const [genres, setGenres] = useState<GenreResponseProps[]>([]);

  useEffect(() => {
    api.get<GenreResponseProps[]>('genres').then(response => {
      setGenres(response.data);
    });
  }, []);

  return (

    Watch
Me

      {genres.map(genre => (
        <Button
          key={String(genre.id)}
          title={genre.title}
          iconName={genre.name}
          onClick={() => props.handleClickButton(genre.id)}


genre => (
        <Button
          key={String(genre.id


interface SideBarProps {
  handleClickButton: (id: number) => void;
  selectedGenreId: number;
}


export class UserService {

    private readonly userDao: UserDao;

    constructor() {
        this.userDao = new UserDao();
    }

    @Transactional()
    public async mergeCreateWithT(name: string) {
        await this.createWithT(name + '_1');
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }

    @Transactional()
    public async mergeCreate2WithT(name: string) {
        await this.create(name + '_1');
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }

    @Transactional()
    public async nestCreateWithT(name: string) {
        await this.userDao.create({ name: name + '_1' });
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }

    public async nestCreate(name: string) {
        await this.userDao.create({ name: name + '_1' });
        await this.create(name + '_222222222222222222222222222222222222222');
    }

    public async create(name: string) {
        return this.userDao.create({ name });
    }

    public async findAll() {
        return this.userDao.findAll();
    }

    @Transactional()
    public async createWithT(name: string) {
        return this.userDao.create({ name });
    }

    @Transactional()
    public async findAllWithT() {
        return this.userDao.findAll();
    }

}


@Transactional()
    public async mergeCreateWithT(name: string) {
        await this.createWithT(name + '_1');
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }


@Transactional()
    public async mergeCreate2WithT(name: string) {
        await this.create(name + '_1');
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }


@Transactional()
    public async nestCreateWithT(name: string) {
        await this.userDao.create({ name: name + '_1' });
        await this.createWithT(name + '_222222222222222222222222222222222222222');
    }


public async nestCreate(name: string) {
        await this.userDao.create({ name: name + '_1' });
        await this.create(name + '_222222222222222222222222222222222222222');
    }


public async create(name: string) {
        return this.userDao.create({ name });
    }


public async findAll() {
        return this.userDao.findAll();
    }


@Transactional()
    public async createWithT(name: string) {
        return this.userDao.create({ name });
    }


@Transactional()
    public async findAllWithT() {
        return this.userDao.findAll();
    }


/**
 * Helper class for generation of common data.
 */
class Generator
{
  static baseColors = [
    "#0-8-a-", "#0-8-c-", "#0-a-a-", "#0-a-c-", "#1-7-5-", "#1-9-5-", "#1-9-3-",
    "#1-9-9-", "#1-b-7-", "#2-6-c-", "#2-8-a-", "#2-8-c-", "#3-9-3-", "#3-9-5-",
    "#3-b-7-", "#4-2-8-", "#4-4-a-", "#4-6-8-", "#4-8-a-", "#4-8-c-", "#5-b-5-",
    "#5-b-7-", "#5-b-b-", "#6-4-a-", "#6-6-8-", "#6-6-a-", "#6-6-c-", "#6-8-a-",
    "#6-8-c-", "#6-a-c-", "#8-2-c-", "#8-4-a-", "#8-6-8-", "#8-6-a-", "#8-8-a-",
    "#8-8-c-", "#8-8-f-", "#9-7-b-", "#9-7-d-", "#a-6-6-", "#a-6-8-", "#a-8-8-",
    "#a-8-a-", "#a-a-8-", "#a-a-a-", "#a-a-c-", "#b-3-5-", "#c-4-8-", "#c-6-8-",
    "#c-6-a-", "#c-6-c-", "#c-8-a-", "#c-8-c-", "#c-8-f-", "#c-a-a-", "#c-a-c-",
    "#d-3-3-", "#d-3-5-", "#d-5-3-", "#d-5-5-", "#f-5-3-", "#f-6-8-", "#f-7-1-",
    "#f-7-5-", "#f-8-8-", "#f-8-6-", "#f-9-1-", "#f-9-3-", "#f-9-5-", "#f-9-7-",
    "#f-9-9-", "#f-9-9-", "#f-a-8-", "#f-a-a-", "#f-b-8-"];

  /**
   * Get a numeric identifier between 1 and 10000000.
   */

  static getId(): number
  {
    return this.getNum(10000000) + 1
  }
  /**
   * Get a random color with pre-defined balance of color.
   */

  static getColor(): string
  {
    let base = this.baseColors[this.getNum(this.baseColors.length)];
    let A = this.getNum(2) == 0 ? "0" : "8";
    let B = this.getNum(2) == 0 ? "0" : "8";
    let C = this.getNum(2) == 0 ? "0" : "8";
    base = base.replace("-", A);
    base = base.replace("-", B);
    base = base.replace("-", C);
    return base;
  }

  /**
   * Get a random number between 0 and max.
   * @param  {number} max Max number.
   */

  static getNum(max: number): number
  {
    return Math.floor(Math.random() * max);
  }

  static getName(): string
  {
    return faker.name.findName();
  }

  static getEmail(): string
  {
    return faker.internet.email();
  }

  static getImageUrl(): string
  {
    return faker.image.imageUrl();
  }

  static getNoun(): string
  {
    return `${faker.hacker.adjective()} ${faker.hacker.noun()}`;
  }

  static getBoolean(): string
  {
    return faker.random.boolean();
  }

  static getDate(): string
  {
    return faker.date.recent();
  }

  static getWord(): string
  {
    return faker.lorem.word()
  }

  static getSentence(): string
  {
    return faker.lorem.sentence()
  }

  static getParagraph(): string
  {
    return faker.lorem.paragraph()
  }

}


/**
   * Get a numeric identifier between 1 and 10000000.
   */
static getId(): number
  {
    return this.getNum(10000000) + 1
  }


/**
   * Get a random color with pre-defined balance of color.
   */
static getColor(): string
  {
    let base = this.baseColors[this.getNum(this.baseColors.length)];
    let A = this.getNum(2) == 0 ? "0" : "8";
    let B = this.getNum(2) == 0 ? "0" : "8";
    let C = this.getNum(2) == 0 ? "0" : "8";
    base = base.replace("-", A);
    base = base.replace("-", B);
    base = base.replace("-", C);
    return base;
  }


/**
   * Get a random number between 0 and max.
   * @param  {number} max Max number.
   */
static getNum(max: number): number
  {
    return Math.floor(Math.random() * max);
  }


static getName(): string
  {
    return faker.name.findName();
  }


static getEmail(): string
  {
    return faker.internet.email();
  }


static getImageUrl(): string
  {
    return faker.image.imageUrl();
  }


static getNoun(): string
  {
    return `${faker.hacker.adjective()} ${faker.hacker.noun()}`;
  }


static getBoolean(): string
  {
    return faker.random.boolean();
  }


static getDate(): string
  {
    return faker.date.recent();
  }


static getWord(): string
  {
    return faker.lorem.word()
  }


static getSentence(): string
  {
    return faker.lorem.sentence()
  }


static getParagraph(): string
  {
    return faker.lorem.paragraph()
  }


<T extends object>(): Partial<T> => {
  // server side rendering
  if (typeof window === 'undefined') {
    return {};
  }

  const params = new URLSearchParams(window.location.search);

  return new Proxy(params, {
    get(target, prop) {
      return target.get(prop as string) || undefined;
    },
  }) as T;
}


get(target, prop) {
      return target.get(prop as string) || undefined;
    }


() => this.router.navigate(['admin', 'games', this.gameId, 'media'])


@Component({
  selector: 'app-admin-games-media-form',
  templateUrl: './admin-games-media-form.component.html',
})
export class AdminGamesMediaFormComponent implements OnInit {

  @ViewChild('form') form: NgForm;

  gameId: number;
  mediaId: number;

  isEditing = false;
  formInfo: GameMedia = {} as GameMedia;

  constructor(
    private readonly gameMediaService: GameMediaService,
    private readonly router: Router,
    private readonly route: ActivatedRoute,
  ) { }

  ngOnInit() {
    this.gameId = this.route.snapshot.params['gameId'];

    if (this.route.snapshot.params['id']) {
      this.mediaId = this.route.snapshot.params['id'];
      this.formInfo = this.route.snapshot.data['gameMedia'];
      this.isEditing = true;
    }
  }

  isValid(): boolean {
    FormUtil.touchForm(this.form.control);
    return this.form.valid;
  }

  send() {
    if (!this.isValid()) { return; }

    if (this.isEditing) {
      this.gameMediaService.patchGameMedia(this.formInfo, this.mediaId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );

    } else {
      this.gameMediaService.postGameMedia(this.formInfo, this.gameId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );
    }
  }

  delete() {
    if (confirm('Are you SURE you want to delete this media?')) {
      this.gameMediaService.deleteGameMedia(this.mediaId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );
    }
  }
}


ngOnInit() {
    this.gameId = this.route.snapshot.params['gameId'];

    if (this.route.snapshot.params['id']) {
      this.mediaId = this.route.snapshot.params['id'];
      this.formInfo = this.route.snapshot.data['gameMedia'];
      this.isEditing = true;
    }
  }


isValid(): boolean {
    FormUtil.touchForm(this.form.control);
    return this.form.valid;
  }


send() {
    if (!this.isValid()) { return; }

    if (this.isEditing) {
      this.gameMediaService.patchGameMedia(this.formInfo, this.mediaId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );

    } else {
      this.gameMediaService.postGameMedia(this.formInfo, this.gameId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );
    }
  }


delete() {
    if (confirm('Are you SURE you want to delete this media?')) {
      this.gameMediaService.deleteGameMedia(this.mediaId)
        .subscribe( () => this.router.navigate(['admin', 'games', this.gameId, 'media']) );
    }
  }


export default function () {
    var app: express.Express = express();

    app.use(cors());
    app.options('*', cors());

    for (let model of config.globFiles(config.models)) {
        require(path.resolve(model));
    }

    if (config.useMongo) {
        mongoose.connect(config.mongodb, {
            promiseLibrary: global.Promise
        }).catch(() => { console.log('Error connecting to mongos'); });
    }

    app.set('views', path.join(__dirname, '../../src/views'));
    app.set('view engine', 'pug');

    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, '../../src/public')));

    for (let route of config.globFiles(config.routes)) {
        require(path.resolve(route)).default(app);
    }

    app.use((req: express.Request, res: express.Response, next: Function): void => {
        let err: Error = new Error('Not Found');
        next(err);
    });

    return app;
}


() => { console.log('Error connecting to mongos'); }


(req: express.Request, res: express.Response, next: Function): void => {
        let err: Error = new Error('Not Found');
        next(err);
    }


(id) => { overrides.overrideElement(id, app); }


(id) => { overrides.overrideElement(id, ovrApp); }


(id) => { newIds.add(id); }


(id) => { overrideIds.add(id); }


(id) => { otherIds.delete(id); }


/** JSON representation of an appearance override in an [[EmphasizeElementsProps]].
 * @see [[EmphasizeElements]].
 * @public
 */
export interface AppearanceOverrideProps {
  overrideType?: FeatureOverrideType;
  color?: ColorDefProps;
  ids?: Id64Array;
}


/** JSON representation of an [[EmphasizeElements]].
 * @public
 */
export interface EmphasizeElementsProps {
  neverDrawn?: Id64Array;
  alwaysDrawn?: Id64Array;
  isAlwaysDrawnExclusive?: boolean;
  alwaysDrawnExclusiveEmphasized?: Id64Array;
  defaultAppearance?: FeatureSymbology.AppearanceProps;
  appearanceOverride?: AppearanceOverrideProps[];
  wantEmphasis?: boolean;
}


/** Options for overriding element appearance.
 * @see [[EmphasizeElements]]
 * @see [[AppearanceOverrideProps]]
 * @public
 */
export enum FeatureOverrideType {
  /** Override color only. */
  ColorOnly,
  /** Override alpha only. */
  AlphaOnly,
  /** Override both color and alpha. */
  ColorAndAlpha,
}


/** Establish active feature overrides to emphasize elements and apply color/transparency overrides.
   * @see [[Viewport.featureOverrideProvider]]
   */
public addFeatureOverrides(overrides: FeatureSymbology.Overrides, vp: Viewport): void {
    const emphasizedElements = this.getEmphasizedElements(vp);
    if (undefined !== emphasizedElements) {
      overrides.setDefaultOverrides(this._defaultAppearance!);
      const app = this.wantEmphasis ? this._emphasizedAppearance : FeatureSymbology.Appearance.defaults;
      emphasizedElements.forEach((id) => { overrides.overrideElement(id, app); });
    }
    const overriddenElements = this.getOverriddenElements();
    if (undefined !== overriddenElements) {
      if (undefined !== this._defaultAppearance)
        overrides.setDefaultOverrides(this._defaultAppearance);
      for (const [key, ids] of overriddenElements) {
        const ovrApp = this.createAppearanceFromKey(key);
        ids.forEach((id) => { overrides.overrideElement(id, ovrApp); });
      }
    }
  }


/** @internal */
protected createAppearanceFromKey(key: number): FeatureSymbology.Appearance {
    let transparency: number | undefined;
    let rgb: RgbColor | undefined;

    if (key < 0) {
      transparency = Math.abs(key);
    } else {
      const color = ColorDef.fromJSON(key);
      rgb = RgbColor.fromColorDef(color);
      if (0 !== color.getAlpha()) // Fully transparent signifies to use color only...
        transparency = color.getTransparency() / 255;
    }

    const emphasized = this.wantEmphasis ? true : undefined;
    return FeatureSymbology.Appearance.fromJSON({ rgb, transparency, emphasized });
  }


/** Get override key from color and override type */
public createOverrideKey(color: ColorDef, override: FeatureOverrideType): number | undefined {
    const colorValues = color.colors;
    switch (override) {
      case FeatureOverrideType.ColorAndAlpha:
        return 255 === colorValues.t ? undefined : color.tbgr; // Hiding elements should be done using neverDrawn, not transparency...
      case FeatureOverrideType.ColorOnly:
        return ColorDef.from(colorValues.r, colorValues.g, colorValues.b, 255).tbgr;
      case FeatureOverrideType.AlphaOnly:
        return -(colorValues.t / 255);
    }
  }


/** Get color and override type for the given key. */
public getOverrideFromKey(key: number): { overrideType: FeatureOverrideType, color: ColorDef } {
    let overrideType;
    let color;

    if (key < 0) {
      color = ColorDef.from(0, 0, 0, 255 * Math.abs(key));
      overrideType = FeatureOverrideType.AlphaOnly;
    } else {
      color = ColorDef.fromJSON(key);
      if (0 === color.getAlpha()) {
        color = color.withAlpha(255);
        overrideType = FeatureOverrideType.ColorOnly;
      } else {
        overrideType = FeatureOverrideType.ColorAndAlpha;
      }
    }

    return { overrideType, color };
  }


/** Create default appearance to use for emphasizeElements when not supplied by caller. */
public createDefaultAppearance(): FeatureSymbology.Appearance {
    return FeatureSymbology.Appearance.fromJSON({
      rgb: new RgbColor(0xe4, 0xe4, 0xe4),
      transparency: 0.8,
      nonLocatable: true,
    });
  }


/** Get the IDs of the currently never drawn elements. */
public getNeverDrawnElements(vp: Viewport): Id64Set | undefined { return (undefined !== vp.neverDrawn && 0 !== vp.neverDrawn.size ? vp.neverDrawn : undefined); }


/** Get the IDs of the currently always drawn elements. */
public getAlwaysDrawnElements(vp: Viewport): Id64Set | undefined { return (undefined !== vp.alwaysDrawn && 0 !== vp.alwaysDrawn.size ? vp.alwaysDrawn : undefined); }


/** Get the IDs of the currently hidden elements. */
public getHiddenElements(vp: Viewport): Id64Set | undefined { return this.getNeverDrawnElements(vp); }


/** Get the IDs of the currently isolated elements. */
public getIsolatedElements(vp: Viewport): Id64Set | undefined { return (vp.isAlwaysDrawnExclusive ? this.getAlwaysDrawnElements(vp) : undefined); }


/** Get the IDs of the currently emphasized isolated elements. */
public getEmphasizedIsolatedElements(): Id64Set | undefined { return (undefined !== this._defaultAppearance && undefined !== this._emphasizeIsolated && 0 !== this._emphasizeIsolated.size ? this._emphasizeIsolated : undefined); }


/** Get the IDs of the currently emphasized elements. */
public getEmphasizedElements(vp: Viewport): Id64Set | undefined { return (undefined !== this.getEmphasizedIsolatedElements() ? this._emphasizeIsolated : (undefined !== this._defaultAppearance && !vp.isAlwaysDrawnExclusive ? this.getAlwaysDrawnElements(vp) : undefined)); }


/** Get the map of current elements with color/transparency overrides. */
public getOverriddenElements(): Map<number, Id64Set> | undefined { return (undefined !== this._overrideAppearance && 0 !== this._overrideAppearance.size ? this._overrideAppearance : undefined); }


/** Get the IDs of current elements with the specified color/transparency override. */
public getOverriddenElementsByKey(key: number): Id64Set | undefined { return (undefined !== this._overrideAppearance ? this._overrideAppearance.get(key) : undefined); }


/** Clear never drawn elements.
   * @return false if nothing to clear.
   */
public clearNeverDrawnElements(vp: Viewport): boolean {
    if (undefined === this.getNeverDrawnElements(vp))
      return false;
    vp.clearNeverDrawn();
    return true;
  }


/** Clear always drawn elements.
   * @return false if nothing to clear.
   */
public clearAlwaysDrawnElements(vp: Viewport): boolean {
    if (undefined === this.getAlwaysDrawnElements(vp))
      return false;
    vp.clearAlwaysDrawn();
    return true;
  }


/** Clear hidden elements.
   * @return false if nothing to clear.
   */
public clearHiddenElements(vp: Viewport): boolean {
    return this.clearNeverDrawnElements(vp);
  }


/** Clear isolated elements.
   * @return false if nothing to clear.
   */
public clearIsolatedElements(vp: Viewport): boolean {
    if (undefined === this.getIsolatedElements(vp))
      return false;
    if (this.clearEmphasizedIsolatedElements(vp, true))
      return true;
    return this.clearAlwaysDrawnElements(vp);
  }


/** Clear emphasized elements.
   * @return false if nothing to clear.
   */
public clearEmphasizedElements(vp: Viewport): boolean {
    if (undefined === this.getEmphasizedElements(vp))
      return false;
    if (this.clearEmphasizedIsolatedElements(vp, false))
      return true;
    if (!this.clearAlwaysDrawnElements(vp))
      return false;
    this._defaultAppearance = undefined;
    return true;
  }


/** Clear emphasized isolated elements.
   * @return false if nothing to clear.
   */
public clearEmphasizedIsolatedElements(vp: Viewport, setToAlwaysDrawn: boolean): boolean {
    const emphasizedIsolated = this.getEmphasizedIsolatedElements();
    this._emphasizeIsolated = undefined; // Always clear in case default appearance was unset...
    if (undefined === emphasizedIsolated)
      return false;
    if (setToAlwaysDrawn && this.setAlwaysDrawnElements(emphasizedIsolated, vp, false))
      return true;
    this._defaultAppearance = undefined;
    vp.setFeatureOverrideProviderChanged();
    return true;
  }


/** Clear elements with color/transparency overrides. Specify key to clear only a single override.
   * @return false if nothing to clear.
   */
public clearOverriddenElements(vp: Viewport, key?: number): boolean {
    if (undefined === this._overrideAppearance)
      return false;
    if (undefined !== key) {
      if (!this._overrideAppearance.delete(key))
        return false;
    } else {
      this._overrideAppearance = undefined;
    }
    vp.setFeatureOverrideProviderChanged();
    return true;
  }


/** @internal */
protected updateIdSet(ids: Id64Arg, replace: boolean, existingIds?: Id64Set): Id64Set | undefined {
    const newIds = new Set<string>();
    Id64.toIdSet(ids).forEach((id) => { newIds.add(id); });
    if (0 === newIds.size)
      return undefined;
    const oldSize = (!replace && undefined !== existingIds ? existingIds.size : 0);
    if (0 !== oldSize && undefined !== existingIds)
      for (const id of existingIds)
        newIds.add(id);
    if (oldSize === newIds.size)
      return undefined;
    return newIds;
  }


/** Set the element IDs to be never drawn.
   * @param ids The IDs of the elements to never draw.
   * @param vp The viewport.
   * @param replace true to replace currently hidden elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.neverDrawn]]
   * @internal
   */
public setNeverDrawnElements(ids: Id64Arg, vp: Viewport, replace: boolean = true): boolean {
    const hiddenIds = this.updateIdSet(ids, replace, vp.neverDrawn);
    if (undefined === hiddenIds)
      return false;
    vp.setNeverDrawn(hiddenIds);
    return true;
  }


/** Set the element IDs to be always drawn.
   * @param ids The IDs of the elements to always draw.
   * @param vp The viewport.
   * @param exclusive If true, *only* the specified elements will be drawn.
   * @param replace true to replace currently always drawn elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.alwaysDrawn]]
   * @see [[Viewport.isAlwaysDrawnExclusive]]
   * @internal
   */
public setAlwaysDrawnElements(ids: Id64Arg, vp: Viewport, exclusive: boolean = true, replace: boolean = true): boolean {
    const visibleIds = this.updateIdSet(ids, replace, vp.alwaysDrawn);
    if (undefined === visibleIds)
      return false;
    vp.setAlwaysDrawn(visibleIds, exclusive);
    return true;
  }


/** Set the element IDs to be never drawn.
   * @param ids The IDs of the elements to never draw.
   * @param vp The viewport.
   * @param replace true to replace currently hidden elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.neverDrawn]]
   */
public hideElements(ids: Id64Arg, vp: Viewport, replace: boolean = false): boolean {
    return this.setNeverDrawnElements(ids, vp, replace);
  }


/** Set the currently selected elements to be never drawn.
   * @param vp The viewport.
   * @param replace true to replace currently hidden elements (if any) or false to add to the existing set.
   * @param clearSelection true to clear current selection after setting appearance override, false to leave selected.
   * @return true if overrides were changed.
   * @see [[Viewport.neverDrawn]]
   */
public hideSelectedElements(vp: Viewport, replace: boolean = false, clearSelection: boolean = true): boolean {
    const selection = vp.view.iModel.selectionSet;
    if (!selection.isActive || !this.hideElements(selection.elements, vp, replace))
      return false;
    if (clearSelection)
      selection.emptyAll();
    return true;
  }


/** Set the element IDs to be always drawn exclusively.
   * @param ids The IDs of the elements to always draw.
   * @param vp The viewport.
   * @param replace true to replace currently isolated elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.alwaysDrawn]]
   * @see [[Viewport.isAlwaysDrawnExclusive]]
   */
public isolateElements(ids: Id64Arg, vp: Viewport, replace: boolean = true): boolean {
    const wasEmphasized = (undefined !== this.getEmphasizedElements(vp));
    if (!this.setAlwaysDrawnElements(ids, vp, true, replace))
      return false;
    if (wasEmphasized)
      this._defaultAppearance = this._emphasizeIsolated = undefined; // Don't clear defaultAppearance unless it was established by emphasize...
    return true;
  }


/** Set the currently selected elements to be always drawn exclusively.
   * @param vp The viewport.
   * @param replace true to replace currently isolated elements (if any) or false to add to the existing set.
   * @param clearSelection true to clear current selection after setting appearance override, false to leave selected.
   * @return true if overrides were changed.
   * @see [[Viewport.alwaysDrawn]]
   * @see [[Viewport.isAlwaysDrawnExclusive]]
   */
public isolateSelectedElements(vp: Viewport, replace: boolean = true, clearSelection: boolean = true): boolean {
    const selection = vp.view.iModel.selectionSet;
    if (!selection.isActive || !this.isolateElements(selection.elements, vp, replace))
      return false;
    if (clearSelection)
      selection.emptyAll();
    return true;
  }


/** Set the element IDs to be always drawn normally with all other elements in the view overridden to draw using a default appearance..
   * @param ids The IDs of the elements to always draw.
   * @param vp The viewport.
   * @param defaultAppearance Optional default appearance, uses non-locatable transparent grey if not specified.
   * @param replace true to replace currently overridden elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.alwaysDrawn]]
   * @see [[Viewport.isAlwaysDrawnExclusive]]
   */
public emphasizeElements(ids: Id64Arg, vp: Viewport, defaultAppearance?: FeatureSymbology.Appearance, replace: boolean = true): boolean {
    if (undefined !== this.getIsolatedElements(vp)) {
      const emphasizeIds = this.updateIdSet(ids, replace, this._emphasizeIsolated);
      if (undefined === emphasizeIds)
        return false;
      this._emphasizeIsolated = emphasizeIds;
      vp.setFeatureOverrideProviderChanged();
    } else {
      if (!this.setAlwaysDrawnElements(ids, vp, false, replace))
        return false;
      this._emphasizeIsolated = undefined;
    }
    this._defaultAppearance = (undefined === defaultAppearance ? this.createDefaultAppearance() : defaultAppearance);
    return true;
  }


/** Set the currently selected elements to be always drawn normally with all other elements in the view overridden to draw using a default appearance.
   * @param vp The viewport.
   * @param defaultAppearance Optional default appearance, uses transparent grey if not specified.
   * @param replace true to replace currently overridden elements (if any) or false to add to the existing set.
   * @param clearSelection true to clear current selection after setting appearance override, false to leave selected.
   * @return true if overrides were changed.
   * @see [[Viewport.alwaysDrawn]]
   * @see [[Viewport.isAlwaysDrawnExclusive]]
   */
public emphasizeSelectedElements(vp: Viewport, defaultAppearance?: FeatureSymbology.Appearance, replace: boolean = true, clearSelection: boolean = true): boolean {
    const selection = vp.view.iModel.selectionSet;
    if (!selection.isActive || !this.emphasizeElements(selection.elements, vp, defaultAppearance, replace))
      return false;

    if (clearSelection)
      selection.emptyAll();

    return true;
  }


/** Set the element IDs to display with a color/transparency override.
   * @param ids The IDs of the elements.
   * @param vp The viewport.
   * @param color ColorDef to specify override rgb and alpha.
   * @param override Whether to use color and alpha, only color, or only alpha from the supplied ColorDef.
   * @param replace true to replace currently overridden elements (if any) or false to add to the existing set.
   * @return true if overrides were changed.
   * @see [[Viewport.featureOverrideProvider]]
   */
public overrideElements(ids: Id64Arg, vp: Viewport, color: ColorDef, override: FeatureOverrideType = FeatureOverrideType.ColorOnly, replace: boolean = false): boolean {
    const ovrKey = this.createOverrideKey(color, override);
    if (undefined === ovrKey)
      return false;

    const overrideIds = new Set<string>();
    Id64.toIdSet(ids).forEach((id) => { overrideIds.add(id); });
    if (0 === overrideIds.size)
      return false;

    const existingIds = (!replace ? this.getOverriddenElementsByKey(ovrKey) : undefined);
    const oldSize = (undefined !== existingIds ? existingIds.size : 0);
    if (0 !== oldSize && undefined !== existingIds)
      for (const id of existingIds)
        overrideIds.add(id);

    if (oldSize === overrideIds.size)
      return false;

    if (undefined === this._overrideAppearance) {
      this._overrideAppearance = new Map<number, Id64Set>();
    } else {
      for (const [key, otherIds] of this._overrideAppearance) {
        if (key === ovrKey) // Make sure these ids are unique to this color/transparency key...
          continue;

        Id64.toIdSet(ids).forEach((id) => { otherIds.delete(id); });
        if (0 !== otherIds.size)
          continue;

        this._overrideAppearance.delete(key);
      }
    }

    this._overrideAppearance.set(ovrKey, overrideIds);
    vp.setFeatureOverrideProviderChanged();

    return true;
  }


/** Set the currently selected elements to display with a color/transparency override.
   * @param vp The viewport.
   * @param color ColorDef to specify override rgb and alpha.
   * @param override Whether to use color and alpha, only color, or only alpha from the supplied ColorDef.
   * @param replace true to replace currently overridden elements (if any) or false to add to the existing set.
   * @param clearSelection true to clear current selection after setting appearance override, false to leave selected.
   * @return true if overrides were changed.
   * @see [[Viewport.featureOverrideProvider]]
   */
public overrideSelectedElements(vp: Viewport, color: ColorDef, override: FeatureOverrideType = FeatureOverrideType.ColorOnly, replace: boolean = false, clearSelection: boolean = true): boolean {
    const selection = vp.view.iModel.selectionSet;
    if (!selection.isActive || !this.overrideElements(selection.elements, vp, color, override, replace))
      return false;
    if (clearSelection)
      selection.emptyAll();
    return true;
  }


/** @return true if provider is currently overriding the display of any elements. */
public isActive(vp: Viewport): boolean { return (undefined !== this.getNeverDrawnElements(vp) || undefined !== this.getAlwaysDrawnElements(vp) || undefined !== this.getOverriddenElements()); }


/** Serialize to JSON representation.
   * @see [[EmphasizeElements.fromJSON]]
   */
public toJSON(vp: Viewport): EmphasizeElementsProps {
    const props: EmphasizeElementsProps = {};
    const neverDrawn = this.getNeverDrawnElements(vp);
    if (undefined !== neverDrawn)
      props.neverDrawn = [...neverDrawn];

    const alwaysDrawn = this.getAlwaysDrawnElements(vp);
    if (undefined !== alwaysDrawn)
      props.alwaysDrawn = [...alwaysDrawn];

    if (vp.isAlwaysDrawnExclusive)
      props.isAlwaysDrawnExclusive = true; // isolate

    const alwaysDrawnExclusiveEmphasized = this.getEmphasizedIsolatedElements();
    if (undefined !== alwaysDrawnExclusiveEmphasized)
      props.alwaysDrawnExclusiveEmphasized = [...alwaysDrawnExclusiveEmphasized];

    if (undefined !== this.defaultAppearance)
      props.defaultAppearance = this.defaultAppearance; // emphasize (or specifically set for override)

    const overriddenElements = this.getOverriddenElements();
    if (undefined !== overriddenElements) {
      const appearanceOverride: AppearanceOverrideProps[] = [];
      for (const [key, ovrIds] of overriddenElements) {
        const { color, overrideType } = { ...this.getOverrideFromKey(key) };
        const ids = [...ovrIds];
        appearanceOverride.push({ overrideType, color: color.toJSON(), ids });
      }

      props.appearanceOverride = appearanceOverride;
    }

    if (this.wantEmphasis)
      props.wantEmphasis = true;

    return props;
  }


/** Initialize from JSON representation.
   * @see [[EmphasizeElements.toJSON]]
   */
public fromJSON(props: EmphasizeElementsProps, vp: Viewport): boolean {
    let changed = false;
    if (undefined !== props.neverDrawn && this.setNeverDrawnElements(new Set<string>(props.neverDrawn), vp, true))
      changed = true;

    if (undefined !== props.alwaysDrawn && this.setAlwaysDrawnElements(new Set<string>(props.alwaysDrawn), vp, undefined !== props.isAlwaysDrawnExclusive && props.isAlwaysDrawnExclusive))
      changed = true;

    if (undefined !== props.alwaysDrawnExclusiveEmphasized)
      this._emphasizeIsolated = new Set<string>(props.alwaysDrawnExclusiveEmphasized); // changed status determined by setAlwaysDrawnElements...

    if (undefined !== props.defaultAppearance)
      this.defaultAppearance = FeatureSymbology.Appearance.fromJSON(props.defaultAppearance); // changed status determined by setAlwaysDrawnElements or overrideElements...

    if (undefined !== props.appearanceOverride) {
      for (const ovrApp of props.appearanceOverride) {
        if (undefined === ovrApp.ids)
          continue;

        if (this.overrideElements(new Set<string>(ovrApp.ids), vp, ColorDef.fromJSON(ovrApp.color), ovrApp.overrideType, true))
          changed = true;
      }
    }

    const wantEmphasis = true === props.wantEmphasis;
    if (wantEmphasis !== this.wantEmphasis) {
      this.wantEmphasis = wantEmphasis;
      changed = true;
    }

    return changed;
  }


/** Get current [[Viewport.featureOverrideProvider]] if it's an instance of EmphasizeElements. */
public static get(vp: Viewport): EmphasizeElements | undefined {
    return (vp.featureOverrideProvider instanceof EmphasizeElements ? vp.featureOverrideProvider : undefined);
  }


/** Get or replace current [[Viewport.featureOverrideProvider]] with an instance of EmphasizeElements. */
public static getOrCreate(vp: Viewport): EmphasizeElements {
    let provider = vp.featureOverrideProvider instanceof EmphasizeElements ? vp.featureOverrideProvider : undefined;
    if (undefined === provider) {
      provider = new EmphasizeElements();
      vp.featureOverrideProvider = provider;
    }
    return provider;
  }


/** Clear current [[Viewport.featureOverrideProvider]] if it's an instance of EmphasizeElements. */
public static clear(vp: Viewport, inactiveOnly: boolean = false) {
    const provider = vp.featureOverrideProvider instanceof EmphasizeElements ? vp.featureOverrideProvider : undefined;
    if (undefined === provider || (inactiveOnly && provider.isActive))
      return;
    vp.clearNeverDrawn();
    vp.clearAlwaysDrawn();
    vp.featureOverrideProvider = undefined;
  }


RpcMethod => {
      pluginManager.addRpcMethod(() => new RpcMethod(pluginManager))
    }


() => new RpcMethod(pluginManager)


() =>
        new AdapterType({
          name: 'CytobandAdapter',
          configSchema: cytobandConfigSchema,
          AdapterClass: DataAdapter,
        })


() => {
      return new WidgetType({
        name: 'BaseFeatureWidget',
        heading: 'Feature details',
        configSchema,
        stateModel: stateModelFactory(pluginManager),
        ReactComponent: lazy(
          () => import('./BaseFeatureWidget/BaseFeatureDetail'),
        ),
      })
    }


() => import('./BaseFeatureWidget/BaseFeatureDetail')


// the core plugin, which registers types that ALL JBrowse applications are
// expected to need.
export default class CorePlugin extends Plugin {
  name = 'CorePlugin'

  install(pluginManager: PluginManager) {
    // register all our core rpc methods
    Object.values(coreRpcMethods).forEach(RpcMethod => {
      pluginManager.addRpcMethod(() => new RpcMethod(pluginManager))
    })

    pluginManager.addAdapterType(
      () =>
        new AdapterType({
          name: 'CytobandAdapter',
          configSchema: cytobandConfigSchema,
          AdapterClass: DataAdapter,
        }),
    )

    pluginManager.addWidgetType(() => {
      return new WidgetType({
        name: 'BaseFeatureWidget',
        heading: 'Feature details',
        configSchema,
        stateModel: stateModelFactory(pluginManager),
        ReactComponent: lazy(
          () => import('./BaseFeatureWidget/BaseFeatureDetail'),
        ),
      })
    })
  }
}


install(pluginManager: PluginManager) {
    // register all our core rpc methods
    Object.values(coreRpcMethods).forEach(RpcMethod => {
      pluginManager.addRpcMethod(() => new RpcMethod(pluginManager))
    })

    pluginManager.addAdapterType(
      () =>
        new AdapterType({
          name: 'CytobandAdapter',
          configSchema: cytobandConfigSchema,
          AdapterClass: DataAdapter,
        }),
    )

    pluginManager.addWidgetType(() => {
      return new WidgetType({
        name: 'BaseFeatureWidget',
        heading: 'Feature details',
        configSchema,
        stateModel: stateModelFactory(pluginManager),
        ReactComponent: lazy(
          () => import('./BaseFeatureWidget/BaseFeatureDetail'),
        ),
      })
    })
  }


() => {
    analyticsWebClientMock = {
      sendUIEvent: jest.fn(),
      sendOperationalEvent: jest.fn(),
      sendTrackEvent: jest.fn(),
      sendScreenEvent: jest.fn(),
    };
    loggerMock = createLoggerMock();
  }


() => {
    const component = mount(
      <NavigationListener client={analyticsWebClientMock} logger={loggerMock}>
        <div />
      </NavigationListener>,
    );

    const analyticsListener = component.find(AnalyticsListener);
    expect(analyticsListener.props()).toHaveProperty('channel', 'navigation');
  }


(
      {
        eventPayload,
        clientPayload,
        eventType = UI_EVENT_TYPE,
        context = [],
      }: CaseArgs,
      done: Function,
    ) => {
      const spy = jest.fn();
      const ButtonWithAnalytics = createButtonWithAnalytics(
        eventPayload,
        FabricChannel.navigation,
      );
      const AnalyticsContexts = createAnalyticsContexts(context);

      const component = mount(
        <NavigationListener client={analyticsWebClientMock} logger={loggerMock}>
          <AnalyticsContexts>
            <ButtonWithAnalytics onClick={spy} />
          </AnalyticsContexts>
        </NavigationListener>,
      );

      component.find(ButtonWithAnalytics).simulate('click');

      const mockFn =
        eventType === OPERATIONAL_EVENT_TYPE
          ? analyticsWebClientMock.sendOperationalEvent
          : analyticsWebClientMock.sendUIEvent;

      window.setTimeout(() => {
        expect((mockFn as any).mock.calls[0][0]).toMatchObject(clientPayload);
        done();
      });
    }


() => {
        expect((mockFn as any).mock.calls[0][0]).toMatchObject(clientPayload);
        done();
      }


type CaseArgs = {
  name: string;
  eventPayload: GasPurePayload;
  clientPayload: GasPurePayload;
  eventType?: string;
  context: any[];
};


@Component({
  selector: 'app-rfq',
  templateUrl: './rfq.component.html',
  styleUrls: ['./rfq.component.less']
})
export class RfqComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


_type => Course_attendance_logUpdateInput


_type => Course_attendance_logWhereUniqueInput


@TypeGraphQL.ArgsType()
export class UpdateCourse_attendance_logArgs {
  @TypeGraphQL.Field(_type => Course_attendance_logUpdateInput, {
    nullable: false
  })
  data!: Course_attendance_logUpdateInput;

  @TypeGraphQL.Field(_type => Course_attendance_logWhereUniqueInput, {
    nullable: false
  })
  where!: Course_attendance_logWhereUniqueInput;
}


function wrapNativeAccount(
  pubkey: StringPublicKey,
  account?: AccountInfo<Buffer>,
): TokenAccount | undefined {
  if (!account) {
    return undefined;
  }

  const key = new PublicKey(pubkey);

  return {
    pubkey: pubkey,
    account,
    info: {
      address: key,
      mint: WRAPPED_SOL_MINT,
      owner: key,
      amount: new u64(account.lamports),
      delegate: null,
      delegatedAmount: new u64(0),
      isInitialized: true,
      isFrozen: false,
      isNative: true,
      rentExemptReserve: null,
      closeAuthority: null,
    },
  };
}


export function AccountsProvider({ children = null as any }) {
  const connection = useConnection();
  const { publicKey } = useWallet();
  const [tokenAccounts, setTokenAccounts] = useState<TokenAccount[]>([]);
  const [userAccounts, setUserAccounts] = useState<TokenAccount[]>([]);
  const { nativeAccount } = UseNativeAccount();
  const walletKey = publicKey?.toBase58();

  const selectUserAccounts = useCallback(() => {
    return cache
      .byParser(TokenAccountParser)
      .map(id => cache.get(id))
      .filter(a => a && a.info.owner.toBase58() === walletKey)
      .map(a => a as TokenAccount);
  }, [walletKey]);

  useEffect(() => {
    const accounts = selectUserAccounts().filter(
      a => a !== undefined,
    ) as TokenAccount[];
    setUserAccounts(accounts);
  }, [nativeAccount, tokenAccounts, selectUserAccounts]);

  useEffect(() => {
    const subs: number[] = [];
    cache.emitter.onCache(args => {
      if (args.isNew && args.isActive) {
        let id = args.id;
        let deserialize = args.parser;
        connection.onAccountChange(new PublicKey(id), info => {
          cache.add(id, info, deserialize);
        });
      }
    });

    return () => {
      subs.forEach(id => connection.removeAccountChangeListener(id));
    };
  }, [connection]);

  useEffect(() => {
    if (!connection || !publicKey) {
      setTokenAccounts([]);
    } else {
      precacheUserTokenAccounts(connection, publicKey).then(() => {
        setTokenAccounts(selectUserAccounts());
      });

      // This can return different types of accounts: token-account, mint, multisig
      // TODO: web3.js expose ability to filter.
      // this should use only filter syntax to only get accounts that are owned by user
      const tokenSubID = connection.onProgramAccountChange(
        programIds().token,
        info => {
          // TODO: fix type in web3.js
          const id = info.accountId as unknown as string;
          // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
          if (info.accountInfo.data.length === AccountLayout.span) {
            const data = deserializeAccount(info.accountInfo.data);

            if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
              cache.add(id, info.accountInfo, TokenAccountParser);
              setTokenAccounts(selectUserAccounts());
            }
          }
        },
        'singleGossip',
      );

      return () => {
        connection.removeProgramAccountChangeListener(tokenSubID);
      };
    }
  }, [connection, publicKey, selectUserAccounts]);

  return (
    <AccountsContext.Provider
      value={{
        userAccounts,
        nativeAccount,
      }}


export function useNativeAccount() {
  const context = useContext(AccountsContext);
  return {
    account: context.nativeAccount as AccountInfo<Buffer>,
  };
}


export function useMint(key?: string | PublicKey) {
  const connection = useConnection();
  const [mint, setMint] = useState<MintInfo>();

  const id = typeof key === 'string' ? key : key?.toBase58();

  useEffect(() => {
    if (!id) {
      return;
    }

    cache
      .query(connection, id, MintParser)
      .then(acc => setMint(acc.info as any))
      .catch(err => console.log(err));

    const dispose = cache.emitter.onCache(e => {
      const event = e;
      if (event.id === id) {
        cache
          .query(connection, id, MintParser)
          .then(mint => setMint(mint.info as any));
      }
    });
    return () => {
      dispose();
    };
  }, [connection, id]);

  return mint;
}


export function useAccount(pubKey?: PublicKey) {
  const connection = useConnection();
  const [account, setAccount] = useState<TokenAccount>();

  const key = pubKey?.toBase58();
  useEffect(() => {
    const query = async () => {
      try {
        if (!key) {
          return;
        }

        const acc = await cache
          .query(connection, key, TokenAccountParser)
          .catch(err => console.log(err));
        if (acc) {
          setAccount(acc);
        }
      } catch (err) {
        console.error(err);
      }
    };

    query();

    const dispose = cache.emitter.onCache(e => {
      const event = e;
      if (event.id === key) {
        query();
      }
    });
    return () => {
      dispose();
    };
  }, [connection, key]);

  return account;
}


() => {
  const context = useContext(AccountsContext);

  return context;
}


() => {
  const connection = useConnection();
  const { publicKey } = useWallet();

  const [nativeAccount, setNativeAccount] = useState<AccountInfo<Buffer>>();

  const updateCache = useCallback(
    account => {
      if (publicKey) {
        const wrapped = wrapNativeAccount(publicKey.toBase58(), account);
        if (wrapped !== undefined) {
          const id = publicKey.toBase58();
          cache.registerParser(id, TokenAccountParser);
          genericCache.set(id, wrapped as TokenAccount);
          cache.emitter.raiseCacheUpdated(id, false, TokenAccountParser, true);
        }
      }
    },
    [publicKey],
  );

  useEffect(() => {
    let subId = 0;
    const updateAccount = (account: AccountInfo<Buffer> | null) => {
      if (account) {
        updateCache(account);
        setNativeAccount(account);
      }
    };

    (async () => {
      if (!connection || !publicKey) {
        return;
      }

      const subDone = timeStart(
        'UseNativeAccount#sub$connection.onAccountChange',
      );
      subId = connection.onAccountChange(publicKey, info => {
        subDone();
        updateAccount(info);
      });

      const done = timeStart('UseNativeAccount#connection.getAccountInfo');
      const account = await connection.getAccountInfo(publicKey);
      updateAccount(account);
      done();
    })();

    return () => {
      if (subId) {
        connection.removeAccountChangeListener(subId);
      }
    };
  }, [setNativeAccount, publicKey, connection, updateCache]);

  return { nativeAccount };
}


account => {
      if (publicKey) {
        const wrapped = wrapNativeAccount(publicKey.toBase58(), account);
        if (wrapped !== undefined) {
          const id = publicKey.toBase58();
          cache.registerParser(id, TokenAccountParser);
          genericCache.set(id, wrapped as TokenAccount);
          cache.emitter.raiseCacheUpdated(id, false, TokenAccountParser, true);
        }
      }
    }


() => {
    let subId = 0;
    const updateAccount = (account: AccountInfo<Buffer> | null) => {
      if (account) {
        updateCache(account);
        setNativeAccount(account);
      }
    };

    (async () => {
      if (!connection || !publicKey) {
        return;
      }

      const subDone = timeStart(
        'UseNativeAccount#sub$connection.onAccountChange',
      );
      subId = connection.onAccountChange(publicKey, info => {
        subDone();
        updateAccount(info);
      });

      const done = timeStart('UseNativeAccount#connection.getAccountInfo');
      const account = await connection.getAccountInfo(publicKey);
      updateAccount(account);
      done();
    })();

    return () => {
      if (subId) {
        connection.removeAccountChangeListener(subId);
      }
    };
  }


(account: AccountInfo<Buffer> | null) => {
      if (account) {
        updateCache(account);
        setNativeAccount(account);
      }
    }


async () => {
      if (!connection || !publicKey) {
        return;
      }

      const subDone = timeStart(
        'UseNativeAccount#sub$connection.onAccountChange',
      );
      subId = connection.onAccountChange(publicKey, info => {
        subDone();
        updateAccount(info);
      });

      const done = timeStart('UseNativeAccount#connection.getAccountInfo');
      const account = await connection.getAccountInfo(publicKey);
      updateAccount(account);
      done();
    }


info => {
        subDone();
        updateAccount(info);
      }


() => {
      if (subId) {
        connection.removeAccountChangeListener(subId);
      }
    }


async (
  connection: Connection,
  owner?: PublicKey,
) => {
  if (!owner) {
    return;
  }

  // used for filtering account updates over websocket
  PRECACHED_OWNERS.add(owner.toBase58());

  // user accounts are updated via ws subscription
  const accounts = await connection.getTokenAccountsByOwner(owner, {
    programId: programIds().token,
  });

  accounts.value.forEach(info => {
    cache.add(info.pubkey.toBase58(), info.account, TokenAccountParser);
  });
}


info => {
    cache.add(info.pubkey.toBase58(), info.account, TokenAccountParser);
  }


() => {
    return cache
      .byParser(TokenAccountParser)
      .map(id => cache.get(id))
      .filter(a => a && a.info.owner.toBase58() === walletKey)
      .map(a => a as TokenAccount);
  }


id => cache.get(id)


a => a && a.info.owner.toBase58() === walletKey


a => a as TokenAccount


() => {
    const accounts = selectUserAccounts().filter(
      a => a !== undefined,
    ) as TokenAccount[];
    setUserAccounts(accounts);
  }


a => a !== undefined


() => {
    const subs: number[] = [];
    cache.emitter.onCache(args => {
      if (args.isNew && args.isActive) {
        let id = args.id;
        let deserialize = args.parser;
        connection.onAccountChange(new PublicKey(id), info => {
          cache.add(id, info, deserialize);
        });
      }
    });

    return () => {
      subs.forEach(id => connection.removeAccountChangeListener(id));
    };
  }


args => {
      if (args.isNew && args.isActive) {
        let id = args.id;
        let deserialize = args.parser;
        connection.onAccountChange(new PublicKey(id), info => {
          cache.add(id, info, deserialize);
        });
      }
    }


info => {
          cache.add(id, info, deserialize);
        }


() => {
      subs.forEach(id => connection.removeAccountChangeListener(id));
    }


id => connection.removeAccountChangeListener(id)


() => {
    if (!connection || !publicKey) {
      setTokenAccounts([]);
    } else {
      precacheUserTokenAccounts(connection, publicKey).then(() => {
        setTokenAccounts(selectUserAccounts());
      });

      // This can return different types of accounts: token-account, mint, multisig
      // TODO: web3.js expose ability to filter.
      // this should use only filter syntax to only get accounts that are owned by user
      const tokenSubID = connection.onProgramAccountChange(
        programIds().token,
        info => {
          // TODO: fix type in web3.js
          const id = info.accountId as unknown as string;
          // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
          if (info.accountInfo.data.length === AccountLayout.span) {
            const data = deserializeAccount(info.accountInfo.data);

            if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
              cache.add(id, info.accountInfo, TokenAccountParser);
              setTokenAccounts(selectUserAccounts());
            }
          }
        },
        'singleGossip',
      );

      return () => {
        connection.removeProgramAccountChangeListener(tokenSubID);
      };
    }
  }


() => {
        setTokenAccounts(selectUserAccounts());
      }


info => {
          // TODO: fix type in web3.js
          const id = info.accountId as unknown as string;
          // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
          if (info.accountInfo.data.length === AccountLayout.span) {
            const data = deserializeAccount(info.accountInfo.data);

            if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
              cache.add(id, info.accountInfo, TokenAccountParser);
              setTokenAccounts(selectUserAccounts());
            }
          }
        }


() => {
        connection.removeProgramAccountChangeListener(tokenSubID);
      }


() => {
    if (!id) {
      return;
    }

    cache
      .query(connection, id, MintParser)
      .then(acc => setMint(acc.info as any))
      .catch(err => console.log(err));

    const dispose = cache.emitter.onCache(e => {
      const event = e;
      if (event.id === id) {
        cache
          .query(connection, id, MintParser)
          .then(mint => setMint(mint.info as any));
      }
    });
    return () => {
      dispose();
    };
  }


acc => setMint(acc.info as any)


e => {
      const event = e;
      if (event.id === id) {
        cache
          .query(connection, id, MintParser)
          .then(mint => setMint(mint.info as any));
      }
    }


mint => setMint(mint.info as any)


() => {
      dispose();
    }


() => {
    const query = async () => {
      try {
        if (!key) {
          return;
        }

        const acc = await cache
          .query(connection, key, TokenAccountParser)
          .catch(err => console.log(err));
        if (acc) {
          setAccount(acc);
        }
      } catch (err) {
        console.error(err);
      }
    };

    query();

    const dispose = cache.emitter.onCache(e => {
      const event = e;
      if (event.id === key) {
        query();
      }
    });
    return () => {
      dispose();
    };
  }


async () => {
      try {
        if (!key) {
          return;
        }

        const acc = await cache
          .query(connection, key, TokenAccountParser)
          .catch(err => console.log(err));
        if (acc) {
          setAccount(acc);
        }
      } catch (err) {
        console.error(err);
      }
    }


e => {
      const event = e;
      if (event.id === key) {
        query();
      }
    }


/**
 * An event generated by a participant interacting with the LAMP app.
 */
export class SensorEvent {

    /**
     *
     */
    timestamp?: Timestamp

    /**
     * The type of the sensor event.
     */
    sensor?: string

    /**
     * The item information recorded within the sensor event.
     */
    data?: any
}


(endpointConfig: ApiDataEndpointConfig, request: ApiDataRequest): boolean =>
    Date.now() - request.lastCall > (typeof endpointConfig.cacheDuration === 'number' ? endpointConfig.cacheDuration : Number.POSITIVE_INFINITY)


() => ({
  createPlayer: jest.fn(),
})


() => ({
  getResource: jest.fn().mockResolvedValue(null),
})


() => ({
  pollForLive: jest.fn().mockResolvedValue(null),
})


() => ({
  appData: {
    video: mockVideo,
  },
  getDecodedJwt: () => ({
    permissions: {
      can_update: mockCanUpdate,
    },
  }),
})


() => ({
    permissions: {
      can_update: mockCanUpdate,
    },
  })


() => ({
  converseMounter: jest.fn(() => jest.fn()),
})


() => jest.fn()


() => {
    fetchMock.mock(
      '/api/timedtexttracks/',
      {
        actions: {
          POST: {
            language: {
              choices: [
                { display_name: 'English', value: 'en' },
                { display_name: 'French', value: 'fr' },
              ],
            },
          },
        },
      },
      { method: 'OPTIONS' },
    );
    mockCreatePlayer.mockResolvedValue({
      destroy: jest.fn(),
    });
    mockCanUpdate = false;
  }


() => {
    fetchMock.restore();
    jest.clearAllMocks();
  }


async () => {
    const video = videoMockFactory({
      urls: {
        manifests: {
          hls: 'https://example.com/hls.m3u8',
        },
        mp4: {
          144: 'https://example.com/144p.mp4',
          1080: 'https://example.com/1080p.mp4',
        },
        thumbnails: {
          144: 'https://example.com/thumbnail/144p.jpg',
          1080: 'https://example.com/thumbnail/1080p.jpg',
        },
      },
    });

    const { container } = render(
      wrapInIntlProvider(
        <PublicVideoDashboard video={video} playerType="videojs" />,
      ),
    );

    await waitFor(() =>
      // The player is created
      expect(mockCreatePlayer).toHaveBeenCalledWith(
        'videojs',
        expect.any(Element),
        expect.anything(),
        video,
      ),
    );

    expect(
      container.querySelector('source[src="https://example.com/144p.mp4"]'),
    ).not.toBeNull();
    expect(
      container.querySelector('source[src="https://example.com/1080p.mp4"]'),
    ).not.toBeNull();
    expect(container.querySelectorAll('source[type="video/mp4"]')).toHaveLength(
      2,
    );
    const videoElement = container.querySelector('video')!;
    expect(videoElement.tabIndex).toEqual(-1);
    expect(videoElement.poster).toEqual(
      'https://example.com/thumbnail/1080p.jpg',
    );
  }


() =>
      // The player is created
      expect(mockCreatePlayer).toHaveBeenCalledWith(
        'videojs',
        expect.any(Element),
        expect.anything(),
        video,
      )


async () => {
    const timedTextTracks = [
      timedTextMockFactory({
        is_ready_to_show: true,
        mode: timedTextMode.TRANSCRIPT,
      }),
    ];
    useTimedTextTrack.getState().addMultipleResources(timedTextTracks);
    const video = videoMockFactory({
      has_transcript: true,
      show_download: true,
      timed_text_tracks: timedTextTracks,
      urls: {
        manifests: {
          hls: 'https://example.com/hls.m3u8',
        },
        mp4: {
          144: 'https://example.com/144p.mp4',
          1080: 'https://example.com/1080p.mp4',
        },
        thumbnails: {
          144: 'https://example.com/thumbnail/144p.jpg',
          1080: 'https://example.com/thumbnail/1080p.jpg',
        },
      },
    });

    const { container } = render(
      wrapInIntlProvider(
        <PublicVideoDashboard video={video} playerType="videojs" />,
      ),
    );

    await waitFor(() =>
      // The player is created
      expect(mockCreatePlayer).toHaveBeenCalledWith(
        'videojs',
        expect.any(Element),
        expect.anything(),
        video,
      ),
    );

    screen.getByText(/Download this video/i);
    screen.getByText('Show a transcript');
    expect(
      container.querySelector('source[src="https://example.com/144p.mp4"]'),
    ).not.toBeNull();
    expect(
      container.querySelector('source[src="https://example.com/1080p.mp4"]'),
    ).not.toBeNull();
    expect(container.querySelectorAll('source[type="video/mp4"]')).toHaveLength(
      2,
    );
    const videoElement = container.querySelector('video')!;
    expect(videoElement.tabIndex).toEqual(-1);
    expect(videoElement.poster).toEqual(
      'https://example.com/thumbnail/1080p.jpg',
    );
  }


async () => {
    const timedTextTracks = [
      timedTextMockFactory({
        id: 'ttt-1',
        is_ready_to_show: true,
        mode: timedTextMode.SUBTITLE,
      }),
    ];
    useTimedTextTrack.getState().addMultipleResources(timedTextTracks);
    const video = videoMockFactory({
      has_transcript: false,
      show_download: true,
      should_use_subtitle_as_transcript: true,
      timed_text_tracks: timedTextTracks,
      urls: {
        manifests: {
          hls: 'https://example.com/hls.m3u8',
        },
        mp4: {
          144: 'https://example.com/144p.mp4',
          1080: 'https://example.com/1080p.mp4',
        },
        thumbnails: {
          144: 'https://example.com/thumbnail/144p.jpg',
          1080: 'https://example.com/thumbnail/1080p.jpg',
        },
      },
    });

    const { container } = render(
      wrapInIntlProvider(
        <PublicVideoDashboard video={video} playerType="videojs" />,
      ),
    );

    await waitFor(() =>
      // The player is created
      expect(mockCreatePlayer).toHaveBeenCalledWith(
        'videojs',
        expect.any(Element),
        expect.anything(),
        video,
      ),
    );

    screen.getByText(/Download this video/i);
    screen.getByText('Show a transcript');
    expect(
      container.querySelector('source[src="https://example.com/144p.mp4"]'),
    ).not.toBeNull();
    expect(
      container.querySelector('source[src="https://example.com/1080p.mp4"]'),
    ).not.toBeNull();
    expect(container.querySelectorAll('source[type="video/mp4"]')).toHaveLength(
      2,
    );
    const videoElement = container.querySelector('video')!;
    expect(videoElement.tabIndex).toEqual(-1);
    expect(videoElement.poster).toEqual(
      'https://example.com/thumbnail/1080p.jpg',
    );

    expect(container.querySelector('option[value="ttt-1"]')).not.toBeNull();
  }


async () => {
    const video = videoMockFactory({
      live_state: liveState.RUNNING,
      urls: {
        manifests: {
          hls: 'https://example.com/hls.m3u8',
        },
        mp4: {},
        thumbnails: {},
      },
      xmpp: {
        bosh_url: 'https://xmpp-server.com/http-bind',
        websocket_url: null,
        conference_url:
          '870c467b-d66e-4949-8ee5-fcf460c72e88@conference.xmpp-server.com',
        prebind_url: 'https://xmpp-server.com/http-pre-bind',
        jid: 'xmpp-server.com',
      },
    });

    const { container } = render(
      wrapInIntlProvider(
        <PublicVideoDashboard video={video} playerType="videojs" />,
      ),
    );

    await waitFor(() =>
      // The player is created
      expect(mockCreatePlayer).toHaveBeenCalledWith(
        'videojs',
        expect.any(Element),
        expect.anything(),
        video,
      ),
    );

    const videoElement = container.querySelector('video')!;
    expect(videoElement.tabIndex).toEqual(-1);
    expect(container.querySelector('#converse-container')).toBeInTheDocument();
  }


() => {
    [liveState.STOPPED, liveState.STOPPING].forEach((state) => {
      const video = videoMockFactory({
        live_state: state,
      });
      render(
        wrapInIntlProvider(
          wrapInRouter(
            <PublicVideoDashboard video={video} playerType="videojs" />,
            [
              {
                path: DASHBOARD_ROUTE(),
                render: ({ match }) => (
                  {`dashboard ${match.params.objectType}`}
                ),
              },
              {
                path: FULL_SCREEN_ERROR_ROUTE(),
                render: ({ match }) => (
                  {`Error Component: ${match.params.code}`}
                ),
              }


(state) => {
      const video = videoMockFactory({
        live_state: state,
      });
      render(
        wrapInIntlProvider(
          wrapInRouter(
            <PublicVideoDashboard video={video} playerType="videojs" />,
            [
              {
                path: DASHBOARD_ROUTE(),
                render: ({ match }) => (
                  <span>{`dashboard ${match.params.objectType}`}</span>
                ),
              }


({ match }) => (
                  <span>{`dashboard ${match.params.objectType}`


({ match }) => (
                  <span>{`Error Component: ${match.params.code}`


() => {
    mockCanUpdate = true;
    [liveState.STOPPED, liveState.STOPPING].forEach((state) => {
      const video = videoMockFactory({
        live_state: state,
      });
      render(
        wrapInIntlProvider(
          wrapInRouter(
            <PublicVideoDashboard video={video} playerType="videojs" />,
            [
              {
                path: DASHBOARD_ROUTE(),
                render: ({ match }) => (
                  {`dashboard ${match.params.objectType}`}
                ),
              },
              {
                path: FULL_SCREEN_ERROR_ROUTE(),
                render: ({ match }) => (
                  {`Error Component: ${match.params.code}`}
                ),
              }


() => {
    [liveState.IDLE, liveState.CREATING, liveState.STARTING].forEach(
      (state) => {
        const video = videoMockFactory({
          live_state: state,
        });
        render(
          wrapInIntlProvider(
            wrapInRouter(
              <PublicVideoDashboard video={video} playerType="videojs" />,
            ),
          ),
        );

        screen.getByText('Live will begin soon');
        screen.getByText(
          'The live is going to start. You can wait here, the player will start once the live is ready.',
        );

        cleanup();
      },
    );
  }


(state) => {
        const video = videoMockFactory({
          live_state: state,
        });
        render(
          wrapInIntlProvider(
            wrapInRouter(
              <PublicVideoDashboard video={video} playerType="videojs" />,
            ),
          ),
        );

        screen.getByText('Live will begin soon');
        screen.getByText(
          'The live is going to start. You can wait here, the player will start once the live is ready.',
        );

        cleanup();
      }


/**
   * Find the next instance of the term, then scroll to and select it. If it
   * doesn't exist, do nothing.
   * @param term The search term.
   * @param searchOptions Search options.
   * @return Whether a result was found.
   */
public findNext(term: string, searchOptions?: ISearchOptions): boolean {
    if (!term || term.length === 0) {
      return false;
    }

    let result: ISearchResult;

    let startRow = this._terminal._core.buffer.ydisp;
    if (this._terminal._core.selectionManager.selectionEnd) {
      // Start from the selection end if there is a selection
      if (this._terminal.getSelection().length !== 0) {
        startRow = this._terminal._core.selectionManager.selectionEnd[1];
      }
    }

    // Search from ydisp + 1 to end
    for (let y = startRow + 1; y < this._terminal._core.buffer.ybase + this._terminal.rows; y++) {
      result = this._findInLine(term, y, searchOptions);
      if (result) {
        break;
      }
    }

    // Search from the top to the current ydisp
    if (!result) {
      for (let y = 0; y < startRow; y++) {
        result = this._findInLine(term, y, searchOptions);
        if (result) {
          break;
        }
      }
    }

    // Set selection and scroll if a result was found
    return this._selectResult(result);
  }