/**
 * Provides the default runtime for a given `RuntimeFamily` or undefined if the runtime is invalid.
 */
export function getDefaultRuntime(runtime: RuntimeFamily): string | undefined {
    return DEFAULT_RUNTIMES.get(runtime)
}


/**
 * Returns a set of runtimes for a specified runtime family or undefined if not found.
 * @param family Runtime family to get runtimes for
 */
function getRuntimesForFamily(family: RuntimeFamily): Set<Runtime> | undefined {
    switch (family) {
        case RuntimeFamily.NodeJS:
            return nodeJsRuntimes
        case RuntimeFamily.Python:
            return pythonRuntimes
        case RuntimeFamily.DotNetCore:
            return dotNetRuntimes
        default:
            return undefined
    }
}


/**
 * Creates a quick pick for a Runtime with the following parameters (all optional)
 * @param {Object} params Optional parameters for creating a QuickPick for runtimes:
 * @param {vscode.QuickInputButton[]} params.buttons Array of buttons to add to the quick pick;
 * @param {Runtime} params.currRuntime Runtime to set a "Selected Previously" mark to;
 * @param {RuntimeFamily} params.runtimeFamily RuntimeFamily that will define the list of runtimes to show (default: samLambdaCreatableRuntimes)
 */
export function createRuntimeQuickPick(params: {
    buttons?: vscode.QuickInputButton[]
    currRuntime?: Runtime
    runtimeFamily?: RuntimeFamily
}): vscode.QuickPick<vscode.QuickPickItem> {
    const runtimes = params.runtimeFamily
        ? getRuntimesForFamily(params.runtimeFamily) ?? samLambdaCreatableRuntimes
        : samLambdaCreatableRuntimes

    return picker.createQuickPick<vscode.QuickPickItem>({
        options: {
            ignoreFocusOut: true,
            title: localize('AWS.samcli.initWizard.runtime.prompt', 'Select a SAM Application Runtime'),
            value: params.currRuntime ? params.currRuntime : '',
        },
        buttons: [...(params.buttons ?? []), vscode.QuickInputButtons.Back],
        items: runtimes
            // remove uncreatable runtimes
            .filter(value => samLambdaCreatableRuntimes.has(value))
            .toArray()
            .sort(compareSamLambdaRuntime)
            .map(runtime => ({
                label: runtime,
                alwaysShow: runtime === params.currRuntime,
                description:
                    runtime === params.currRuntime
                        ? localize('AWS.wizard.selectedPreviously', 'Selected Previously')
                        : '',
            })),
    })
}


runtime => runtime !== 'nodejs8.10'


value => samLambdaCreatableRuntimes.has(value)


runtime => ({
                label: runtime,
                alwaysShow: runtime === params.currRuntime,
                description:
                    runtime === params.currRuntime
                        ? localize('AWS.wizard.selectedPreviously', 'Selected Previously')
                        : '',
            })


export enum RuntimeFamily {
    Unknown,
    Python,
    NodeJS,
    DotNetCore,
}


export type DependencyManager = 'cli-package' | 'mod' | 'gradle' | 'pip' | 'npm' | 'maven' | 'bundler'


@NgModule({
  declarations: [PanelComponent],
  imports: [
    TooltipModule,
    CommonModule,
    DialogsModule
  ],
  exports: [PanelComponent]
})
export class PanelsModule { }


export function createSubscription<S, T>(config: SubscriptionConfig<S, T>): Subscription<S, T>;


export interface SubscriptionConfig<S, T> {
    /**
     * Synchronously gets the value for the subscribed property.
     * Return undefined if the subscribable value is undefined,
     * Or does not support synchronous reading (e.g. native Promise).
     */
    getCurrentValue: (source: S) => T;

    /**
     * Set up a subscription for the subscribable value in props, and return an unsubscribe function.
     * Return false to indicate the property cannot be unsubscribed from (e.g. native Promises).
     * Due to the variety of change event types, subscribers should provide their own handlers.
     * Those handlers should not attempt to update state though;
     * They should call the callback() instead when a subscription changes.
     */
    subscribe: (source: S, callback: (newValue: T) => void) => Unsubscribe;
}


export interface SubscriptionProps<S, T> {
    children: (value: T) => React.ReactNode;
    source: S;
}


export interface Subscription<S, T> extends React.ComponentClass<SubscriptionProps<S, T>> {}


export type Unsubscribe = () => any;


export function main() {
  return platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
}


/** */
export default class Model extends AbstractClass {
	properties: Array<ClassProperty> = [];
	config: any = {};
	uses: Array<string> = [];

	constructor(data: any) {
		super(data);
		if (data.properties !== undefined) {
			for (const properId of Object.keys(data.properties)) {
				if (data.properties[properId] !== undefined) {
					let p = data.properties[properId];
					//process type
					let type;
					type = p.type ?? 'string';
					type = (type === 'integer') ? 'int' : type;
					const property = {
						access: 'private',
						name: `$${properId}`,
						type: type,
						format: p.format ?? 'vachart(50)',
						description: p.description ?? properId,
						default: p.default ?? '',
						example: p.example ?? '',
						enum: p.enum ?? [],
					};
					this.properties.push(new ClassProperty(property));
				}
			}
		}
	}

	setNamespace(): void {
		throw new Error('Method not implemented.');
	}

	process(): void {
		throw new Error('Method not implemented.');
	}

	getJson(): any {
		return {
			namespace: this.namespace,
			isAbstract: false,
			className: this.name,
			implenments: this.implenments,
			properties: this.properties,
		};
	}
}


setNamespace(): void {
		throw new Error('Method not implemented.');
	}


process(): void {
		throw new Error('Method not implemented.');
	}


getJson(): any {
		return {
			namespace: this.namespace,
			isAbstract: false,
			className: this.name,
			implenments: this.implenments,
			properties: this.properties,
		};
	}


() => {
  it('results in an empty object with undefined options', () => {
    const result = packFilterOptions(undefined);
    expect(result).toEqual('{}');
  });

  it('results in an empty object with no options', () => {
    const result = packFilterOptions({});
    expect(result).toEqual('{}');
  });

  it('encodes threshold to a string', () => {
    const result = packFilterOptions({
      threshold: 5.5,
    });
    expect(result).toEqual('{"threshold":"5.5"}');
  });

  it('encodes the frequency to a string', () => {
    const result = packFilterOptions({
      alertFrequency: 'ALWAYS',
    });
    expect(result).toEqual('{"alertFrequency":"ALWAYS"}');
  });

  it('encodes the directMessageType to a string', () => {
    const result = packFilterOptions({
      directMessageType: 'MARKETING',
    });
    expect(result).toEqual('{"directMessageType":"MARKETING"}');
  });
}


() => {
    const result = packFilterOptions(undefined);
    expect(result).toEqual('{}');
  }


() => {
    const result = packFilterOptions({});
    expect(result).toEqual('{}');
  }


() => {
    const result = packFilterOptions({
      threshold: 5.5,
    });
    expect(result).toEqual('{"threshold":"5.5"}');
  }


() => {
    const result = packFilterOptions({
      alertFrequency: 'ALWAYS',
    });
    expect(result).toEqual('{"alertFrequency":"ALWAYS"}');
  }


() => {
    const result = packFilterOptions({
      directMessageType: 'MARKETING',
    });
    expect(result).toEqual('{"directMessageType":"MARKETING"}');
  }


@Component({
  tag: 'pr-button',
  styleUrl: 'pr-button.css',
  shadow: true,
})
export class PrButton {
  @Prop() color: 'PRIMARY' | 'SECONDARY' = 'PRIMARY';
  @Prop() disabled: boolean = false;
  @Prop() size: 'LARGE' | 'MEDIUM' | 'SMALL' = 'LARGE';
  @Prop() text: string;
  @Prop() icon: string;

  //Event to emit any action from of parent
  @Event() event: EventEmitter;
  eventButton() {
    this.event.emit();
  }
  //get size of button
  getSizeOfBotton() {
    return CONST_SIZES_BUTTON[this.size];
  }
  //get color of button
  getColorOfButton() {
    return this.disabled ? CONST_COLORS_BUTTON[this.color]['DISABLED'] : CONST_COLORS_BUTTON[this.color]['ENABLED'];
  }
  //get BackgroundColor
  getBackgroundColor() {
    return this.disabled ? CONST_COLORS_BUTTON['TRANSPARENT'] : this.getColorOfButton();
  }

  //get object css for button
  stylePrButton = {
    ...this.getSizeOfBotton(),
    backgroundColor: this.getBackgroundColor(),
    borderColor: this.getColorOfButton(),
  };

  render() {
    return (
      <Host>
        <button class="pr-button" disabled={this.disabled} style={this.stylePrButton} type="button" onClick={this.eventButton.bind(this)}>
          {this.text}
          <img class="imagen" src={this.icon} />
        </button>
      </Host>
    );
  }
}


class


eventButton() {
    this.event.emit();
  }


//get size of button
getSizeOfBotton() {
    return CONST_SIZES_BUTTON[this.size];
  }


//get color of button
getColorOfButton() {
    return this.disabled ? CONST_COLORS_BUTTON[this.color]['DISABLED'] : CONST_COLORS_BUTTON[this.color]['ENABLED'];
  }


//get BackgroundColor
getBackgroundColor() {
    return this.disabled ? CONST_COLORS_BUTTON['TRANSPARENT'] : this.getColorOfButton();
  }


render() {
    return (
      <Host>
        <button class="pr-button" disabled={this.disabled} style={this.stylePrButton} type="button" onClick={this.eventButton.bind(this)}>
          {this.text}
          <img class="imagen" src={this.icon} />
        </button>
      </Host>
    );
  }


props => props.disabled && `
    background: #000;
  `


(props: HomeProps) => {
  const [balance, setBalance] = useState<number>();
  const [isActive, setIsActive] = useState(isPast(freezerOpenDate)); // true when countdown completes
  const [isSoldOut, setIsSoldOut] = useState(false); // true when items remaining is zero
  const [isMinting, setIsMinting] = useState(false); // true when user got to press MINT

  const [itemsAvailable, setItemsAvailable] = useState(0);
  const [itemsRedeemed, setItemsRedeemed] = useState(0);
  const [itemsRemaining, setItemsRemaining] = useState(0);

  const [alertState, setAlertState] = useState<AlertState>({
    open: false,
    message: "",
    severity: undefined,
  });

  const [startDate, setStartDate] = useState(new Date(props.startDate));

  const wallet = useAnchorWallet();
  const [candyMachine, setCandyMachine] = useState<CandyMachine>();

  const refreshCandyMachineState = () => {
    (async () => {
      if (!wallet) return;

      const {
        candyMachine,
        goLiveDate,
        itemsAvailable,
        itemsRemaining,
        itemsRedeemed,
      } = await getCandyMachineState(
        wallet as anchor.Wallet,
        props.candyMachineId,
        props.connection
      );

      setItemsAvailable(itemsAvailable);
      setItemsRemaining(itemsRemaining);
      setItemsRedeemed(itemsRedeemed);

      setIsSoldOut(itemsRemaining === 0);
      setStartDate(goLiveDate);
      setCandyMachine(candyMachine);
    })();
  };

  const onMint = async () => {
    try {
      setIsMinting(true);
      if (wallet && candyMachine?.program) {
        const mintTxId = await mintOneToken(
          candyMachine,
          props.config,
          wallet.publicKey,
          props.treasury
        );

        const status = await awaitTransactionSignatureConfirmation(
          mintTxId,
          props.txTimeout,
          props.connection,
          "singleGossip",
          false
        );

        if (!status?.err) {
          setAlertState({
            open: true,
            message: "Congratulations! Mint succeeded!",
            severity: "success",
          });
        } else {
          setAlertState({
            open: true,
            message: "Mint failed! Please try again!",
            severity: "error",
          });
        }
      }
    } catch (error: any) {
      // TODO: blech:
      let message = error.msg || "Minting failed! Please try again!";
      if (!error.msg) {
        if (error.message.indexOf("0x138")) {
        } else if (error.message.indexOf("0x137")) {
          message = `SOLD OUT!`;
        } else if (error.message.indexOf("0x135")) {
          message = `Insufficient funds to mint. Please fund your wallet.`;
        }
      } else {
        if (error.code === 311) {
          message = `SOLD OUT!`;
          setIsSoldOut(true);
        } else if (error.code === 312) {
          message = `Minting period hasn't started yet.`;
        }
      }

      setAlertState({
        open: true,
        message,
        severity: "error",
      });
    } finally {
      if (wallet) {
        const balance = await props.connection.getBalance(wallet.publicKey);
        setBalance(balance / LAMPORTS_PER_SOL);
      }
      setIsMinting(false);
      refreshCandyMachineState();
    }
  };

  useEffect(() => {
    (async () => {
      if (wallet) {
        const balance = await props.connection.getBalance(wallet.publicKey);
        setBalance(balance / LAMPORTS_PER_SOL);
      }
    })();
  }, [wallet, props.connection]);

  useEffect(refreshCandyMachineState, [
    wallet,
    props.candyMachineId,
    props.connection,
  ]);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setIsActive(isPast(freezerOpenDate));
    }, 1000);

    return () => clearInterval(intervalId);
  }, []);

  return (
    <MainContainer>

          <ScoopLogoSVG />
          <img className="wordmark" src={`${process.env.PUBLIC_URL}/img/ScoopShopLogo.svg`}


() => {
    (async () => {
      if (!wallet) return;

      const {
        candyMachine,
        goLiveDate,
        itemsAvailable,
        itemsRemaining,
        itemsRedeemed,
      } = await getCandyMachineState(
        wallet as anchor.Wallet,
        props.candyMachineId,
        props.connection
      );

      setItemsAvailable(itemsAvailable);
      setItemsRemaining(itemsRemaining);
      setItemsRedeemed(itemsRedeemed);

      setIsSoldOut(itemsRemaining === 0);
      setStartDate(goLiveDate);
      setCandyMachine(candyMachine);
    })();
  }


async () => {
      if (!wallet) return;

      const {
        candyMachine,
        goLiveDate,
        itemsAvailable,
        itemsRemaining,
        itemsRedeemed,
      } = await getCandyMachineState(
        wallet as anchor.Wallet,
        props.candyMachineId,
        props.connection
      );

      setItemsAvailable(itemsAvailable);
      setItemsRemaining(itemsRemaining);
      setItemsRedeemed(itemsRedeemed);

      setIsSoldOut(itemsRemaining === 0);
      setStartDate(goLiveDate);
      setCandyMachine(candyMachine);
    }


async () => {
    try {
      setIsMinting(true);
      if (wallet && candyMachine?.program) {
        const mintTxId = await mintOneToken(
          candyMachine,
          props.config,
          wallet.publicKey,
          props.treasury
        );

        const status = await awaitTransactionSignatureConfirmation(
          mintTxId,
          props.txTimeout,
          props.connection,
          "singleGossip",
          false
        );

        if (!status?.err) {
          setAlertState({
            open: true,
            message: "Congratulations! Mint succeeded!",
            severity: "success",
          });
        } else {
          setAlertState({
            open: true,
            message: "Mint failed! Please try again!",
            severity: "error",
          });
        }
      }
    } catch (error: any) {
      // TODO: blech:
      let message = error.msg || "Minting failed! Please try again!";
      if (!error.msg) {
        if (error.message.indexOf("0x138")) {
        } else if (error.message.indexOf("0x137")) {
          message = `SOLD OUT!`;
        } else if (error.message.indexOf("0x135")) {
          message = `Insufficient funds to mint. Please fund your wallet.`;
        }
      } else {
        if (error.code === 311) {
          message = `SOLD OUT!`;
          setIsSoldOut(true);
        } else if (error.code === 312) {
          message = `Minting period hasn't started yet.`;
        }
      }

      setAlertState({
        open: true,
        message,
        severity: "error",
      });
    } finally {
      if (wallet) {
        const balance = await props.connection.getBalance(wallet.publicKey);
        setBalance(balance / LAMPORTS_PER_SOL);
      }
      setIsMinting(false);
      refreshCandyMachineState();
    }
  }


() => {
    (async () => {
      if (wallet) {
        const balance = await props.connection.getBalance(wallet.publicKey);
        setBalance(balance / LAMPORTS_PER_SOL);
      }
    })();
  }


async () => {
      if (wallet) {
        const balance = await props.connection.getBalance(wallet.publicKey);
        setBalance(balance / LAMPORTS_PER_SOL);
      }
    }


() => {
    const intervalId = setInterval(() => {
      setIsActive(isPast(freezerOpenDate));
    }, 1000);

    return () => clearInterval(intervalId);
  }


() => {
      setIsActive(isPast(freezerOpenDate));
    }


() => clearInterval(intervalId)


() => setAlertState({ ...alertState, open: false })


({ days, hours, minutes, seconds, completed }: any) => {
  return (
    <CounterText>
      {hours + (days || 0) * 24}


export interface HomeProps {
  candyMachineId: anchor.web3.PublicKey;
  config: anchor.web3.PublicKey;
  connection: anchor.web3.Connection;
  startDate: number;
  treasury: anchor.web3.PublicKey;
  txTimeout: number;
}


interface AlertState {
  open: boolean;
  message: string;
  severity: "success" | "info" | "warning" | "error" | undefined;
}


shortenAddress(wallet


async () => {
  const trackedUsers = new TrackedUsers(TEST_NETWORK_ID, DB_FACTORY);

  let err: Error;
  try {
    await trackedUsers.setUserTracked("mock");
  } catch (e) {
    err = e;
  }
  await expect(err.message).toMatch('invalid address (arg="address", value="mock", version=4.0.24)');

  expect(await trackedUsers.getUsers()).toEqual([]);
}


export type GradientStroke = {
  /**
   * Match Name
   * @desc After Effect's Match Name. Used for expressions
   */
  mn: string;
  /**
   * Name
   * @desc After Effect's Name. Used for expressions
   */
  nm: string;
  /**
   * Type
   * @desc Shape content type
   */
  ty: ShapeType.GradientStroke;
  /**
   * Opacity
   * @desc Stroke Opacity
   */
  o: Value<number | OffsetKeyframe[]>;
  /**
   * Start Point
   * @desc Gradient Start Point
   */
  s: MultiDimensional<number[] | OffsetKeyframe[]>;
  /**
   * End Point
   * @desc Gradient End Point
   */
  e: MultiDimensional<number[] | OffsetKeyframe[]>;
  /**
   * Type
   * @desc Gradient Type
   */
  t: GradientType;
  /**
   * Highlight Length
   * @desc Gradient Highlight Length. Only if type is Radial
   */
  h: Value<number | OffsetKeyframe[]>;
  /**
   * Highlight Angle
   * @desc Highlight Angle. Only if type is Radial
   */
  a: Value<number | OffsetKeyframe[]>;
  /**
   * Gradient Colors
   */
  g: GradientColors;
  /**
   * Stroke Width
   * @desc Gradient Stroke Width
   */
  w: Value<number | OffsetKeyframe[]>;
  /**
   * Line Cap
   * @desc Gradient Stroke Line Cap;
   */
  lc: LineCap;
  /**
   * Line Join
   * @desc Gradient Stroke Line Join
   */
  lj: LineJoin;
  /**
   * Miter Limit
   * @desc Gradient Stroke Miter Limit. Only if Line Join is set to Miter
   */
  ml: number;
  /**
   * Property Index
   * @desc Property Index. Used for expressions
   */
  ix?: number;
  /**
   * Hide element
   */
  hd?: boolean;
  /**
   * 混合模式 - Blend Mode
   * @default BlendMode.Normal
   */
  bm?: BlendMode;
  /**
   * Dashes
   */
  d?: StorkeDash[];
};


// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
export class WindowUtils {
    public postMessage(win: Window, data: any, targetOrigin: string): void {
        win.postMessage(JSON.stringify(data), targetOrigin);
    }

    public addEventListener(win: Window, command: string, callback: (e: MessageEvent) => void, useCapture: boolean): void {
        win.addEventListener(command, callback, useCapture);
    }

    public removeEventListener(win: Window, command: string, callback: (e: MessageEvent) => void, useCapture: boolean): void {
        win.removeEventListener(command, callback);
    }

    public setTimeout(handler: Function, timeout: number): number {
        return window.setTimeout(handler, timeout);
    }

    public setInterval(handler: Function, timeout: number): number {
        return window.setInterval(handler, timeout);
    }

    public createObjectURL(sourceObject: Blob | File | MediaSource): string {
        return window.URL.createObjectURL(sourceObject);
    }

    public clearTimeout(timeout: number): void {
        window.clearTimeout(timeout);
    }

    public clearInterval(timeInterval: number): void {
        window.clearInterval(timeInterval);
    }

    public getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration {
        return window.getComputedStyle(elt, pseudoElt);
    }

    public getTopWindow(): Window {
        return window.top;
    }

    public getWindow(): Window {
        return window;
    }

    public isTopWindow(): boolean {
        return this.getTopWindow() === this.getWindow();
    }

    public getParentWindow(): Window {
        return window.parent;
    }

    public closeWindow(): void {
        window.close();
    }

    public getPlatform(): string {
        return window.navigator.platform;
    }
}


public postMessage(win: Window, data: any, targetOrigin: string): void {
        win.postMessage(JSON.stringify(data), targetOrigin);
    }


public addEventListener(win: Window, command: string, callback: (e: MessageEvent) => void, useCapture: boolean): void {
        win.addEventListener(command, callback, useCapture);
    }


public removeEventListener(win: Window, command: string, callback: (e: MessageEvent) => void, useCapture: boolean): void {
        win.removeEventListener(command, callback);
    }


public setTimeout(handler: Function, timeout: number): number {
        return window.setTimeout(handler, timeout);
    }


public setInterval(handler: Function, timeout: number): number {
        return window.setInterval(handler, timeout);
    }


public createObjectURL(sourceObject: Blob | File | MediaSource): string {
        return window.URL.createObjectURL(sourceObject);
    }


public clearTimeout(timeout: number): void {
        window.clearTimeout(timeout);
    }


public clearInterval(timeInterval: number): void {
        window.clearInterval(timeInterval);
    }


public getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration {
        return window.getComputedStyle(elt, pseudoElt);
    }


public getTopWindow(): Window {
        return window.top;
    }


public getWindow(): Window {
        return window;
    }


public isTopWindow(): boolean {
        return this.getTopWindow() === this.getWindow();
    }


public getParentWindow(): Window {
        return window.parent;
    }


public closeWindow(): void {
        window.close();
    }


public getPlatform(): string {
        return window.navigator.platform;
    }


/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://bangular.io/license
 */
// THIS CODE IS GENERATED - DO NOT MODIFY
// See bangular/tools/gulp-tasks/cldr/extract.js
function plural(n: number): number {
  return 5;
}


@Directive({
  selector: '[sort-by]',
  host: {
    '(click)': 'onClick($event)'
  }
})
export class SortByDirective {

	private sortProperty: string;

  @Output()
	sorted: EventEmitter<string> = new EventEmitter();

  constructor() { }

  @Input('sort-by')
  set sortBy(value: string) {
    this.sortProperty = value;
  }

  onClick(event: any) {
    event.preventDefault();
    this.sorted.next(this.sortProperty); //Raise clicked event
  }

}


onClick(event: any) {
    event.preventDefault();
    this.sorted.next(this.sortProperty); //Raise clicked event
  }


export interface ScreenProps extends ViewProps {
  active?: 0 | 1 | Animated.AnimatedInterpolation;
  activityState?: 0 | 1 | 2 | Animated.AnimatedInterpolation;
  children?: React.ReactNode;
  /**
   * All children screens should have the same value of their "enabled" prop as their container.
   */
  enabled?: boolean;
  /**
   * Whether you can use gestures to dismiss this screen. Defaults to `true`.
   * Only supported on iOS.
   *
   * @platform ios
   */
  gestureEnabled?: boolean;
  /**
   * A callback that gets called when the current screen appears.
   */
  onAppear?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  onComponentRef?: (view: unknown) => void;
  /**
   * A callback that gets called when the current screen disappears.
   */
  onDisappear?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  /**
   * A callback that gets called when the current screen is dismissed by hardware back (on Android) or dismiss gesture (swipe back or down).
   * The callback takes the number of dismissed screens as an argument since iOS 14 native header back button can pop more than 1 screen at a time.
   */
  onDismissed?: (e: NativeSyntheticEvent<{ dismissCount: number }>) => void;
  /**
   * A callback that gets called when the current screen will appear. This is called as soon as the transition begins.
   */
  onWillAppear?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  /**
   * A callback that gets called when the current screen will disappear. This is called as soon as the transition begins.
   */
  onWillDisappear?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  ref?: React.Ref<View>;
  /**
   * How should the screen replacing another screen animate. Defaults to `pop`.
   * The following values are currently supported:
   * - "push" – the new screen will perform push animation.
   * - "pop" – the new screen will perform pop animation.
   */
  replaceAnimation?: ScreenReplaceTypes;
  /**
   * In which orientation should the screen appear.
   * The following values are currently supported:
   * - "default" - resolves to "all" without "portrait_down" on iOS. On Android, this lets the system decide the best orientation.
   * - "all" – all orientations are permitted
   * - "portrait" – portrait orientations are permitted
   * - "portrait_up" – right-side portrait orientation is permitted
   * - "portrait_down" – upside-down portrait orientation is permitted
   * - "landscape" – landscape orientations are permitted
   * - "landscape_left" – landscape-left orientation is permitted
   * - "landscape_right" – landscape-right orientation is permitted
   */
  screenOrientation?: ScreenOrientationTypes;
  /**
   * How the screen should appear/disappear when pushed or popped at the top of the stack.
   * The following values are currently supported:
   * - "default" – uses a platform default animation
   * - "fade" – fades screen in or out
   * - "flip" – flips the screen, requires stackPresentation: "modal" (iOS only)
   * - "simple_push" – performs a default animation, but without shadow and native header transition (iOS only)
   * - `slide_from_bottom` – performs a slide from bottom animation (iOS only)
   * - "slide_from_right" - slide in the new screen from right to left (Android only, resolves to default transition on iOS)
   * - "slide_from_left" - slide in the new screen from left to right (Android only, resolves to default transition on iOS)
   * - "none" – the screen appears/dissapears without an animation
   */
  stackAnimation?: StackAnimationTypes;
  /**
   * How should the screen be presented.
   * The following values are currently supported:
   * - "push" – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme.
   * - "modal" – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens.
   * - "transparentModal" – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If "modal" is used instead the below screen will get unmounted as soon as the transition ends.
   * - "containedModal" – will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android.
   * - "containedTransparentModal" – will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android.
   * - "fullScreenModal" – will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android.
   * - "formSheet" – will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to "modal" on Android.
   */
  stackPresentation?: StackPresentationTypes;
  /**
   * Sets the status bar animation (similar to the `StatusBar` component). Requires enabling (or deleting) `View controller-based status bar appearance` in your Info.plist file on iOS.
   */
  statusBarAnimation?: 'none' | 'fade' | 'slide';
  /**
   * Sets the status bar color (similar to the `StatusBar` component). Defaults to initial status bar color.
   *
   * @platform android
   */
  statusBarColor?: string;
  /**
   * Whether the status bar should be hidden on this screen. Requires enabling (or deleting) `View controller-based status bar appearance` in your Info.plist file on iOS. Defaults to `false`.
   */
  statusBarHidden?: boolean;
  /**
   * Sets the status bar color (similar to the `StatusBar` component). Requires enabling (or deleting) `View controller-based status bar appearance` in your Info.plist file on iOS. Defaults to `auto`.
   */
  statusBarStyle?: 'inverted' | 'auto' | 'light' | 'dark';
  /**
   * Sets the translucency of the status bar. Defaults to `false`.
   *
   * @platform android
   */
  statusBarTranslucent?: boolean;
}


export interface ScreenContainerProps extends ViewProps {
  children?: React.ReactNode;
  /**
   * A prop that gives users an option to switch between using Screens for the navigator (container). All children screens should have the same value of their "enabled" prop as their container.
   */
  enabled?: boolean;
}


export interface ScreenStackProps extends ViewProps {
  children?: React.ReactNode;
  /**
   * A callback that gets called when the current screen finishes its transition.
   */
  onFinishTransitioning?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
}


export interface ScreenStackHeaderConfigProps extends ViewProps {
  /**
   * Whether to show the back button with custom left side of the header.
   */
  backButtonInCustomView?: boolean;
  /**
   * Controls the color of the navigation header.
   */
  backgroundColor?: string;
  /**
   * Title to display in the back button.
   * @platform ios.
   */
  backTitle?: string;
  /**
   * Allows for customizing font family to be used for back button title on iOS.
   * @platform ios
   */
  backTitleFontFamily?: string;
  /**
   * Allows for customizing font size to be used for back button title on iOS.
   * @platform ios
   */
  backTitleFontSize?: number;
  /**
   * Blur effect to be applied to the header. Works with backgroundColor's alpha < 1.
   * @platform ios
   */
  blurEffect?: BlurEffectTypes;
  /**
   * Pass HeaderLeft, HeaderRight and HeaderTitle
   */
  children?: React.ReactNode;
  /**
   * Controls the color of items rendered on the header. This includes back icon, back text (iOS only) and title text. If you want the title to have different color use titleColor property.
   */
  color?: string;
  /**
   * Whether the stack should be in rtl or ltr form.
   */
  direction?: 'rtl' | 'ltr';
  /**
   * Boolean indicating whether to show the menu on longPress of iOS >= 14 back button.
   * @platform ios
   */
  disableBackButtonMenu?: boolean;
  /**
   * When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false.
   */
  hidden?: boolean;
  /**
   * Boolean indicating whether to hide the back button in header.
   */
  hideBackButton?: boolean;
  /**
   * Boolean indicating whether to hide the elevation shadow or the bottom border on the header.
   */
  hideShadow?: boolean;
  /**
   * Boolean to set native property to prefer large title header (like in iOS setting).
   * For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`.
   * If the scrollable area doesn't fill the screen, the large title won't collapse on scroll.
   * Only supported on iOS.
   *
   * @platform ios
   */
  largeTitle?: boolean;
  /**
   * Controls the color of the navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar.
   */
  largeTitleBackgroundColor?: string;
  /**
   * Customize the color to be used for the large title. By default uses the titleColor property.
   * @platform ios
   */
  largeTitleColor?: string;
  /**
   * Customize font family to be used for the large title.
   * @platform ios
   */
  largeTitleFontFamily?: string;
  /**
   * Customize the size of the font to be used for the large title.
   * @platform ios
   */
  largeTitleFontSize?: number;
  /**
   * Customize the weight of the font to be used for the large title.
   * @platform ios
   */
  largeTitleFontWeight?: string;
  /**
   * Boolean that allows for disabling drop shadow under navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar.
   */
  largeTitleHideShadow?: boolean;
  /**
   * String that can be displayed in the header as a fallback for `headerTitle`.
   */
  title?: string;
  /**
   * Allows for setting text color of the title.
   */
  titleColor?: string;
  /**
   * Customize font family to be used for the title.
   */
  titleFontFamily?: string;
  /**
   * Customize the size of the font to be used for the title.
   */
  titleFontSize?: number;
  /**
   * Customize the weight of the font to be used for the title.
   */
  titleFontWeight?: string;
  /**
   * A flag to that lets you opt out of insetting the header. You may want to
   * set this to `false` if you use an opaque status bar. Defaults to `true`.
   * Only supported on Android. Insets are always applied on iOS because the
   * header cannot be opaque.
   *
   * @platform android
   */
  topInsetEnabled?: boolean;
  /**
   * Boolean indicating whether the navigation bar is translucent.
   */
  translucent?: boolean;
}


export interface SearchBarProps {
  /**
   * Indicates whether to to obscure the underlying content
   */
  obscureBackground?: boolean;
  /**
   * Indicates whether to hide the navigation bar
   */
  hideNavigationBar?: boolean;
  /**
   * Indicates whether to hide the search bar when scrolling
   */
  hideWhenScrolling?: boolean;
  /**
   * The auto-capitalization behavior
   */
  autoCapitalize?: 'none' | 'words' | 'sentences' | 'characters';
  /**
   * Text displayed when search field is empty
   */
  placeholder?: string;
  /**
   * The search field background color
   */
  barTintColor?: string;
  /**
   * A callback that gets called when the text changes. It receives the current text value of the search bar.
   */
  onChangeText?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
  /**
   * A callback that gets called when the cancel button is pressed
   */
  onCancelButtonPress?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  /**
   * A callback that gets called when the search button is pressed. It receives the current text value of the search bar.
   */
  onSearchButtonPress?: (
    e: NativeSyntheticEvent<TextInputFocusEventData>
  ) => void;
  /**
   * A callback that gets called when search bar has received focus
   */
  onFocus?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
  /**
   * A callback that gets called when search bar has lost focus
   */
  onBlur?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
}


export type StackPresentationTypes =
  | 'push'
  | 'modal'
  | 'transparentModal'
  | 'containedModal'
  | 'containedTransparentModal'
  | 'fullScreenModal'
  | 'formSheet';


export type StackAnimationTypes =
  | 'default'
  | 'fade'
  | 'flip'
  | 'none'
  | 'simple_push'
  | 'slide_from_bottom'
  | 'slide_from_right'
  | 'slide_from_left';


export type BlurEffectTypes =
  | 'extraLight'
  | 'light'
  | 'dark'
  | 'regular'
  | 'prominent'
  | 'systemUltraThinMaterial'
  | 'systemThinMaterial'
  | 'systemMaterial'
  | 'systemThickMaterial'
  | 'systemChromeMaterial'
  | 'systemUltraThinMaterialLight'
  | 'systemThinMaterialLight'
  | 'systemMaterialLight'
  | 'systemThickMaterialLight'
  | 'systemChromeMaterialLight'
  | 'systemUltraThinMaterialDark'
  | 'systemThinMaterialDark'
  | 'systemMaterialDark'
  | 'systemThickMaterialDark'
  | 'systemChromeMaterialDark';


export type ScreenReplaceTypes = 'push' | 'pop';


export type ScreenOrientationTypes =
  | 'default'
  | 'all'
  | 'portrait'
  | 'portrait_up'
  | 'portrait_down'
  | 'landscape'
  | 'landscape_left'
  | 'landscape_right';


export type HeaderSubviewTypes =
  | 'back'
  | 'right'
  | 'left'
  | 'center'
  | 'searchBar';


()=> {

  let context:JcadContext = null;
  let getContextSpy:any = null;
  let getDecoratorSpy:any = null;
  let annotationSpy:any = null;
  let decorateSpy:any = null;

  before(()=> {
    getContextSpy = sinon.spy(JcadContextManager.getInstance(), "getContext");
    getDecoratorSpy =
             sinon.spy(DecoratorConnectorManager.getInstance(), "getDecorator");
    annotationSpy = sinon.spy(DELETEAnnotation, "DELETE");
    decorateSpy = sinon.spy(utils.TEST_DECORATOR, "decorate");
    context = utils.initContext();
    utils.buildClassRef();
  });

  after(()=> {
    utils.resetContext(context);
    sinon.restore();
  });

  beforeEach(()=> {
    utils.buildClassRef();
  });

  describe("@DELETE", ()=> {

    it("should invoke the JcadContextManager with the JarsConnectorRefs.DELETE_CONNECTOR_REF reference", function() {
      sinon.assert.calledOnce(getContextSpy);
      sinon.assert.calledWith(
        getContextSpy, JarsConnectorRefs.DELETE_CONNECTOR_REF
      );
    });

    it("should invoke the DecoratorConnectorManager with the JarsConnectorRefs.DELETE_CONNECTOR_REF reference and the correct JCAD context", function() {
      sinon.assert.calledOnce(getDecoratorSpy);
      sinon.assert.calledWith(
        getDecoratorSpy, JarsConnectorRefs.DELETE_CONNECTOR_REF, context
      );
    });

    it("should invoke the annotation decorator with the right parameters", function() {
      sinon.assert.calledOnce(annotationSpy);
      //sinon.assert.calledWith(getDecoratorSpy, params.HTTP_METHOD_PARAMS);
    });

    it("should invoke the registered decorator with the right method name and parameters", function() {
      sinon.assert.calledOnce(decorateSpy);
      //sinon.assert.calledWith(getDecoratorSpy, params.HTTP_METHOD_PARAMS);
    });
  });
}


()=> {
    getContextSpy = sinon.spy(JcadContextManager.getInstance(), "getContext");
    getDecoratorSpy =
             sinon.spy(DecoratorConnectorManager.getInstance(), "getDecorator");
    annotationSpy = sinon.spy(DELETEAnnotation, "DELETE");
    decorateSpy = sinon.spy(utils.TEST_DECORATOR, "decorate");
    context = utils.initContext();
    utils.buildClassRef();
  }


()=> {
    utils.resetContext(context);
    sinon.restore();
  }


()=> {
    utils.buildClassRef();
  }


()=> {

    it("should invoke the JcadContextManager with the JarsConnectorRefs.DELETE_CONNECTOR_REF reference", function() {
      sinon.assert.calledOnce(getContextSpy);
      sinon.assert.calledWith(
        getContextSpy, JarsConnectorRefs.DELETE_CONNECTOR_REF
      );
    });

    it("should invoke the DecoratorConnectorManager with the JarsConnectorRefs.DELETE_CONNECTOR_REF reference and the correct JCAD context", function() {
      sinon.assert.calledOnce(getDecoratorSpy);
      sinon.assert.calledWith(
        getDecoratorSpy, JarsConnectorRefs.DELETE_CONNECTOR_REF, context
      );
    });

    it("should invoke the annotation decorator with the right parameters", function() {
      sinon.assert.calledOnce(annotationSpy);
      //sinon.assert.calledWith(getDecoratorSpy, params.HTTP_METHOD_PARAMS);
    });

    it("should invoke the registered decorator with the right method name and parameters", function() {
      sinon.assert.calledOnce(decorateSpy);
      //sinon.assert.calledWith(getDecoratorSpy, params.HTTP_METHOD_PARAMS);
    });
  }


(region: string, options?: any) => {
  let regionInfo: RegionInfo | undefined = undefined;
  switch (region) {
    // First, try to match exact region names.
    case "af-south-1":
      regionInfo = {
        hostname: "route53resolver.af-south-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-east-1":
      regionInfo = {
        hostname: "route53resolver.ap-east-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-northeast-1":
      regionInfo = {
        hostname: "route53resolver.ap-northeast-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-northeast-2":
      regionInfo = {
        hostname: "route53resolver.ap-northeast-2.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-northeast-3":
      regionInfo = {
        hostname: "route53resolver.ap-northeast-3.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-south-1":
      regionInfo = {
        hostname: "route53resolver.ap-south-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-southeast-1":
      regionInfo = {
        hostname: "route53resolver.ap-southeast-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ap-southeast-2":
      regionInfo = {
        hostname: "route53resolver.ap-southeast-2.amazonaws.com",
        partition: "aws",
      };
      break;
    case "ca-central-1":
      regionInfo = {
        hostname: "route53resolver.ca-central-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "cn-north-1":
      regionInfo = {
        hostname: "route53resolver.cn-north-1.amazonaws.com.cn",
        partition: "aws-cn",
      };
      break;
    case "cn-northwest-1":
      regionInfo = {
        hostname: "route53resolver.cn-northwest-1.amazonaws.com.cn",
        partition: "aws-cn",
      };
      break;
    case "eu-central-1":
      regionInfo = {
        hostname: "route53resolver.eu-central-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "eu-north-1":
      regionInfo = {
        hostname: "route53resolver.eu-north-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "eu-south-1":
      regionInfo = {
        hostname: "route53resolver.eu-south-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "eu-west-1":
      regionInfo = {
        hostname: "route53resolver.eu-west-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "eu-west-2":
      regionInfo = {
        hostname: "route53resolver.eu-west-2.amazonaws.com",
        partition: "aws",
      };
      break;
    case "eu-west-3":
      regionInfo = {
        hostname: "route53resolver.eu-west-3.amazonaws.com",
        partition: "aws",
      };
      break;
    case "me-south-1":
      regionInfo = {
        hostname: "route53resolver.me-south-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "sa-east-1":
      regionInfo = {
        hostname: "route53resolver.sa-east-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "us-east-1":
      regionInfo = {
        hostname: "route53resolver.us-east-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "us-east-2":
      regionInfo = {
        hostname: "route53resolver.us-east-2.amazonaws.com",
        partition: "aws",
      };
      break;
    case "us-gov-east-1":
      regionInfo = {
        hostname: "route53resolver.us-gov-east-1.amazonaws.com",
        partition: "aws-us-gov",
      };
      break;
    case "us-gov-west-1":
      regionInfo = {
        hostname: "route53resolver.us-gov-west-1.amazonaws.com",
        partition: "aws-us-gov",
      };
      break;
    case "us-west-1":
      regionInfo = {
        hostname: "route53resolver.us-west-1.amazonaws.com",
        partition: "aws",
      };
      break;
    case "us-west-2":
      regionInfo = {
        hostname: "route53resolver.us-west-2.amazonaws.com",
        partition: "aws",
      };
      break;
    // Next, try to match partition endpoints.
    default:
      if (AWS_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_TEMPLATE.replace("{region}", region),
          partition: "aws",
        };
      }
      if (AWS_CN_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_CN_TEMPLATE.replace("{region}", region),
          partition: "aws-cn",
        };
      }
      if (AWS_ISO_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_ISO_TEMPLATE.replace("{region}", region),
          partition: "aws-iso",
        };
      }
      if (AWS_ISO_B_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_ISO_B_TEMPLATE.replace("{region}", region),
          partition: "aws-iso-b",
        };
      }
      if (AWS_US_GOV_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_US_GOV_TEMPLATE.replace("{region}", region),
          partition: "aws-us-gov",
        };
      }
      // Finally, assume it's an AWS partition endpoint.
      if (regionInfo === undefined) {
        regionInfo = {
          hostname: AWS_TEMPLATE.replace("{region}", region),
          partition: "aws",
        };
      }
  }
  return Promise.resolve({ signingService: "route53resolver", ...regionInfo });
}


() => {
  const history = useHistory();
  const location = useLocation();
  const loadedUser = useSelector((state: ReduxState) => state.users.loadedUser);
  const authenticated = useSelector((state: ReduxState) => state.users.authenticated);

  const dispatch = useDispatch();
  const dispatchLoadUser = React.useCallback(() => dispatch(_users.loadSession()), [dispatch]);

  /**
   * Automatically redirect based on authentication
   */
  React.useEffect(() => {
    if (!loadedUser) {
      dispatchLoadUser();
    } else {
      if (!authenticated) {
        history.push("/login");
      } else if (location.pathname === "/login") {
        history.push("/");
      }
    }
  }, [authenticated, dispatchLoadUser, history, loadedUser, location.pathname]);

  return (
    <Switch>
      <Route path="/login" component={LoginPage} />
      <Route path="/" component={App} />
    </Switch>


(state: ReduxState) => state.users.loadedUser


(state: ReduxState) => state.users.authenticated


() => dispatch(_users.loadSession())


() => {
    if (!loadedUser) {
      dispatchLoadUser();
    } else {
      if (!authenticated) {
        history.push("/login");
      } else if (location.pathname === "/login") {
        history.push("/");
      }
    }
  }


(a: Attachment) => a.type === attachmentType


class VedleggSpørsmål extends React.Component<Props> {
    constructor(props: Props) {
        super(props);
        this.updateVedleggList = this.updateVedleggList.bind(this);
        this.updateVedleggItem = this.updateVedleggItem.bind(this);
        this.deleteVedleggItem = this.deleteVedleggItem.bind(this);
    }

    updateVedleggItem(vedleggItem: Attachment) {
        const { vedlegg } = this.props;
        let vedleggList: Attachment[] = vedlegg || [];
        const index = vedleggList.indexOf(vedleggItem);
        if (index >= 0) {
            vedleggList[index] = vedleggItem;
        } else {
            vedleggList = [vedleggItem];
        }
        this.updateVedleggList(vedleggList);
    }

    deleteVedleggItem(vedleggItem: Attachment) {
        const { vedlegg } = this.props;
        const vedleggList: Attachment[] = vedlegg || [];
        const index = vedleggList.indexOf(vedleggItem);
        vedleggList.splice(index, 1);
        this.updateVedleggList(vedleggList);
    }

    updateVedleggList(vedlegg: Attachment[]) {
        this.props.onChange(vedlegg);
    }

    render() {
        const { vedlegg, skjemanummer, attachmentType } = this.props;
        return (
            <AttachmentsUploader
                attachments={vedlegg ? vedlegg.filter((a: Attachment) => a.type === attachmentType) : []}
                onFilesUploadStart={(nyeVedlegg) => {
                    this.updateVedleggList([...(vedlegg || []), ...nyeVedlegg]);
                }}
                onFileUploadFinish={this.updateVedleggItem}
                onFileDelete={this.deleteVedleggItem}
                attachmentType={attachmentType}
                skjemanummer={skjemanummer}
            />
        );
    }


interface OwnProps {
    vedlegg?: Attachment[];
    attachmentType: AttachmentType;
    onChange: (vedlegg: Attachment[]) => void;
    skjemanummer: Skjemanummer;
    intl: IntlShape;
}


type Props = OwnProps;


updateVedleggItem(vedleggItem: Attachment) {
        const { vedlegg } = this.props;
        let vedleggList: Attachment[] = vedlegg || [];
        const index = vedleggList.indexOf(vedleggItem);
        if (index >= 0) {
            vedleggList[index] = vedleggItem;
        } else {
            vedleggList = [vedleggItem];
        }
        this.updateVedleggList(vedleggList);
    }


deleteVedleggItem(vedleggItem: Attachment) {
        const { vedlegg } = this.props;
        const vedleggList: Attachment[] = vedlegg || [];
        const index = vedleggList.indexOf(vedleggItem);
        vedleggList.splice(index, 1);
        this.updateVedleggList(vedleggList);
    }


updateVedleggList(vedlegg: Attachment[]) {
        this.props.onChange(vedlegg);
    }


render() {
        const { vedlegg, skjemanummer, attachmentType } = this.props;
        return (
            <AttachmentsUploader
                attachments={vedlegg ? vedlegg.filter((a: Attachment) => a.type === attachmentType) : []}
                onFilesUploadStart={(nyeVedlegg) => {
                    this.updateVedleggList([...(vedlegg || []), ...nyeVedlegg]);
                }}


export function setStore(s: Store) {
  store = s
  const state = s.getState()
  onStoreStartedListeners.forEach(l => l(state))
}


export function onStoreStarted(l: (s: State) => void) {
  onStoreStartedListeners.push(l)
}


export function onAfterActionDispatch<T extends AllActions['type']>(type: T, listener: OnActionDispatchListener<T>) {
  onAfterActionDispatchListeners.push({ type, listener })
}


export function onBeforeActionDispatch<T extends AllActions['type']>(type: T, listener: OnActionDispatchListener<T>) {
  onBeforeActionDispatchListeners.push({ type, listener })
}


export function getState(): State {
  return store.getState()
}


export function dispatch(action: AllActions) {
  const state = store.getState()
  onBeforeActionDispatchListeners!.filter(i => i.type === action.type).forEach(l => l.listener(action, state))
  store.dispatch(action)
  const state2 = store.getState()
  onAfterActionDispatchListeners!.filter(i => i.type === action.type).forEach(l => l.listener(action, state2))
}


l => l(state)


i => i.type === action.type


l => l.listener(action, state)


l => l.listener(action, state2)


export type ActionForType<T extends AllActions['type']> = AllActions extends infer R ? R extends AllActions ? T extends R['type'] ? R : never : never : never


type OnActionDispatchListener<T extends AllActions['type']= AllActions['type']> = (action: ActionForType<T>, state: State) => void


export type AllActions =

  RequestCodeChangeAction | EditorModelChangedAction |

  PushLogAction |

  ChangeAutoApply | SelectExplorer | SetWorking |

  ChangeThemeAction |

  FetchCompiledAction | RenderCompiledAction | ErrorCompiledAction |

  JSXColorsActions


function createIntlMock() {
    const intlProvider = new IntlProvider({ locale: 'en-US', messages: messagesMap['en-US'] }, {});
    const { intl } = intlProvider.getChildContext();
    return intl;
}


function getResponse(response: string, delay: number): Promise<string> {
    return new Promise((resolve) => {
        setTimeout(() => resolve(response), delay);
    });
}


function fetchVisObject(uri: string): Promise<VisualizationObject.IVisualizationObject> {
    const visObj = charts.find(chart => chart.visualizationObject.meta.uri === uri);

    if (!visObj) {
        throw new Error(`Unknown uri ${uri}`);
    }

    return Promise.resolve(visObj.visualizationObject);
}


function fetchVisualizationClass(visualizationClassUri: string): Promise<VisualizationClass.IVisualizationClass> {
    const visClass = visualizationClasses.find(vc => vc.visualizationClass.meta.uri === visualizationClassUri);

    if (!visClass) {
        throw new Error(`Unknown uri ${visualizationClassUri}`);
    }

    return Promise.resolve(visClass.visualizationClass);
}


// tslint:disable-next-line:variable-name
function uriResolver(_projectId: string, uri: string, identifier: string): Promise<string> {
    if (identifier === TABLE_IDENTIFIER || uri === TABLE_URI) {
        return getResponse(TABLE_URI, FAST);
    }

    if (identifier === CHART_IDENTIFIER || uri === CHART_URI) {
        return getResponse(CHART_URI, SLOW);
    }

    return Promise.reject('Unknown identifier');
}


(resolve) => {
        setTimeout(() => resolve(response), delay);
    }


() => resolve(response)


chart => chart.visualizationObject.meta.uri === uri


vc => vc.visualizationClass.meta.uri === visualizationClassUri


() => {
    it('should construct and provide intl', () => {
        const wrapper = mount(
            <Visualization
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
            />
        );

        return delay(FAST + 1).then(() => {
            expect(wrapper.find(IntlWrapper).length).toBe(1);
            expect(wrapper.find(IntlVisualization).length).toBe(1);
        });
    });
}


() => {
        const wrapper = mount(
            <Visualization
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
            />
        );

        return delay(FAST + 1).then(() => {
            expect(wrapper.find(IntlWrapper).length).toBe(1);
            expect(wrapper.find(IntlVisualization).length).toBe(1);
        });
    }


() => {
            expect(wrapper.find(IntlWrapper).length).toBe(1);
            expect(wrapper.find(IntlVisualization).length).toBe(1);
        }


() => {
    const intl = createIntlMock();

    it('should render chart', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
        });
    });

    it('should render table', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                intl={intl}
            />
        );

        const expectedResultSpec: AFM.IResultSpec = {
            dimensions: [
                {
                    itemIdentifiers: ['a1'],
                    totals: [
                        {
                            attributeIdentifier: 'a1',
                            measureIdentifier: 'm1',
                            type: 'avg'
                        }
                    ]
                },
                {
                    itemIdentifiers: ['measureGroup']
                }
            ],
            sorts: [
                {
                    attributeSortItem: {
                        attributeIdentifier: 'a1', direction: 'asc'
                    }
                }
            ]
        };

        const expectedTotals: VisualizationObject.IVisualizationTotal[] = [
            {
                type: 'avg',
                alias: 'average',
                measureIdentifier: 'm1',
                attributeIdentifier: 'a1'
            }
        ];

        return delay(SLOW).then(() => {
            expect(wrapper.find(SortableTable).length).toBe(1);
            expect(wrapper.state('type')).toEqual(VisualizationTypes.TABLE);
            expect(wrapper.state('dataSource')).not.toBeNull();
            expect(wrapper.state('resultSpec')).toEqual(expectedResultSpec);
            expect(wrapper.state('totals')).toEqual(expectedTotals);
        });
    });

    it('should render with uri', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                uri={CHART_URI}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
        });
    });

    it('should trigger error in case of given uri is not valid', (done) => {
        const errorHandler = (value: { status: string }) => {
            expect(value.status).toEqual(ErrorStates.NOT_FOUND);
            done();
        };

        mount(
            <VisualizationWrapped
                projectId={projectId}
                uri={'/invalid/url'}
                onError={errorHandler}
                intl={intl}
            />
        );
    });

    it('should handle slow requests', () => {
        // Response from first request comes back later that from the second one
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                intl={intl}
            />
        );

        wrapper.setProps({ identifier: TABLE_IDENTIFIER });

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(Table).length).toBe(1);
        });
    });

    it('should handle set state on unmounted component', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                intl={intl}
            />
        );

        const spy = jest.spyOn(wrapper.instance(), 'setState');

        // Would throw an error if not handled properly
        wrapper.unmount();
        return delay(FAST + 1).then(() => {
            expect(spy).not.toHaveBeenCalled();
            spy.mockRestore();
        });
    });

    it('should pass LoadingComponent and ErrorComponent to TableComponent', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                LoadingComponent={LoadingComponent}
                ErrorComponent={ErrorComponent}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(Table).length).toBe(1);
            const TableElement = wrapper.find(Table).get(0);
            expect(TableElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(TableElement.props.ErrorComponent).toBe(ErrorComponent);
        });
    });

    it('should pass LoadingComponent and ErrorComponent to BaseChart', () => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                LoadingComponent={LoadingComponent}
                ErrorComponent={ErrorComponent}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
            const BaseChartElement = wrapper.find(BaseChart).get(0);
            expect(BaseChartElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(BaseChartElement.props.ErrorComponent).toBe(ErrorComponent);
        });
    });
}


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
        });
    }


() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
        }


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                intl={intl}
            />
        );

        const expectedResultSpec: AFM.IResultSpec = {
            dimensions: [
                {
                    itemIdentifiers: ['a1'],
                    totals: [
                        {
                            attributeIdentifier: 'a1',
                            measureIdentifier: 'm1',
                            type: 'avg'
                        }
                    ]
                },
                {
                    itemIdentifiers: ['measureGroup']
                }
            ],
            sorts: [
                {
                    attributeSortItem: {
                        attributeIdentifier: 'a1', direction: 'asc'
                    }
                }
            ]
        };

        const expectedTotals: VisualizationObject.IVisualizationTotal[] = [
            {
                type: 'avg',
                alias: 'average',
                measureIdentifier: 'm1',
                attributeIdentifier: 'a1'
            }
        ];

        return delay(SLOW).then(() => {
            expect(wrapper.find(SortableTable).length).toBe(1);
            expect(wrapper.state('type')).toEqual(VisualizationTypes.TABLE);
            expect(wrapper.state('dataSource')).not.toBeNull();
            expect(wrapper.state('resultSpec')).toEqual(expectedResultSpec);
            expect(wrapper.state('totals')).toEqual(expectedTotals);
        });
    }


() => {
            expect(wrapper.find(SortableTable).length).toBe(1);
            expect(wrapper.state('type')).toEqual(VisualizationTypes.TABLE);
            expect(wrapper.state('dataSource')).not.toBeNull();
            expect(wrapper.state('resultSpec')).toEqual(expectedResultSpec);
            expect(wrapper.state('totals')).toEqual(expectedTotals);
        }


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                uri={CHART_URI}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                uriResolver={uriResolver}
                BaseChartComponent={BaseChart}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
        });
    }


(done) => {
        const errorHandler = (value: { status: string }) => {
            expect(value.status).toEqual(ErrorStates.NOT_FOUND);
            done();
        };

        mount(
            <VisualizationWrapped
                projectId={projectId}
                uri={'/invalid/url'}
                onError={errorHandler}
                intl={intl}
            />
        );
    }


(value: { status: string }) => {
            expect(value.status).toEqual(ErrorStates.NOT_FOUND);
            done();
        }


() => {
        // Response from first request comes back later that from the second one
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                intl={intl}
            />
        );

        wrapper.setProps({ identifier: TABLE_IDENTIFIER });

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(Table).length).toBe(1);
        });
    }


() => {
            expect(wrapper.find(Table).length).toBe(1);
        }


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                intl={intl}
            />
        );

        const spy = jest.spyOn(wrapper.instance(), 'setState');

        // Would throw an error if not handled properly
        wrapper.unmount();
        return delay(FAST + 1).then(() => {
            expect(spy).not.toHaveBeenCalled();
            spy.mockRestore();
        });
    }


() => {
            expect(spy).not.toHaveBeenCalled();
            spy.mockRestore();
        }


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={TABLE_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                LoadingComponent={LoadingComponent}
                ErrorComponent={ErrorComponent}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(Table).length).toBe(1);
            const TableElement = wrapper.find(Table).get(0);
            expect(TableElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(TableElement.props.ErrorComponent).toBe(ErrorComponent);
        });
    }


() => {
            expect(wrapper.find(Table).length).toBe(1);
            const TableElement = wrapper.find(Table).get(0);
            expect(TableElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(TableElement.props.ErrorComponent).toBe(ErrorComponent);
        }


() => {
        const wrapper = mount(
            <VisualizationWrapped
                projectId={projectId}
                identifier={CHART_IDENTIFIER}
                uriResolver={uriResolver}
                fetchVisObject={fetchVisObject}
                fetchVisualizationClass={fetchVisualizationClass}
                BaseChartComponent={BaseChart}
                TableComponent={Table}
                LoadingComponent={LoadingComponent}
                ErrorComponent={ErrorComponent}
                intl={intl}
            />
        );

        return delay(SLOW + 1).then(() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
            const BaseChartElement = wrapper.find(BaseChart).get(0);
            expect(BaseChartElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(BaseChartElement.props.ErrorComponent).toBe(ErrorComponent);
        });
    }


() => {
            expect(wrapper.find(BaseChart).length).toBe(1);
            const BaseChartElement = wrapper.find(BaseChart).get(0);
            expect(BaseChartElement.props.LoadingComponent).toBe(LoadingComponent);
            expect(BaseChartElement.props.ErrorComponent).toBe(ErrorComponent);
        }


async () => {
    const a = tf.tensor1d([3, -1, 0, 100, -7, 2]);
    const r = tf.max(a);
    expectArraysClose(await r.data(), 100);
  }


async () => {
    const a = tf.tensor1d([3, 3, 3]);
    const r = tf.max(a);
    expectArraysClose(await r.data(), 3);
  }


async () => {
    const aData = new Float32Array(1000);
    aData[0] = 1;
    const a = tf.tensor1d(aData);
    const r = tf.max(a);
    expectArraysClose(await r.data(), 1);
  }


async () => {
    expectArraysClose(await tf.max([3, NaN, 2]).data(), NaN);
  }


async () => {
    const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
    expectArraysClose(await tf.max(a).data(), 100);
  }


async () => {
    const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
    expectArraysClose(await tf.max(a, [0, 1]).data(), 100);
  }


async () => {
    const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
    const r = tf.max(a, [0]);

    expect(r.shape).toEqual([3]);
    expectArraysClose(await r.data(), [100, -1, 2]);
  }


async () => {
    const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
    const r = tf.max(a, [0], true /* keepDims */);

    expect(r.shape).toEqual([1, 3]);
    expectArraysClose(await r.data(), [100, -1, 2]);
  }


async () => {
    const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
    const r = tf.max(a, 1);
    expectArraysClose(await r.data(), [5, 100]);
  }


async () => {
    const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
    const r = tf.max(a, -1);
    expectArraysClose(await r.data(), [5, 100]);
  }


async () => {
    const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
    const r = tf.max(a, [1]);
    expectArraysClose(await r.data(), [5, 100]);
  }


async () => {
    const a = tf.range(0, 64).reshape([2, 2, 2, 2, 2, 2]);
    const r = tf.max(a, [5]);
    const expectedResult = [
      1,  3,  5,  7,  9,  11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
      33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63
    ];
    expectArraysClose(await r.data(), expectedResult);
  }


async () => {
    const input = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
    const inputDataBefore = await input.data();

    tf.max(input, [1, 0]);

    const inputDataAfter = await input.data();
    expectArraysClose(inputDataBefore, inputDataAfter);
  }


() => {
    expect(() => tf.max({} as tf.Tensor))
        .toThrowError(/Argument 'x' passed to 'max' must be a Tensor/);
  }


() => tf.max({} as tf.Tensor)


async () => {
    const r = tf.max([3, -1, 0, 100, -7, 2]);
    expectArraysClose(await r.data(), 100);
  }


async () => {
    const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3], 'int32');
    expect(a.dtype).toEqual('int32');
    expectArraysClose(await tf.max(a).data(), 100);
  }


async () => {
    const x = tf.scalar(42);
    const dy = tf.scalar(-1);
    const gradients = tf.grad(v => tf.max(v))(x, dy);
    expectArraysClose(await gradients.data(), [-1]);
  }


v => tf.max(v)


async () => {
    const x = tf.scalar(42);
    const dy = tf.scalar(-1);
    const gradients = tf.grad(v => tf.max(v.clone()).clone())(x, dy);
    expectArraysClose(await gradients.data(), [-1]);
  }


v => tf.max(v.clone()).clone()


async () => {
    const x = tf.tensor1d([1, 3, 7, 7]);
    const dy = tf.scalar(-1);
    const gradients = tf.grad(v => tf.max(v))(x, dy);
    expectArraysClose(await gradients.data(), [0, 0, -1, -1]);
  }


async () => {
    const x = tf.tensor2d([[0, 20, 10], [-10, -30, -20]]);
    const dy = tf.tensor1d([-1, -1]);
    const axis = -1;
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, 0, -1, 0, 0]);
    expect(gradients.shape).toEqual([2, 3]);
  }


v => tf.max(v, axis)


async () => {
    const x = tf.tensor2d([[0, 20, 20], [-10, -30, -10]]);
    const dy = tf.tensor1d([-1, -1]);
    const axis = -1;
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, -1, -1, 0, -1]);
    expect(gradients.shape).toEqual([2, 3]);
  }


async () => {
    const x = tf.tensor2d([[0, 20, 10], [-10, -30, 20]]);
    const dy = tf.tensor1d([-1, -1, -1]);
    const axis = 0;
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [-1, -1, 0, 0, 0, -1]);
    expect(gradients.shape).toEqual([2, 3]);
  }


async () => {
    const x = tf.tensor2d([[0, 20, 10], [-10, -30, -20]]);
    const dy = tf.tensor2d([[-1], [-1]]);
    const axis = -1;
    const keepDims = true;
    const gradients = tf.grad(v => tf.max(v, axis, keepDims))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, 0, -1, 0, 0]);
    expect(gradients.shape).toEqual([2, 3]);
  }


v => tf.max(v, axis, keepDims)


async () => {
    const x = tf.tensor2d([[0, 20, 10], [-10, -30, 20]]);
    const dy = tf.tensor2d([[-1, -1, -1]]);
    const axis = 0;
    const keepDims = true;
    const gradients = tf.grad(v => tf.max(v, axis, keepDims))(x, dy);
    expectArraysClose(await gradients.data(), [-1, -1, 0, 0, 0, -1]);
    expect(gradients.shape).toEqual([2, 3]);
  }


async () => {
    const x = tf.ones([2, 1, 250]);
    const axis = 1;
    const gradients = tf.grad(v => tf.max(v, axis))(x);
    expect(gradients.shape).toEqual(x.shape);
  }


async () => {
    const x = tf.tensor3d([[[0, 20], [10, 15]], [[-10, -30], [-20, -15]]]);
    const dy = tf.tensor1d([-1, -1]);
    const axis = [1, 2];
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, 0, 0, -1, 0, 0, 0]);
    expect(gradients.shape).toEqual([2, 2, 2]);
  }


async () => {
    const x = tf.tensor3d([[[0, 20], [20, 20]], [[-10, -30], [-10, -15]]]);
    const dy = tf.tensor1d([-1, -1]);
    const axis = [1, 2];
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, -1, -1, -1, 0, -1, 0]);
    expect(gradients.shape).toEqual([2, 2, 2]);
  }


async () => {
    const x = tf.tensor3d([[[0, 20], [10, 15]], [[-10, -30], [-20, -15]]]);
    const dy = tf.tensor2d([[-1, -1], [-1, -1]]);
    const axis = 2;
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, 0, -1, -1, 0, 0, -1]);
    expect(gradients.shape).toEqual([2, 2, 2]);
  }


async () => {
    const x = tf.tensor3d([[[0, 20], [10, 15]], [[-10, -30], [-20, -15]]]);
    const dy = tf.tensor3d([[[-1], [-1]], [[-1], [-1]]]);
    const axis = 2;
    const keepDims = true;
    const gradients = tf.grad(v => tf.max(v, axis, keepDims))(x, dy);
    expectArraysClose(await gradients.data(), [0, -1, 0, -1, -1, 0, 0, -1]);
    expect(gradients.shape).toEqual([2, 2, 2]);
  }


async () => {
    const x = tf.tensor4d([
      [[[0, 20], [20, 20]], [[-10, -30], [-10, -30]]],
      [[[0, -20], [-20, -20]], [[10, 30], [10, 30]]]
    ]);
    const dy = tf.tensor1d([-1, -1]);
    const axis = [1, 2, 3];
    const gradients = tf.grad(v => tf.max(v, axis))(x, dy);
    expectArraysClose(
        await gradients.data(),
        [0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1]);
    expect(gradients.shape).toEqual([2, 2, 2, 2]);
  }


async () => {
    const x = tf.tensor4d([
      [[[0, 20], [20, 20]], [[-10, -30], [-10, -30]]],
      [[[0, -20], [-20, -20]], [[10, 30], [10, 30]]]
    ]);
    const dy = tf.tensor4d([[[[-1]], [[-2]]], [[[-3]], [[-4]]]]);
    const axis = [2, 3];
    const keepDims = true;
    const gradients = tf.grad(v => tf.max(v, axis, keepDims))(x, dy);
    expectArraysClose(
        await gradients.data(),
        [0, -1, -1, -1, -2, 0, -2, 0, -3, 0, 0, 0, 0, -4, 0, -4]);
    expect(gradients.shape).toEqual([2, 2, 2, 2]);
  }


() => {
    expect(() => tf.max(['a']))
        .toThrowError(/Argument 'x' passed to 'max' must be numeric tensor/);
  }


() => tf.max(['a'])


export interface Student {
    firstName:string;
    lastName:string;
    studentEmail:string;
    course:string;
    yearOfStudy: bigint;
    registrationNumber:string;
  }


export default class GameNode {
    id: string;
    state: any;
}


export class AbstractTrieNode<T> implements TrieNode {

  /**
   * @override
   */
  public kind: TrieNodeKind;

  private children_: {[key: string]: TrieNode} = {};

  /**
   * @param constraint The constraint the node represents.
   * @param test The constraint test of this node.
   */
  constructor(
    public constraint: string, public test: ((p1: T) => boolean)|null) {
    this.kind = TrieNodeKind.ROOT;
  }

  /**
   * @override
   */
  public getConstraint() {
    return this.constraint;
  }

  /**
   * @override
   */
  public getKind() {
    return this.kind;
  }

  /**
   * @override
   */
  public applyTest(object: T) {
    return this.test(object);
  }

  /**
   * @override
   */
  public addChild(node: TrieNode) {
    let constraint = node.getConstraint();
    let child = this.children_[constraint];
    this.children_[constraint] = node;
    return child;
  }

  /**
   * @override
   */
  public getChild(constraint: string) {
    return this.children_[constraint];
  }

  /**
   * @override
   */
  public getChildren() {
    let children = [];
    for (let key in this.children_) {
      children.push(this.children_[key]);
    }
    return children;
  }

  /**
   * @override
   */
  public findChildren(object: T) {
    let children = [];
    for (let key in this.children_) {
      let child = this.children_[key];
      if (child.applyTest(object)) {
        children.push(child);
      }
    }
    return children;
  }

  /**
   * @override
   */
  public removeChild(constraint: string) {
    delete this.children_[constraint];
  }

  /**
   * @override
   */
  public toString() {
    return this.constraint;
  }
}


export class StaticTrieNode extends AbstractTrieNode<Node> {

  private rule_: SpeechRule|null = null;

  /**
   * @param constraint The constraint the node represents.
   * @param test The constraint test of this node.
   */
  constructor(constraint: string, test: ((p1: Node) => boolean)|null) {
    super(constraint, test);
    this.kind = TrieNodeKind.STATIC;
  }

  /**
   * @return The speech rule of the node.
   */
  public getRule(): SpeechRule|null {
    return this.rule_;
  }

  /**
   * @param rule speech rule of the node.
   */
  public setRule(rule: SpeechRule) {
    if (this.rule_) {
      Debugger.getInstance().output(
          'Replacing rule ' + this.rule_ + ' with ' + rule);
    }
    this.rule_ = rule;
  }

  /**
   * @override
   */
  public toString() {
    let rule = this.getRule();
    return rule ? this.constraint + '\n' +
            '==> ' + this.getRule().action :
                  this.constraint;
  }
}


/**
   * @override
   */
public getConstraint() {
    return this.constraint;
  }


/**
   * @override
   */
public getKind() {
    return this.kind;
  }


/**
   * @override
   */
public applyTest(object: T) {
    return this.test(object);
  }


/**
   * @override
   */
public addChild(node: TrieNode) {
    let constraint = node.getConstraint();
    let child = this.children_[constraint];
    this.children_[constraint] = node;
    return child;
  }


/**
   * @override
   */
public getChild(constraint: string) {
    return this.children_[constraint];
  }


/**
   * @override
   */
public getChildren() {
    let children = [];
    for (let key in this.children_) {
      children.push(this.children_[key]);
    }
    return children;
  }


/**
   * @override
   */
public findChildren(object: T) {
    let children = [];
    for (let key in this.children_) {
      let child = this.children_[key];
      if (child.applyTest(object)) {
        children.push(child);
      }
    }
    return children;
  }


/**
   * @override
   */
public removeChild(constraint: string) {
    delete this.children_[constraint];
  }


/**
   * @override
   */
public toString() {
    return this.constraint;
  }


/**
   * @return The speech rule of the node.
   */
public getRule(): SpeechRule|null {
    return this.rule_;
  }


/**
   * @param rule speech rule of the node.
   */
public setRule(rule: SpeechRule) {
    if (this.rule_) {
      Debugger.getInstance().output(
          'Replacing rule ' + this.rule_ + ' with ' + rule);
    }
    this.rule_ = rule;
  }


/**
   * @override
   */
public toString() {
    let rule = this.getRule();
    return rule ? this.constraint + '\n' +
            '==> ' + this.getRule().action :
                  this.constraint;
  }


/**
 *
Gets the network settings.

 * @example
 * Use a bare-bones client and the command you need to make an API call.
 * ```javascript
 * import { WorkSpacesWebClient, GetNetworkSettingsCommand } from "@aws-sdk/client-workspaces-web"; // ES Modules import
 * // const { WorkSpacesWebClient, GetNetworkSettingsCommand } = require("@aws-sdk/client-workspaces-web"); // CommonJS import
 * const client = new WorkSpacesWebClient(config);
 * const command = new GetNetworkSettingsCommand(input);
 * const response = await client.send(command);
 * ```
 *
 * @see {@link GetNetworkSettingsCommandInput} for command's `input` shape.
 * @see {@link GetNetworkSettingsCommandOutput} for command's `response` shape.
 * @see {@link WorkSpacesWebClientResolvedConfig | config} for WorkSpacesWebClient's `config` shape.
 *
 */
export class GetNetworkSettingsCommand extends $Command<
  GetNetworkSettingsCommandInput,
  GetNetworkSettingsCommandOutput,
  WorkSpacesWebClientResolvedConfig
> {
  // Start section: command_properties
  // End section: command_properties

  constructor(readonly input: GetNetworkSettingsCommandInput) {
    // Start section: command_constructor
    super();
    // End section: command_constructor
  }

  /**
   * @internal
   */
  resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: WorkSpacesWebClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<GetNetworkSettingsCommandInput, GetNetworkSettingsCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "WorkSpacesWebClient";
    const commandName = "GetNetworkSettingsCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: GetNetworkSettingsRequest.filterSensitiveLog,
      outputFilterSensitiveLog: GetNetworkSettingsResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }

  private serialize(input: GetNetworkSettingsCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_restJson1GetNetworkSettingsCommand(input, context);
  }

  private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<GetNetworkSettingsCommandOutput> {
    return deserializeAws_restJson1GetNetworkSettingsCommand(output, context);
  }

  // Start section: command_body_extra
  // End section: command_body_extra
}


export interface GetNetworkSettingsCommandInput extends GetNetworkSettingsRequest {}


export interface GetNetworkSettingsCommandOutput extends GetNetworkSettingsResponse, __MetadataBearer {}


/**
   * @internal
   */
resolveMiddleware(
    clientStack: MiddlewareStack<ServiceInputTypes, ServiceOutputTypes>,
    configuration: WorkSpacesWebClientResolvedConfig,
    options?: __HttpHandlerOptions
  ): Handler<GetNetworkSettingsCommandInput, GetNetworkSettingsCommandOutput> {
    this.middlewareStack.use(getSerdePlugin(configuration, this.serialize, this.deserialize));

    const stack = clientStack.concat(this.middlewareStack);

    const { logger } = configuration;
    const clientName = "WorkSpacesWebClient";
    const commandName = "GetNetworkSettingsCommand";
    const handlerExecutionContext: HandlerExecutionContext = {
      logger,
      clientName,
      commandName,
      inputFilterSensitiveLog: GetNetworkSettingsRequest.filterSensitiveLog,
      outputFilterSensitiveLog: GetNetworkSettingsResponse.filterSensitiveLog,
    };
    const { requestHandler } = configuration;
    return stack.resolve(
      (request: FinalizeHandlerArguments<any>) =>
        requestHandler.handle(request.request as __HttpRequest, options || {}),
      handlerExecutionContext
    );
  }


private serialize(input: GetNetworkSettingsCommandInput, context: __SerdeContext): Promise<__HttpRequest> {
    return serializeAws_restJson1GetNetworkSettingsCommand(input, context);
  }


private deserialize(output: __HttpResponse, context: __SerdeContext): Promise<GetNetworkSettingsCommandOutput> {
    return deserializeAws_restJson1GetNetworkSettingsCommand(output, context);
  }


export interface OCPPConfigurationKey {
    key: string | StandardParametersKey;
    readonly: boolean;
    value?: string;
}


export enum ConnectorPhaseRotation {
    NotApplicable = 'NotApplicable',
    Unknown = 'Unknown',
    RST = 'RST',
    RTS = 'RTS',
    SRT = 'SRT',
    STR = 'STR',
    TRS = 'TRS',
    TSR = 'TSR'
}


export type StandardParametersKey = OCPP16StandardParametersKey;


export type SupportedFeatureProfiles = OCPP16SupportedFeatureProfiles;


@Component({
  selector: 'fr-navbar-menu',
  template: ''
})
export class FrNavbarMenuComponent {

  @Input() link: string;
  @Input() title: string;

}


@Controller('patients/:id/investigations')
@ApiUseTags('Investigations')
export class PatientInvestigationController {
  constructor(private readonly patientInvestigationService: PatientInvestigationService) {
  }

  @Get()
  findManyByPatientId(@Param('id') patientId: number) {
    return this.patientInvestigationService.findMany({
      where: {Patient: patientId},
      relations: ['Investigation'],
    });
  }
}


@Get()
  findManyByPatientId(@Param('id') patientId: number) {
    return this.patientInvestigationService.findMany({
      where: {Patient: patientId},
      relations: ['Investigation'],
    });
  }


@NgModule({
  imports: [
    CollapseModule,
    CommonModule,
    IterationModule,
    ModalModule,
    RouterModule
  ],
  declarations: [
    SidepanelComponent
  ],
  exports: [SidepanelComponent]
})
export class SidepanelModule { }


export class WeightWidget extends AbstractWidget {

  getName(): string {
    return 'Weight';
  }

  getUnits(): string {
    return 'kg';
  }

  isAggregated(): boolean {
    return false;
  }

  createTimeWindow(): TimeWindow {
    return {
      type: 'years',
      length: 1
    };
  }

  getType(): GraphType {
    return GraphType.Line;
  }

  getDataTypeName(): string {
    return 'derived:com.google.weight:com.google.android.gms:merge_weight';
    // return 'com.google.weight';
  }
}


getName(): string {
    return 'Weight';
  }


getUnits(): string {
    return 'kg';
  }


isAggregated(): boolean {
    return false;
  }


createTimeWindow(): TimeWindow {
    return {
      type: 'years',
      length: 1
    };
  }


getType(): GraphType {
    return GraphType.Line;
  }


getDataTypeName(): string {
    return 'derived:com.google.weight:com.google.android.gms:merge_weight';
    // return 'com.google.weight';
  }


export default abstract class AbstractDepartment extends AbstractFunction {

    public departmentId: string;
    public departmentName: string;
    public parentDepartmentId: string;
    public managerEmployeeId: string;
    public departmentTitle: string;
    public active: boolean;

    public customFields: Array<[string, any]> = [];
}


({ placeholder: label, style, ...props }) => {
  const [focused, setFocused] = useState(false)

  const handleFocus = useCallback(() => {
    setFocused(true)
  }, [])

  const handleBlur = useCallback(() => {
    setFocused(false)
  }, [])

  return (
    <Container style={style}>
      <Input2 {...props} onFocus={handleFocus} onBlur={handleBlur} className="input-text" />
      <InputBorder data-focused={focused} />
      <Label
        aria-hidden={true}
        style={{
          color: focused ? 'var(--focused-border-color)' : '',
        }}


() => {
    setFocused(true)
  }


() => {
    setFocused(false)
  }


interface Props extends HTMLProps<HTMLInputElement> {}


({ $stateParams: { provider, instanceId } }) => {
        this.setState({ provider, instanceId, loading: true, accountId: null, moniker: null, environment: null });
      }


({ app, $stateParams }) => {
        const { provider, instanceId } = $stateParams;
        const accountId = Observable.fromPromise(SkinService.getAccountForInstance(provider, instanceId, app));
        const moniker = Observable.fromPromise(SkinService.getMonikerForInstance(provider, instanceId, app));
        const accountDetails = accountId.mergeMap(id => AccountService.getAccountDetails(id));
        return Observable.forkJoin(accountId, moniker, accountDetails);
      }


id => AccountService.getAccountDetails(id)


([accountId, moniker, accountDetails]) => {
        const environment = accountDetails && accountDetails.environment;
        this.setState({ accountId, moniker, environment, loading: false });
      }


export class InstanceDetails extends React.Component<IInstanceDetailsProps, IInstanceDetailsState> {
  public state: IInstanceDetailsState = {
    accountId: null,
    environment: null,
    instanceId: null,
    loading: false,
    moniker: null,
    provider: null,
  };

  private destroy$ = new Subject();
  private props$ = new Subject<IInstanceDetailsProps>();

  public componentDidMount() {
    this.props$
      .do(({ $stateParams: { provider, instanceId } }) => {
        this.setState({ provider, instanceId, loading: true, accountId: null, moniker: null, environment: null });
      })
      .switchMap(({ app, $stateParams }) => {
        const { provider, instanceId } = $stateParams;
        const accountId = Observable.fromPromise(SkinService.getAccountForInstance(provider, instanceId, app));
        const moniker = Observable.fromPromise(SkinService.getMonikerForInstance(provider, instanceId, app));
        const accountDetails = accountId.mergeMap(id => AccountService.getAccountDetails(id));
        return Observable.forkJoin(accountId, moniker, accountDetails);
      })
      .takeUntil(this.destroy$)
      .subscribe(([accountId, moniker, accountDetails]) => {
        const environment = accountDetails && accountDetails.environment;
        this.setState({ accountId, moniker, environment, loading: false });
      });

    this.props$.next(this.props);
  }

  public componentWillReceiveProps(nextProps: IInstanceDetailsProps) {
    this.props$.next(nextProps);
  }

  public componentWillUnmount() {
    this.destroy$.next();
  }

  public render() {
    const { accountId, instanceId, moniker, environment, loading, provider } = this.state;

    if (loading) {
      return (
        <InstanceDetailsPane>
          <Spinner size="medium" message=" " />
        </InstanceDetailsPane>
      );
    } else if (!accountId || !moniker || !environment) {
      return (
        <InstanceDetailsPane>
          <h4>
            Could not find {provider} instance {instanceId}.
          </h4>
        </InstanceDetailsPane>
      );
    }

    return <InstanceDetailsCmp {...this.props} accountId={accountId} moniker={moniker} environment={environment} />;
  }
}


@Overridable('instance.details')
export class InstanceDetailsCmp extends React.Component<IInstanceDetailsProps> {
  public render() {
    return
Instance Details
;
  }
}


export interface IInstanceDetailsProps extends IOverridableProps {
  $stateParams: {
    provider: string;
    instanceId: string;
  };
  app: Application;
  moniker: IMoniker;
  environment: string;
}


export interface IInstanceDetailsState {
  accountId: string;
  environment: string;
  instanceId: string;
  loading: boolean;
  moniker: IMoniker;
  provider: string;
}


public componentDidMount() {
    this.props$
      .do(({ $stateParams: { provider, instanceId } }) => {
        this.setState({ provider, instanceId, loading: true, accountId: null, moniker: null, environment: null });
      })
      .switchMap(({ app, $stateParams }) => {
        const { provider, instanceId } = $stateParams;
        const accountId = Observable.fromPromise(SkinService.getAccountForInstance(provider, instanceId, app));
        const moniker = Observable.fromPromise(SkinService.getMonikerForInstance(provider, instanceId, app));
        const accountDetails = accountId.mergeMap(id => AccountService.getAccountDetails(id));
        return Observable.forkJoin(accountId, moniker, accountDetails);
      })
      .takeUntil(this.destroy$)
      .subscribe(([accountId, moniker, accountDetails]) => {
        const environment = accountDetails && accountDetails.environment;
        this.setState({ accountId, moniker, environment, loading: false });
      });

    this.props$.next(this.props);
  }


public componentWillReceiveProps(nextProps: IInstanceDetailsProps) {
    this.props$.next(nextProps);
  }


public componentWillUnmount() {
    this.destroy$.next();
  }


public render() {
    const { accountId, instanceId, moniker, environment, loading, provider } = this.state;

    if (loading) {
      return (
        <InstanceDetailsPane>
          <Spinner size="medium" message=" " />
        </InstanceDetailsPane>
      );
    } else if (!accountId || !moniker || !environment) {
      return (
        <InstanceDetailsPane>
          <h4>
            Could not find {provider} instance {instanceId}.
          </h4>
        </InstanceDetailsPane>
      );
    }

    return <InstanceDetailsCmp {...this.props} accountId={accountId} moniker={moniker} environment={environment} />;
  }


public render() {
    return
Instance Details
;
  }


export declare class ButtonCommandBarExample extends React.Component<IButtonProps, {}> {
    render(): JSX.Element;
}


render(): JSX.Element;


() => {
        Log.logger = console;
        Log.level = Log.NONE;
        localStorage.clear();

        userStoreMock = new WebStorageStateStore();

        subject = new UserManager({
            authority: "http://sts/oidc",
            client_id: "client",
            redirect_uri: "http://app/cb",
            monitorSession : false,
            userStore: userStoreMock,
            metadata: {
                authorization_endpoint: "http://sts/oidc/authorize",
                token_endpoint: "http://sts/oidc/token",
                revocation_endpoint: "http://sts/oidc/revoke",
            },
        });

        const location = Object.defineProperties({}, {
            ...Object.getOwnPropertyDescriptors(window.location),
            assign: {
                enumerable: true,
                value: jest.fn(),
            },
            replace: {
                enumerable: true,
                value: jest.fn(),
            },
        });
        Object.defineProperty(window, "location", {
            enumerable: true,
            get: () => location,
        });
    }


() => location


() => {
        it("should accept settings", () => {
            // act
            expect(subject.settings.client_id).toEqual("client");
        });
    }


() => {
            // act
            expect(subject.settings.client_id).toEqual("client");
        }


() => {
        it("should be UserManagerSettings", () => {
            // act
            expect(subject.settings).toBeInstanceOf(UserManagerSettingsStore);
        });
    }


() => {
            // act
            expect(subject.settings).toBeInstanceOf(UserManagerSettingsStore);
        }


() => {
        it("should be able to call getUser without recursion", () => {
            // arrange
            subject.events.addUserLoaded(async () => {
                await subject.getUser();
            });

            // act
            subject.events.load({} as User);
        });

        it("should return user if there is a user stored", async () => {
            // arrange
            const user = new User({
                access_token: "access_token",
                token_type: "token_type",
                profile: {} as UserProfile,
            });
            subject["_loadUser"] = jest.fn().mockReturnValue(user);
            const loadMock = jest.spyOn(subject["_events"], "load");

            // act
            const result = await subject.getUser();

            // assert
            expect(result).toEqual(user);
            expect(loadMock).toBeCalledWith(user, false);
        });

        it("should return null if there is no user stored", async () => {
            // arrange
            subject["_loadUser"] = jest.fn().mockReturnValue(null);
            const loadMock = jest.spyOn(subject["_events"], "load");

            // act
            const result = await subject.getUser();

            // assert
            expect(result).toBeNull();
            expect(loadMock).not.toBeCalled();
        });
    }


() => {
            // arrange
            subject.events.addUserLoaded(async () => {
                await subject.getUser();
            });

            // act
            subject.events.load({} as User);
        }


async () => {
                await subject.getUser();
            }