/**
   * Writes some data in the shape of the provided GraphQL fragment directly to
   * the store. This method will write to a GraphQL fragment from any arbitrary
   * id that is currently cached, unlike `writeQuery` which will only write
   * from the root query.
   *
   * You must pass in a GraphQL document with a single fragment or a document
   * with multiple fragments that represent what you are writing. If you pass
   * in a document with multiple fragments then you must also specify a
   * `fragmentName`.
   */
public writeFragment<TData = any, TVariables = OperationVariables>(
    options: DataProxy.WriteFragmentOptions<TData, TVariables>,
  ): void {
    this.cache.writeFragment<TData, TVariables>(options);
    this.queryManager.broadcastQueries();
  }


public __actionHookForDevTools(cb: () => any) {
    this.devToolsHookCb = cb;
  }


public __requestRaw(payload: GraphQLRequest): Observable<ExecutionResult> {
    return execute(this.link, payload);
  }


/**
   * Resets your entire store by clearing out your cache and then re-executing
   * all of your active queries. This makes it so that you may guarantee that
   * there is no data left in your store from a time before you called this
   * method.
   *
   * `resetStore()` is useful when your user just logged out. You’ve removed the
   * user session, and you now want to make sure that any references to data you
   * might have fetched while the user session was active is gone.
   *
   * It is important to remember that `resetStore()` *will* refetch any active
   * queries. This means that any components that might be mounted will execute
   * their queries again using your network interface. If you do not want to
   * re-execute any queries then you should make sure to stop watching any
   * active queries.
   */
public resetStore(): Promise<ApolloQueryResult<any>[] | null> {
    return Promise.resolve()
      .then(() => this.queryManager.clearStore({
        discardWatches: false,
      }))
      .then(() => Promise.all(this.resetStoreCallbacks.map(fn => fn())))
      .then(() => this.reFetchObservableQueries());
  }


/**
   * Remove all data from the store. Unlike `resetStore`, `clearStore` will
   * not refetch any active queries.
   */
public clearStore(): Promise<any[]> {
    return Promise.resolve()
      .then(() => this.queryManager.clearStore({
        discardWatches: true,
      }))
      .then(() => Promise.all(this.clearStoreCallbacks.map(fn => fn())));
  }


/**
   * Allows callbacks to be registered that are executed when the store is
   * reset. `onResetStore` returns an unsubscribe function that can be used
   * to remove registered callbacks.
   */
public onResetStore(cb: () => Promise<any>): () => void {
    this.resetStoreCallbacks.push(cb);
    return () => {
      this.resetStoreCallbacks = this.resetStoreCallbacks.filter(c => c !== cb);
    };
  }


/**
   * Allows callbacks to be registered that are executed when the store is
   * cleared. `onClearStore` returns an unsubscribe function that can be used
   * to remove registered callbacks.
   */
public onClearStore(cb: () => Promise<any>): () => void {
    this.clearStoreCallbacks.push(cb);
    return () => {
      this.clearStoreCallbacks = this.clearStoreCallbacks.filter(c => c !== cb);
    };
  }


/**
   * Refetches all of your active queries.
   *
   * `reFetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage
   *
   * It is important to remember that `reFetchObservableQueries()` *will* refetch any active
   * queries. This means that any components that might be mounted will execute
   * their queries again using your network interface. If you do not want to
   * re-execute any queries then you should make sure to stop watching any
   * active queries.
   * Takes optional parameter `includeStandby` which will include queries in standby-mode when refetching.
   */
public reFetchObservableQueries(
    includeStandby?: boolean,
  ): Promise<ApolloQueryResult<any>[]> {
    return this.queryManager.reFetchObservableQueries(includeStandby);
  }


/**
   * Refetches specified active queries. Similar to "reFetchObservableQueries()" but with a specific list of queries.
   *
   * `refetchQueries()` is useful for use cases to imperatively refresh a selection of queries.
   *
   * It is important to remember that `refetchQueries()` *will* refetch specified active
   * queries. This means that any components that might be mounted will execute
   * their queries again using your network interface. If you do not want to
   * re-execute any queries then you should make sure to stop watching any
   * active queries.
   */
public refetchQueries<
    TCache extends ApolloCache<any> = ApolloCache<TCacheShape>,
    TResult = Promise<ApolloQueryResult<any>>,
  >(
    options: RefetchQueriesOptions<TCache, TResult>,
  ): RefetchQueriesResult<TResult> {
    const map = this.queryManager.refetchQueries(options);
    const queries: ObservableQuery<any>[] = [];
    const results: InternalRefetchQueriesResult<TResult>[] = [];

    map.forEach((result, obsQuery) => {
      queries.push(obsQuery);
      results.push(result);
    });

    const result = Promise.all<TResult>(
      results as TResult[]
    ) as RefetchQueriesResult<TResult>;

    // In case you need the raw results immediately, without awaiting
    // Promise.all(results):
    result.queries = queries;
    result.results = results;

    // If you decide to ignore the result Promise because you're using
    // result.queries and result.results instead, you shouldn't have to worry
    // about preventing uncaught rejections for the Promise.all result.
    result.catch(error => {
      invariant.debug(`In client.refetchQueries, Promise.all promise rejected with error ${error}`);
    });

    return result;
  }


/**
   * Get all currently active `ObservableQuery` objects, in a `Map` keyed by
   * query ID strings. An "active" query is one that has observers and a
   * `fetchPolicy` other than "standby" or "cache-only". You can include all
   * `ObservableQuery` objects (including the inactive ones) by passing "all"
   * instead of "active", or you can include just a subset of active queries by
   * passing an array of query names or DocumentNode objects.
   */
public getObservableQueries(
    include: RefetchQueriesInclude = "active",
  ): Map<string, ObservableQuery<any>> {
    return this.queryManager.getObservableQueries(include);
  }


/**
   * Exposes the cache's complete state, in a serializable format for later restoration.
   */
public extract(optimistic?: boolean): TCacheShape {
    return this.cache.extract(optimistic);
  }


/**
   * Replaces existing state in the cache (if any) with the values expressed by
   * `serializedState`.
   *
   * Called when hydrating a cache (server side rendering, or offline storage),
   * and also (potentially) during hot reloads.
   */
public restore(serializedState: TCacheShape): ApolloCache<TCacheShape> {
    return this.cache.restore(serializedState);
  }


/**
   * Add additional local resolvers.
   */
public addResolvers(resolvers: Resolvers | Resolvers[]) {
    this.localState.addResolvers(resolvers);
  }


/**
   * Set (override existing) local resolvers.
   */
public setResolvers(resolvers: Resolvers | Resolvers[]) {
    this.localState.setResolvers(resolvers);
  }


/**
   * Get all registered local resolvers.
   */
public getResolvers() {
    return this.localState.getResolvers();
  }


/**
   * Set a custom local state fragment matcher.
   */
public setLocalStateFragmentMatcher(fragmentMatcher: FragmentMatcher) {
    this.localState.setFragmentMatcher(fragmentMatcher);
  }


/**
   * Define a new ApolloLink (or link chain) that Apollo Client will use.
   */
public setLink(newLink: ApolloLink) {
    this.link = this.queryManager.link = newLink;
  }


@Module({
  controllers: [CoinsController],
  providers: [CoinsService]
})
export class CoinsModule {}


export default class extends MultiArgument {
	public get base() {
		return this.store.get('username')!;
	}
}


() => {
    this.props.onAnchorClick('https://azure.microsoft.com/en-us/services/bot-service');
  }


() => {
    this.props.onAnchorClick('https://aka.ms/about-bot-file');
  }


export class AzureLoginPromptDialog extends Component<AzureLoginPromptDialogProps, {}> {
  public render() {
    return (
      <Dialog cancel={ this.props.cancel } title="Sign in with an Azure account" className={styles.dialogMedium}>

{ 'Use your Azure account to sign in to all your Azure services, ' +
        'such as Azure Bot Service, Dispatch, LUIS, and QnA Maker.' }

            Don't have an Azure Account? Sign up.

{ 'By signing in to your services, you can register any app in that ' +
        'service with your bot without having to enter in credentials manually.' }

            Learn more about registering services

        <DialogFooter>
          <DefaultButton text="Cancel" onClick={ this.props.cancel }/>
          <PrimaryButton text="Sign in with Azure" onClick={ this.props.confirm }/>
        </DialogFooter>
      </Dialog>
    );
  }

  private onLearnMoreAzureAccount = () => {
    this.props.onAnchorClick('https://azure.microsoft.com/en-us/services/bot-service');
  }

  private onLearnMoreRegister = () => {
    this.props.onAnchorClick('https://aka.ms/about-bot-file');
  }
}


export interface AzureLoginPromptDialogProps {
  cancel: () => void;
  confirm: () => void;
  onAnchorClick: (url: string) => void;
}


public render() {
    return (
      <Dialog cancel={ this.props.cancel } title="Sign in with an Azure account" className={styles.dialogMedium}>

{ 'Use your Azure account to sign in to all your Azure services, ' +
        'such as Azure Bot Service, Dispatch, LUIS, and QnA Maker.' }

            Don't have an Azure Account? Sign up.

{ 'By signing in to your services, you can register any app in that ' +
        'service with your bot without having to enter in credentials manually.' }

            Learn more about registering services

        <DialogFooter>
          <DefaultButton text="Cancel" onClick={ this.props.cancel }/>
          <PrimaryButton text="Sign in with Azure" onClick={ this.props.confirm }/>
        </DialogFooter>
      </Dialog>
    );
  }


export default interface DetailCallbacks {
  handleEdit(): void
  handleRemove(): void
  handleSave(): void
  handleCancel(): void
  titleDetail: string
}


@Module({
  imports: [MulterModule.register({
    dest: './uploads',
  }),
  TypeOrmModule.forRoot(typeOrmConfig),
    UsersModule,
    UserNotesModule,
    PresentationsModule,
    AuthModule,
  ],
  controllers: [AppController, PresentationsController, UsersController, UserNotesController, AuthController],
  providers: [AppService, UsersService, AuthService, UserRepository],
})
export class AppModule { }


export class LogChannel {
    static channel = '#Log';     // Used later for distributed logs
    static logLevel = 'LogLevel';
}


export class LogLevelObject {
    private _logLevel = LogLevel.Warn;

    build (logLevel: LogLevel) {
        this._logLevel = logLevel;
        return this;
    }

    get logLevel () {
        return this._logLevel;
    }

    set logLevel (level: LogLevel) {
        this._logLevel = level;
    }
}


export class LogObject {
    private _logLevel: LogLevel;
    private _suppress: boolean;
    private _channel: string;
    private _object: any;
    private _caller: string;

    build (logLevel: LogLevel, channel: string, object: any, caller: string, suppress = false) {
        this._logLevel = logLevel;
        this._channel = channel;
        this._object = object;
        this._caller = caller;
        this._suppress = suppress;

        return this;
    }

    get logLevel () {
        return this._logLevel;
    }

    set logLevel (level: LogLevel) {
        this._logLevel = level;
    }

    get channel () {
        return this._channel;
    }

    set channel (chan: string) {
        this._channel = chan;
    }

    get object () {
        return this._object;
    }

    set object (object: any) {
        if (object.constructor !== String) {    // stringify if not string object
            object = LogUtil.pretty(object);
        }
        this._object = object;
    }

    get caller () {
        return this._caller;
    }

    set caller (source: any) {
        this._caller = source;
    }

    get suppress () {
        return this._suppress;
    }

    set suppress (suppress: any) {
        this._suppress = suppress;
    }
}


export enum LogLevel {
    Verbose,
    Debug,
    Info,
    Warn,
    Error,
    Off,
}


build (logLevel: LogLevel) {
        this._logLevel = logLevel;
        return this;
    }


build (logLevel: LogLevel, channel: string, object: any, caller: string, suppress = false) {
        this._logLevel = logLevel;
        this._channel = channel;
        this._object = object;
        this._caller = caller;
        this._suppress = suppress;

        return this;
    }


export class GAWrapperArray
		extends WrapperArray
	{
		protected instanceArray: InstanceArray;

		protected result: std.HashMap<string, WrapperGroup>;

		private price: number;

		/**
		 * @brief Validity of this sequence list.
		 */
		private valid: boolean;

		/* -----------------------------------------------------------
			CONSTRUCTORS
		----------------------------------------------------------- */
		/**
		 * Construct from instances.
		 *
		 * @param instanceArray Instances to be wrapped.
		 */
		public constructor(instanceArray: InstanceArray);

		/**
		 * @brief Copy Constructor.
		 */
		public constructor(genes: GAWrapperArray);

		public constructor(obj: InstanceArray | GAWrapperArray)
		{
			super();

			this.result = new std.HashMap<string, WrapperGroup>();
			this.price = 0.0;

			if (obj instanceof InstanceArray)
			{
				this.instanceArray = <InstanceArray>obj;
			}
			else
			{
				let genes: GAWrapperArray = <GAWrapperArray>obj;

				this.instanceArray = genes.instanceArray;
				this.assign(genes.begin(), genes.end());
			}
		}

		private constructResult(): void
		{
			if (this.result.empty() == false)
				return; // IF RESULT IS ALREADY DEDUCTED

			// INSTANCE AND WRAPPER IS CORRESPOND, 1:1 RELATIONSHIP.
			for (let i: number = 0; i < this.size(); i++)
			{
				let wrapper: Wrapper = this.at(i);
				if (this.result.has(wrapper.getName()) == false)
				{
					let wrapperGroup: WrapperGroup = new WrapperGroup(wrapper);
					this.result.set(wrapper.getName(), wrapperGroup);
				}

				let wrapperGroup: WrapperGroup = this.result.get(wrapper.getName());
				let instance: Instance = this.instanceArray.at(i);

				if (wrapperGroup.allocate(instance) == false)
				{
					// THE INSTANCE IS GREATER THAN THE WRAPPER
					// THIS GENE IS NOT VALID SO THAT CANNOT PARTICIPATE IN THE OPTIMIZATION PROCESS
					this.valid = false;
					return;
				}
			}

			// THE GENE IS VALID, THEN CALCULATE THE COST
			this.price = 0.0;
			this.valid = true;

			for (let it = this.result.begin(); !it.equals(this.result.end()); it = it.next())
			{
				it.second.optimize();
				this.price += it.second.getPrice();
			}
		}

		/* -----------------------------------------------------------
			GETTERS
		----------------------------------------------------------- */
		/**
		 * @brief Get optimization result.
		 *
		 * @return result map.
		 */
		public getResult(): std.HashMap<string, WrapperGroup>
		{
			this.constructResult();

			return this.result;
		}

		public less(obj: GAWrapperArray): boolean
		{
			this.constructResult();
			obj.constructResult();

			if (this.valid == true && obj.valid == true)
				return this.price < obj.price;
			else if (this.valid == true && obj.valid == false)
				return true;
			else
				return false;
		}
	}


private constructResult(): void
		{
			if (this.result.empty() == false)
				return; // IF RESULT IS ALREADY DEDUCTED

			// INSTANCE AND WRAPPER IS CORRESPOND, 1:1 RELATIONSHIP.
			for (let i: number = 0; i < this.size(); i++)
			{
				let wrapper: Wrapper = this.at(i);
				if (this.result.has(wrapper.getName()) == false)
				{
					let wrapperGroup: WrapperGroup = new WrapperGroup(wrapper);
					this.result.set(wrapper.getName(), wrapperGroup);
				}

				let wrapperGroup: WrapperGroup = this.result.get(wrapper.getName());
				let instance: Instance = this.instanceArray.at(i);

				if (wrapperGroup.allocate(instance) == false)
				{
					// THE INSTANCE IS GREATER THAN THE WRAPPER
					// THIS GENE IS NOT VALID SO THAT CANNOT PARTICIPATE IN THE OPTIMIZATION PROCESS
					this.valid = false;
					return;
				}
			}

			// THE GENE IS VALID, THEN CALCULATE THE COST
			this.price = 0.0;
			this.valid = true;

			for (let it = this.result.begin(); !it.equals(this.result.end()); it = it.next())
			{
				it.second.optimize();
				this.price += it.second.getPrice();
			}
		}


/* -----------------------------------------------------------
			GETTERS
		----------------------------------------------------------- */
/**
		 * @brief Get optimization result.
		 *
		 * @return result map.
		 */
public getResult(): std.HashMap<string, WrapperGroup>
		{
			this.constructResult();

			return this.result;
		}


public less(obj: GAWrapperArray): boolean
		{
			this.constructResult();
			obj.constructResult();

			if (this.valid == true && obj.valid == true)
				return this.price < obj.price;
			else if (this.valid == true && obj.valid == false)
				return true;
			else
				return false;
		}


export class ChannelUnit extends Component<PropsType, StateType> {

    constructor(props: PropsType) {
        super(props);
        this.state = {
            user: null
        };
    }

    async componentDidMount() {
        var user = await getUserDto(this.props.dto.channel.userID)
        this.setState({
            user: user
        })
    }

    async onClick() {
        if (this.props.clickAm) {
            var identityObj = getIdentity();
            if (identityObj == null) {
                return
            }
            var ret = await sendChannelMember(identityObj, this.props.dto.channel.channelID, this.props.userAm ?? "");
            if (!ret.success) {
                alert(ret.msg)
            } else {
                alert('succeed add user to list')
            }
        }
        else {
            var url = `/listdetail/${this.props.dto.channel.channelID}`
            goURL(url, this.props.refreshMainCourse)
        }

    }

    render() {

        if (this.state.user == null) {
            return
loading {this.props.dto.channel.channelID}

        }

        var channelDto = this.props.dto;
        var channel = channelDto.channel;
        var userDto = this.state.user
        var userInfo = userDto.userInfo;

        return

                <div style={{ "width": "100%", "display": "inline-block" }}


type PropsType = {
    dto: ChannelDto
    refreshMainCourse: any
    clickAm?: boolean
    userAm?: string
}


type StateType = {
    user: UserDto | null
}


async componentDidMount() {
        var user = await getUserDto(this.props.dto.channel.userID)
        this.setState({
            user: user
        })
    }


async onClick() {
        if (this.props.clickAm) {
            var identityObj = getIdentity();
            if (identityObj == null) {
                return
            }
            var ret = await sendChannelMember(identityObj, this.props.dto.channel.channelID, this.props.userAm ?? "");
            if (!ret.success) {
                alert(ret.msg)
            } else {
                alert('succeed add user to list')
            }
        }
        else {
            var url = `/listdetail/${this.props.dto.channel.channelID}`
            goURL(url, this.props.refreshMainCourse)
        }

    }


render() {

        if (this.state.user == null) {
            return
loading {this.props.dto.channel.channelID}

        }

        var channelDto = this.props.dto;
        var channel = channelDto.channel;
        var userDto = this.state.user
        var userInfo = userDto.userInfo;

        return

                <div style={{ "width": "100%", "display": "inline-block" }}


getUserImgUrl(userDto)


function defaultErrorHandler(error: any): any {
  throw error;
}


function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
  let s = snapshot.parent;
  while (s) {
    const c: any = s._routeConfig;
    if (c && c._loadedConfig) return c._loadedConfig;
    if (c && c.component) return null;
    s = s.parent;
  }
  return null;
}


function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
  if (!snapshot) return null;

  let s = snapshot.parent;
  while (s) {
    const c: any = s._routeConfig;
    if (c && c._loadedConfig) return c._loadedConfig;
    s = s.parent;
  }
  return null;
}


function nodeChildrenAsMap(node: TreeNode<any>) {
  return node ? node.children.reduce((m: any, c: TreeNode<any>) => {
    m[c.value.outlet] = c;
    return m;
  }, {}) : {};
}


function getOutlet(outletMap: RouterOutletMap, route: ActivatedRoute): RouterOutlet {
  let outlet = outletMap._outlets[route.outlet];
  if (!outlet) {
    const componentName = (<any>route.component).name;
    if (route.outlet === PRIMARY_OUTLET) {
      throw new Error(`Cannot find primary outlet to load '${componentName}'`);
    } else {
      throw new Error(`Cannot find the outlet ${route.outlet} to load '${componentName}'`);
    }
  }
  return outlet;
}


(change: any) => {
      const tree = this.urlSerializer.parse(change['url']);
      // we fire multiple events for a single URL change
      // we should navigate only once
      return this.currentUrlTree.toString() !== tree.toString() ?
          this.scheduleNavigation(tree, {skipLocationChange: change['pop'], replaceUrl: true}) :
          null;
    }


(_) => this.runNavigate(url, extras.skipLocationChange, extras.replaceUrl, id)


(resolvePromise, rejectPromise) => {
      let state: RouterState;
      let navigationIsSuccessful: boolean;
      let preActivation: PreActivation;

      let appliedUrl: UrlTree;

      const storedState = this.currentRouterState;
      const storedUrl = this.currentUrlTree;

      const redirectsApplied$ = applyRedirects(this.injector, this.configLoader, url, this.config);

      const snapshot$ = mergeMap.call(redirectsApplied$, (u: UrlTree) => {
        appliedUrl = u;
        return recognize(
            this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
      });

      const emitRecognzied$ = map.call(snapshot$, (newRouterStateSnapshot: RouterStateSnapshot) => {
        this.routerEvents.next(new RoutesRecognized(
            id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
        return newRouterStateSnapshot;
      });

      const routerState$ = map.call(emitRecognzied$, (routerStateSnapshot: RouterStateSnapshot) => {
        return createRouterState(routerStateSnapshot, this.currentRouterState);
      });

      const preactivation$ = map.call(routerState$, (newState: RouterState) => {
        state = newState;
        preActivation =
            new PreActivation(state.snapshot, this.currentRouterState.snapshot, this.injector);
        preActivation.traverse(this.outletMap);
      });

      const preactivation2$ =
          mergeMap.call(preactivation$, () => { return preActivation.checkGuards(); });

      const resolveData$ = mergeMap.call(preactivation2$, (shouldActivate: boolean) => {
        if (shouldActivate) {
          return map.call(preActivation.resolveData(), () => shouldActivate);
        } else {
          return of (shouldActivate);
        }
      });

      resolveData$
          .forEach((shouldActivate: boolean) => {
            if (!shouldActivate || id !== this.navigationId) {
              navigationIsSuccessful = false;
              return;
            }

            this.currentUrlTree = appliedUrl;
            this.currentRouterState = state;

            if (!shouldPreventPushState) {
              let path = this.urlSerializer.serialize(appliedUrl);
              if (this.location.isCurrentPathEqualTo(path) || shouldReplaceUrl) {
                this.location.replaceState(path);
              } else {
                this.location.go(path);
              }
            }

            new ActivateRoutes(state, storedState).activate(this.outletMap);

            navigationIsSuccessful = true;
          })
          .then(
              () => {
                this.navigated = true;
                if (navigationIsSuccessful) {
                  this.routerEvents.next(
                      new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl)));
                  resolvePromise(true);
                } else {
                  this.routerEvents.next(new NavigationCancel(id, this.serializeUrl(url), ''));
                  resolvePromise(false);
                }
              },
              (e: any) => {
                if (e instanceof NavigationCancelingError) {
                  this.navigated = true;
                  this.routerEvents.next(
                      new NavigationCancel(id, this.serializeUrl(url), e.message));
                  resolvePromise(false);
                } else {
                  this.routerEvents.next(new NavigationError(id, this.serializeUrl(url), e));
                  try {
                    resolvePromise(this.errorHandler(e));
                  } catch (ee) {
                    rejectPromise(ee);
                  }
                }

                if (id === this.navigationId) {
                  this.currentRouterState = storedState;
                  this.currentUrlTree = storedUrl;
                  this.location.replaceState(this.serializeUrl(storedUrl));
                }
              });
    }


(u: UrlTree) => {
        appliedUrl = u;
        return recognize(
            this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
      }


(newRouterStateSnapshot: RouterStateSnapshot) => {
        this.routerEvents.next(new RoutesRecognized(
            id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
        return newRouterStateSnapshot;
      }


(routerStateSnapshot: RouterStateSnapshot) => {
        return createRouterState(routerStateSnapshot, this.currentRouterState);
      }


(newState: RouterState) => {
        state = newState;
        preActivation =
            new PreActivation(state.snapshot, this.currentRouterState.snapshot, this.injector);
        preActivation.traverse(this.outletMap);
      }


() => { return preActivation.checkGuards(); }


(shouldActivate: boolean) => {
        if (shouldActivate) {
          return map.call(preActivation.resolveData(), () => shouldActivate);
        } else {
          return of (shouldActivate);
        }
      }


() => shouldActivate


(shouldActivate: boolean) => {
            if (!shouldActivate || id !== this.navigationId) {
              navigationIsSuccessful = false;
              return;
            }

            this.currentUrlTree = appliedUrl;
            this.currentRouterState = state;

            if (!shouldPreventPushState) {
              let path = this.urlSerializer.serialize(appliedUrl);
              if (this.location.isCurrentPathEqualTo(path) || shouldReplaceUrl) {
                this.location.replaceState(path);
              } else {
                this.location.go(path);
              }
            }

            new ActivateRoutes(state, storedState).activate(this.outletMap);

            navigationIsSuccessful = true;
          }


() => {
                this.navigated = true;
                if (navigationIsSuccessful) {
                  this.routerEvents.next(
                      new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl)));
                  resolvePromise(true);
                } else {
                  this.routerEvents.next(new NavigationCancel(id, this.serializeUrl(url), ''));
                  resolvePromise(false);
                }
              }


(e: any) => {
                if (e instanceof NavigationCancelingError) {
                  this.navigated = true;
                  this.routerEvents.next(
                      new NavigationCancel(id, this.serializeUrl(url), e.message));
                  resolvePromise(false);
                } else {
                  this.routerEvents.next(new NavigationError(id, this.serializeUrl(url), e));
                  try {
                    resolvePromise(this.errorHandler(e));
                  } catch (ee) {
                    rejectPromise(ee);
                  }
                }

                if (id === this.navigationId) {
                  this.currentRouterState = storedState;
                  this.currentUrlTree = storedUrl;
                  this.location.replaceState(this.serializeUrl(storedUrl));
                }
              }


(s: any) => {
      if (s instanceof CanActivate) {
        return andObservables(
            from([this.runCanActivateChild(s.path), this.runCanActivate(s.route)]));
      } else if (s instanceof CanDeactivate) {
        // workaround https://github.com/Microsoft/TypeScript/issues/7271
        const s2 = s as CanDeactivate;
        return this.runCanDeactivate(s2.component, s2.route);
      } else {
        throw new Error('Cannot be reached');
      }
    }


(result: any) => result === true


(s: any) => {
      if (s instanceof CanActivate) {
        return this.runResolve(s.route);
      } else {
        return of (null);
      }
    }


(_: any, __: any) => _


c => {
      this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap, futurePath.concat([c.value]));
      delete prevChildren[c.value.outlet];
    }


(v: any, k: string) => this.deactivateOutletAndItChildren(v, outletMap._outlets[k])


(v: RouterOutlet) => {
      if (v.isActivated) {
        this.deactivateOutletAndItChildren(v.activatedRoute.snapshot, v);
      }
    }


(c: any) => {
      const guard = this.getToken(c, future);
      if (guard.canActivate) {
        return wrapIntoObservable(guard.canActivate(future, this.future));
      } else {
        return wrapIntoObservable(guard(future, this.future));
      }
    }


p => this.extractCanActivateChild(p)


_ => _ !== null


(d: any) => {
      const obs = map.call(from(d.guards), (c: any) => {
        const guard = this.getToken(c, c.node);
        if (guard.canActivateChild) {
          return wrapIntoObservable(guard.canActivateChild(future, this.future));
        } else {
          return wrapIntoObservable(guard(future, this.future));
        }
      });
      return andObservables(obs);
    }


(c: any) => {
        const guard = this.getToken(c, c.node);
        if (guard.canActivateChild) {
          return wrapIntoObservable(guard.canActivateChild(future, this.future));
        } else {
          return wrapIntoObservable(guard(future, this.future));
        }
      }


(c: any) => {
      const guard = this.getToken(c, curr);
      if (guard.canDeactivate) {
        return wrapIntoObservable(guard.canDeactivate(component, curr, this.curr));
      } else {
        return wrapIntoObservable(guard(component, curr, this.curr));
      }
    }


(resolvedData: any): any => {
      resolve.resolvedData = resolvedData;
      future.data = merge(future.data, resolve.flattenedResolvedData);
      return null;
    }


(k, v) => {
      const resolver = this.getToken(v, future);
      return resolver.resolve ? wrapIntoObservable(resolver.resolve(future, this.future)) :
                                wrapIntoObservable(resolver(future, this.future));
    }


c => {
      this.activateRoutes(c, prevChildren[c.value.outlet], outletMap);
      delete prevChildren[c.value.outlet];
    }


(v: any, k: string) => this.deactivateOutletAndItChildren(outletMap._outlets[k])


(v: RouterOutlet) => this.deactivateOutletAndItChildren(v)


(m: any, c: TreeNode<any>) => {
    m[c.value.outlet] = c;
    return m;
  }


/**
 * An event triggered when a navigation starts
 *
 * @stable
 */
export class NavigationStart {
  constructor(public id: number, public url: string) {}

  toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
}


/**
 * An event triggered when a navigation ends successfully
 *
 * @stable
 */
export class NavigationEnd {
  constructor(public id: number, public url: string, public urlAfterRedirects: string) {}

  toString(): string {
    return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
  }
}


/**
 * An event triggered when a navigation is canceled
 *
 * @stable
 */
export class NavigationCancel {
  constructor(public id: number, public url: string, public reason: string) {}

  toString(): string { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
}


/**
 * An event triggered when a navigation fails due to unexpected error
 *
 * @stable
 */
export class NavigationError {
  constructor(public id: number, public url: string, public error: any) {}

  toString(): string {
    return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
  }
}


/**
 * An event triggered when routes are recognized
 *
 * @stable
 */
export class RoutesRecognized {
  constructor(
      public id: number, public url: string, public urlAfterRedirects: string,
      public state: RouterStateSnapshot) {}

  toString(): string {
    return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }
}


class CanActivate {
  constructor(public path: ActivatedRouteSnapshot[]) {}
  get route(): ActivatedRouteSnapshot { return this.path[this.path.length - 1]; }
}


class CanDeactivate {
  constructor(public component: Object, public route: ActivatedRouteSnapshot) {}
}


class ActivateRoutes {
  constructor(private futureState: RouterState, private currState: RouterState) {}

  activate(parentOutletMap: RouterOutletMap): void {
    const futureRoot = this.futureState._root;
    const currRoot = this.currState ? this.currState._root : null;
    advanceActivatedRoute(this.futureState.root);
    this.activateChildRoutes(futureRoot, currRoot, parentOutletMap);
  }

  private activateChildRoutes(
      futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
      outletMap: RouterOutletMap): void {
    const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);
    futureNode.children.forEach(c => {
      this.activateRoutes(c, prevChildren[c.value.outlet], outletMap);
      delete prevChildren[c.value.outlet];
    });
    forEach(
        prevChildren,
        (v: any, k: string) => this.deactivateOutletAndItChildren(outletMap._outlets[k]));
  }

  activateRoutes(
      futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
      parentOutletMap: RouterOutletMap): void {
    const future = futureNode.value;
    const curr = currNode ? currNode.value : null;

    // reusing the node
    if (future === curr) {
      // advance the route to push the parameters
      advanceActivatedRoute(future);

      // If we have a normal route, we need to go through an outlet.
      if (future.component) {
        const outlet = getOutlet(parentOutletMap, futureNode.value);
        this.activateChildRoutes(futureNode, currNode, outlet.outletMap);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        this.activateChildRoutes(futureNode, currNode, parentOutletMap);
      }
    } else {
      if (curr) {
        // if we had a normal route, we need to deactivate only that outlet.
        if (curr.component) {
          const outlet = getOutlet(parentOutletMap, futureNode.value);
          this.deactivateOutletAndItChildren(outlet);

          // if we had a componentless route, we need to deactivate everything!
        } else {
          this.deactivateOutletMap(parentOutletMap);
        }
      }

      // if we have a normal route, we need to advance the route
      // and place the component into the outlet. After that recurse.
      if (future.component) {
        advanceActivatedRoute(future);
        const outlet = getOutlet(parentOutletMap, futureNode.value);
        const outletMap = new RouterOutletMap();
        this.placeComponentIntoOutlet(outletMap, future, outlet);
        this.activateChildRoutes(futureNode, null, outletMap);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        advanceActivatedRoute(future);
        this.activateChildRoutes(futureNode, null, parentOutletMap);
      }
    }
  }

  private placeComponentIntoOutlet(
      outletMap: RouterOutletMap, future: ActivatedRoute, outlet: RouterOutlet): void {
    const resolved = <any[]>[{provide: ActivatedRoute, useValue: future}, {
      provide: RouterOutletMap,
      useValue: outletMap
    }];

    const config = parentLoadedConfig(future.snapshot);

    let loadedFactoryResolver: ComponentFactoryResolver = null;
    let loadedInjector: Injector = null;

    if (config) {
      loadedFactoryResolver = config.factoryResolver;
      loadedInjector = config.injector;
      resolved.push({provide: ComponentFactoryResolver, useValue: loadedFactoryResolver});
    }
    outlet.activate(
        future, loadedFactoryResolver, loadedInjector, ReflectiveInjector.resolve(resolved),
        outletMap);
  }

  private deactivateOutletAndItChildren(outlet: RouterOutlet): void {
    if (outlet && outlet.isActivated) {
      this.deactivateOutletMap(outlet.outletMap);
      outlet.deactivate();
    }
  }

  private deactivateOutletMap(outletMap: RouterOutletMap): void {
    forEach(outletMap._outlets, (v: RouterOutlet) => this.deactivateOutletAndItChildren(v));
  }
}


/**
 * @stable
 */
export interface NavigationExtras {
  /**
  * Enables relative navigation from the current ActivatedRoute
  *
  * Configuration
  *
  * ```
  * [{
  *   path: 'parent',
  *   component: ParentComponent,
  *   children: [
  *     {
  *       path: 'list',
  *       component: ListComponent
  *     },
  *     {
  *       path: 'child',
  *       component: ChildComponent
  *     }
  *   ]
  * }]
  * ```
  *
  * Navigate to list route from child route
  *
  * ```
  *  @Component({...})
  *  class ChildComponent {
  *    constructor(private router: Router, private route: ActivatedRoute) {}
  *
  *    go() {
  *      this.router.navigate('../list', { relativeTo: this.route });
  *    }
  *  }
  * ```
  */
  relativeTo?: ActivatedRoute;
  /**
  * Sets query parameters to the URL
  *
  * ```
  * // Navigate to /results?page=1
  * this.router.navigate('/results', { queryParams: { page: 1 } });
  * ```
  */
  queryParams?: Params;
  /**
  * Sets the hash fragment for the URL
  *
  * ```
  * // Navigate to /results#top
  * this.router.navigate('/results', { fragment: 'top' });
  * ```
  */
  fragment?: string;
  /**
  * Preserves the query parameters for the next navigation
  *
  * ```
  * // Preserve query params from /results?page=1 to /view?page=1
  * this.router.navigate('/view', { preserveQueryParams: true });
  * ```
  */
  preserveQueryParams?: boolean;
  /**
  * Preserves the fragment for the next navigation
  *
  * ```
  * // Preserve fragment from /results#top to /view#top
  * this.router.navigate('/view', { preserveFragment: true });
  * ```
  */
  preserveFragment?: boolean;
  /**
  * Navigates without pushing a new state into history
  *
  * ```
  * // Navigate silently to /view
  * this.router.navigate('/view', { skipLocationChange: true });
  * ```
  */
  skipLocationChange?: boolean;
  /**
  * Navigates while replacing the current state in history
  *
  * ```
  * // Navigate to /view
  * this.router.navigate('/view', { replaceUrl: true });
  * ```
  */
  replaceUrl?: boolean;
}


/**
 * @stable
 */
export type Event =
    NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized;


/**
 * Error handler that is invoked when a navigation errors.
 *
 * If the handler retuns a value, the navigation promise will be resolved with this value.
 * If the handler throws an exception, the navigation promise will be rejected with
 * the exception.
 *
 * @stable
 */
export type ErrorHandler = (error: any) => any;


toString(): string { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }


toString(): string {
    return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
  }


toString(): string { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }


toString(): string {
    return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
  }


toString(): string {
    return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }


/**
   * Sets up the location change listener and performs the inital navigation
   */
initialNavigation(): void {
    this.setUpLocationChangeListener();
    this.navigateByUrl(this.location.path(true), {replaceUrl: true});
  }


/**
   * Sets up the location change listener
   */
setUpLocationChangeListener(): void {
    // Zone.current.wrap is needed because of the issue with RxJS scheduler,
    // which does not work properly with zone.js in IE and Safari
    this.locationSubscription = <any>this.location.subscribe(Zone.current.wrap((change: any) => {
      const tree = this.urlSerializer.parse(change['url']);
      // we fire multiple events for a single URL change
      // we should navigate only once
      return this.currentUrlTree.toString() !== tree.toString() ?
          this.scheduleNavigation(tree, {skipLocationChange: change['pop'], replaceUrl: true}) :
          null;
    }));
  }


/**
   * Resets the configuration used for navigation and generating links.
   *
   * ### Usage
   *
   * ```
   * router.resetConfig([
   *  { path: 'team/:id', component: TeamCmp, children: [
   *    { path: 'simple', component: SimpleCmp },
   *    { path: 'user/:name', component: UserCmp }
   *  ] }
   * ]);
   * ```
   */
resetConfig(config: Routes): void {
    validateConfig(config);
    this.config = config;
  }


ngOnDestroy() { this.dispose(); }


/**
   * Disposes of the router.
   */
dispose(): void { this.locationSubscription.unsubscribe(); }


/**
   * Applies an array of commands to the current url tree and creates
   * a new url tree.
   *
   * When given an activate route, applies the given commands starting from the route.
   * When not given a route, applies the given command starting from the root.
   *
   * ### Usage
   *
   * ```
   * // create /team/33/user/11
   * router.createUrlTree(['/team', 33, 'user', 11]);
   *
   * // create /team/33;expand=true/user/11
   * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
   *
   * // you can collapse static segments like this (this works only with the first passed-in value):
   * router.createUrlTree(['/team/33/user', userId]);
   *
   * // If the first segment can contain slashes, and you do not want the router to split it, you
   * // can do the following:
   *
   * router.createUrlTree([{segmentPath: '/one/two'}]);
   *
   * // create /team/33/(user/11//right:chat)
   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
   *
   * // remove the right secondary node
   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
   *
   * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
   *
   * // navigate to /team/33/user/11/details
   * router.createUrlTree(['details'], {relativeTo: route});
   *
   * // navigate to /team/33/user/22
   * router.createUrlTree(['../22'], {relativeTo: route});
   *
   * // navigate to /team/44/user/22
   * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
   * ```
   */
createUrlTree(
      commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams,
                        preserveFragment}: NavigationExtras = {}): UrlTree {
    const a = relativeTo ? relativeTo : this.routerState.root;
    const q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams;
    const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
    return createUrlTree(a, this.currentUrlTree, commands, q, f);
  }


/**
   * Navigate based on the provided url. This navigation is always absolute.
   *
   * Returns a promise that:
   * - is resolved with 'true' when navigation succeeds
   * - is resolved with 'false' when navigation fails
   * - is rejected when an error happens
   *
   * ### Usage
   *
   * ```
   * router.navigateByUrl("/team/33/user/11");
   *
   * // Navigate without updating the URL
   * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
   * ```
   *
   * In opposite to `navigate`, `navigateByUrl` takes a whole URL
   * and does not apply any delta to the current one.
   */
navigateByUrl(url: string|UrlTree, extras: NavigationExtras = {skipLocationChange: false}):
      Promise<boolean> {
    if (url instanceof UrlTree) {
      return this.scheduleNavigation(url, extras);
    } else {
      const urlTree = this.urlSerializer.parse(url);
      return this.scheduleNavigation(urlTree, extras);
    }
  }


/**
   * Navigate based on the provided array of commands and a starting point.
   * If no starting route is provided, the navigation is absolute.
   *
   * Returns a promise that:
   * - is resolved with 'true' when navigation succeeds
   * - is resolved with 'false' when navigation fails
   * - is rejected when an error happens
   *
   * ### Usage
   *
   * ```
   * router.navigate(['team', 33, 'team', '11], {relativeTo: route});
   *
   * // Navigate without updating the URL
   * router.navigate(['team', 33, 'team', '11], {relativeTo: route, skipLocationChange: true });
   * ```
   *
   * In opposite to `navigateByUrl`, `navigate` always takes a delta
   * that is applied to the current URL.
   */
navigate(commands: any[], extras: NavigationExtras = {skipLocationChange: false}):
      Promise<boolean> {
    return this.scheduleNavigation(this.createUrlTree(commands, extras), extras);
  }


/**
   * Serializes a {@link UrlTree} into a string.
   */
serializeUrl(url: UrlTree): string { return this.urlSerializer.serialize(url); }


/**
   * Parse a string into a {@link UrlTree}.
   */
parseUrl(url: string): UrlTree { return this.urlSerializer.parse(url); }


/**
   * Returns if the url is activated or not.
   */
isActive(url: string|UrlTree, exact: boolean): boolean {
    if (url instanceof UrlTree) {
      return containsTree(this.currentUrlTree, url, exact);
    } else {
      const urlTree = this.urlSerializer.parse(url);
      return containsTree(this.currentUrlTree, urlTree, exact);
    }
  }


private scheduleNavigation(url: UrlTree, extras: NavigationExtras): Promise<boolean> {
    const id = ++this.navigationId;
    this.routerEvents.next(new NavigationStart(id, this.serializeUrl(url)));
    return Promise.resolve().then(
        (_) => this.runNavigate(url, extras.skipLocationChange, extras.replaceUrl, id));
  }


private runNavigate(
      url: UrlTree, shouldPreventPushState: boolean, shouldReplaceUrl: boolean,
      id: number): Promise<boolean> {
    if (id !== this.navigationId) {
      this.location.go(this.urlSerializer.serialize(this.currentUrlTree));
      this.routerEvents.next(new NavigationCancel(
          id, this.serializeUrl(url),
          `Navigation ID ${id} is not equal to the current navigation id ${this.navigationId}`));
      return Promise.resolve(false);
    }

    return new Promise((resolvePromise, rejectPromise) => {
      let state: RouterState;
      let navigationIsSuccessful: boolean;
      let preActivation: PreActivation;

      let appliedUrl: UrlTree;

      const storedState = this.currentRouterState;
      const storedUrl = this.currentUrlTree;

      const redirectsApplied$ = applyRedirects(this.injector, this.configLoader, url, this.config);

      const snapshot$ = mergeMap.call(redirectsApplied$, (u: UrlTree) => {
        appliedUrl = u;
        return recognize(
            this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
      });

      const emitRecognzied$ = map.call(snapshot$, (newRouterStateSnapshot: RouterStateSnapshot) => {
        this.routerEvents.next(new RoutesRecognized(
            id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
        return newRouterStateSnapshot;
      });

      const routerState$ = map.call(emitRecognzied$, (routerStateSnapshot: RouterStateSnapshot) => {
        return createRouterState(routerStateSnapshot, this.currentRouterState);
      });

      const preactivation$ = map.call(routerState$, (newState: RouterState) => {
        state = newState;
        preActivation =
            new PreActivation(state.snapshot, this.currentRouterState.snapshot, this.injector);
        preActivation.traverse(this.outletMap);
      });

      const preactivation2$ =
          mergeMap.call(preactivation$, () => { return preActivation.checkGuards(); });

      const resolveData$ = mergeMap.call(preactivation2$, (shouldActivate: boolean) => {
        if (shouldActivate) {
          return map.call(preActivation.resolveData(), () => shouldActivate);
        } else {
          return of (shouldActivate);
        }
      });

      resolveData$
          .forEach((shouldActivate: boolean) => {
            if (!shouldActivate || id !== this.navigationId) {
              navigationIsSuccessful = false;
              return;
            }

            this.currentUrlTree = appliedUrl;
            this.currentRouterState = state;

            if (!shouldPreventPushState) {
              let path = this.urlSerializer.serialize(appliedUrl);
              if (this.location.isCurrentPathEqualTo(path) || shouldReplaceUrl) {
                this.location.replaceState(path);
              } else {
                this.location.go(path);
              }
            }

            new ActivateRoutes(state, storedState).activate(this.outletMap);

            navigationIsSuccessful = true;
          })
          .then(
              () => {
                this.navigated = true;
                if (navigationIsSuccessful) {
                  this.routerEvents.next(
                      new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl)));
                  resolvePromise(true);
                } else {
                  this.routerEvents.next(new NavigationCancel(id, this.serializeUrl(url), ''));
                  resolvePromise(false);
                }
              },
              (e: any) => {
                if (e instanceof NavigationCancelingError) {
                  this.navigated = true;
                  this.routerEvents.next(
                      new NavigationCancel(id, this.serializeUrl(url), e.message));
                  resolvePromise(false);
                } else {
                  this.routerEvents.next(new NavigationError(id, this.serializeUrl(url), e));
                  try {
                    resolvePromise(this.errorHandler(e));
                  } catch (ee) {
                    rejectPromise(ee);
                  }
                }

                if (id === this.navigationId) {
                  this.currentRouterState = storedState;
                  this.currentUrlTree = storedUrl;
                  this.location.replaceState(this.serializeUrl(storedUrl));
                }
              });
    });
  }


traverse(parentOutletMap: RouterOutletMap): void {
    const futureRoot = this.future._root;
    const currRoot = this.curr ? this.curr._root : null;
    this.traverseChildRoutes(futureRoot, currRoot, parentOutletMap, [futureRoot.value]);
  }


checkGuards(): Observable<boolean> {
    if (this.checks.length === 0) return of (true);
    const checks$ = from(this.checks);
    const runningChecks$ = map.call(checks$, (s: any) => {
      if (s instanceof CanActivate) {
        return andObservables(
            from([this.runCanActivateChild(s.path), this.runCanActivate(s.route)]));
      } else if (s instanceof CanDeactivate) {
        // workaround https://github.com/Microsoft/TypeScript/issues/7271
        const s2 = s as CanDeactivate;
        return this.runCanDeactivate(s2.component, s2.route);
      } else {
        throw new Error('Cannot be reached');
      }
    });
    const mergedChecks$ = mergeAll.call(runningChecks$);
    return every.call(mergedChecks$, (result: any) => result === true);
  }


resolveData(): Observable<any> {
    if (this.checks.length === 0) return of (null);
    const checks$ = from(this.checks);
    const runningChecks$ = mergeMap.call(checks$, (s: any) => {
      if (s instanceof CanActivate) {
        return this.runResolve(s.route);
      } else {
        return of (null);
      }
    });
    return reduce.call(runningChecks$, (_: any, __: any) => _);
  }


private traverseChildRoutes(
      futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
      outletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
    const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);

    futureNode.children.forEach(c => {
      this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap, futurePath.concat([c.value]));
      delete prevChildren[c.value.outlet];
    });
    forEach(
        prevChildren,
        (v: any, k: string) => this.deactivateOutletAndItChildren(v, outletMap._outlets[k]));
  }


traverseRoutes(
      futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
      parentOutletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
    const future = futureNode.value;
    const curr = currNode ? currNode.value : null;
    const outlet = parentOutletMap ? parentOutletMap._outlets[futureNode.value.outlet] : null;

    // reusing the node
    if (curr && future._routeConfig === curr._routeConfig) {
      if (!shallowEqual(future.params, curr.params)) {
        this.checks.push(new CanDeactivate(outlet.component, curr), new CanActivate(futurePath));
      } else {
        // we need to set the data
        future.data = curr.data;
      }

      // If we have a component, we need to go through an outlet.
      if (future.component) {
        this.traverseChildRoutes(
            futureNode, currNode, outlet ? outlet.outletMap : null, futurePath);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        this.traverseChildRoutes(futureNode, currNode, parentOutletMap, futurePath);
      }
    } else {
      if (curr) {
        // if we had a normal route, we need to deactivate only that outlet.
        if (curr.component) {
          this.deactivateOutletAndItChildren(curr, outlet);

          // if we had a componentless route, we need to deactivate everything!
        } else {
          this.deactivateOutletMap(parentOutletMap);
        }
      }

      this.checks.push(new CanActivate(futurePath));
      // If we have a component, we need to go through an outlet.
      if (future.component) {
        this.traverseChildRoutes(futureNode, null, outlet ? outlet.outletMap : null, futurePath);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        this.traverseChildRoutes(futureNode, null, parentOutletMap, futurePath);
      }
    }
  }


private deactivateOutletAndItChildren(route: ActivatedRouteSnapshot, outlet: RouterOutlet): void {
    if (outlet && outlet.isActivated) {
      this.deactivateOutletMap(outlet.outletMap);
      this.checks.push(new CanDeactivate(outlet.component, route));
    }
  }


private deactivateOutletMap(outletMap: RouterOutletMap): void {
    forEach(outletMap._outlets, (v: RouterOutlet) => {
      if (v.isActivated) {
        this.deactivateOutletAndItChildren(v.activatedRoute.snapshot, v);
      }
    });
  }


private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> {
    const canActivate = future._routeConfig ? future._routeConfig.canActivate : null;
    if (!canActivate || canActivate.length === 0) return of (true);
    const obs = map.call(from(canActivate), (c: any) => {
      const guard = this.getToken(c, future);
      if (guard.canActivate) {
        return wrapIntoObservable(guard.canActivate(future, this.future));
      } else {
        return wrapIntoObservable(guard(future, this.future));
      }
    });
    return andObservables(obs);
  }


private runCanActivateChild(path: ActivatedRouteSnapshot[]): Observable<boolean> {
    const future = path[path.length - 1];

    const canActivateChildGuards = path.slice(0, path.length - 1)
                                       .reverse()
                                       .map(p => this.extractCanActivateChild(p))
                                       .filter(_ => _ !== null);

    return andObservables(map.call(from(canActivateChildGuards), (d: any) => {
      const obs = map.call(from(d.guards), (c: any) => {
        const guard = this.getToken(c, c.node);
        if (guard.canActivateChild) {
          return wrapIntoObservable(guard.canActivateChild(future, this.future));
        } else {
          return wrapIntoObservable(guard(future, this.future));
        }
      });
      return andObservables(obs);
    }));
  }


private extractCanActivateChild(p: ActivatedRouteSnapshot):
      {node: ActivatedRouteSnapshot, guards: any[]} {
    const canActivateChild = p._routeConfig ? p._routeConfig.canActivateChild : null;
    if (!canActivateChild || canActivateChild.length === 0) return null;
    return {node: p, guards: canActivateChild};
  }


private runCanDeactivate(component: Object, curr: ActivatedRouteSnapshot): Observable<boolean> {
    const canDeactivate = curr && curr._routeConfig ? curr._routeConfig.canDeactivate : null;
    if (!canDeactivate || canDeactivate.length === 0) return of (true);
    const canDeactivate$ = map.call(from(canDeactivate), (c: any) => {
      const guard = this.getToken(c, curr);
      if (guard.canDeactivate) {
        return wrapIntoObservable(guard.canDeactivate(component, curr, this.curr));
      } else {
        return wrapIntoObservable(guard(component, curr, this.curr));
      }
    });
    const merged$ = mergeAll.call(canDeactivate$);
    return every.call(merged$, (result: any) => result === true);
  }


private runResolve(future: ActivatedRouteSnapshot): Observable<any> {
    const resolve = future._resolve;
    return map.call(this.resolveNode(resolve.current, future), (resolvedData: any): any => {
      resolve.resolvedData = resolvedData;
      future.data = merge(future.data, resolve.flattenedResolvedData);
      return null;
    });
  }


private resolveNode(resolve: ResolveData, future: ActivatedRouteSnapshot): Observable<any> {
    return waitForMap(resolve, (k, v) => {
      const resolver = this.getToken(v, future);
      return resolver.resolve ? wrapIntoObservable(resolver.resolve(future, this.future)) :
                                wrapIntoObservable(resolver(future, this.future));
    });
  }


private getToken(token: any, snapshot: ActivatedRouteSnapshot): any {
    const config = closestLoadedConfig(snapshot);
    const injector = config ? config.injector : this.injector;
    return injector.get(token);
  }


activate(parentOutletMap: RouterOutletMap): void {
    const futureRoot = this.futureState._root;
    const currRoot = this.currState ? this.currState._root : null;
    advanceActivatedRoute(this.futureState.root);
    this.activateChildRoutes(futureRoot, currRoot, parentOutletMap);
  }


private activateChildRoutes(
      futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
      outletMap: RouterOutletMap): void {
    const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);
    futureNode.children.forEach(c => {
      this.activateRoutes(c, prevChildren[c.value.outlet], outletMap);
      delete prevChildren[c.value.outlet];
    });
    forEach(
        prevChildren,
        (v: any, k: string) => this.deactivateOutletAndItChildren(outletMap._outlets[k]));
  }


activateRoutes(
      futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
      parentOutletMap: RouterOutletMap): void {
    const future = futureNode.value;
    const curr = currNode ? currNode.value : null;

    // reusing the node
    if (future === curr) {
      // advance the route to push the parameters
      advanceActivatedRoute(future);

      // If we have a normal route, we need to go through an outlet.
      if (future.component) {
        const outlet = getOutlet(parentOutletMap, futureNode.value);
        this.activateChildRoutes(futureNode, currNode, outlet.outletMap);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        this.activateChildRoutes(futureNode, currNode, parentOutletMap);
      }
    } else {
      if (curr) {
        // if we had a normal route, we need to deactivate only that outlet.
        if (curr.component) {
          const outlet = getOutlet(parentOutletMap, futureNode.value);
          this.deactivateOutletAndItChildren(outlet);

          // if we had a componentless route, we need to deactivate everything!
        } else {
          this.deactivateOutletMap(parentOutletMap);
        }
      }

      // if we have a normal route, we need to advance the route
      // and place the component into the outlet. After that recurse.
      if (future.component) {
        advanceActivatedRoute(future);
        const outlet = getOutlet(parentOutletMap, futureNode.value);
        const outletMap = new RouterOutletMap();
        this.placeComponentIntoOutlet(outletMap, future, outlet);
        this.activateChildRoutes(futureNode, null, outletMap);

        // if we have a componentless route, we recurse but keep the same outlet map.
      } else {
        advanceActivatedRoute(future);
        this.activateChildRoutes(futureNode, null, parentOutletMap);
      }
    }
  }


private placeComponentIntoOutlet(
      outletMap: RouterOutletMap, future: ActivatedRoute, outlet: RouterOutlet): void {
    const resolved = <any[]>[{provide: ActivatedRoute, useValue: future}, {
      provide: RouterOutletMap,
      useValue: outletMap
    }];

    const config = parentLoadedConfig(future.snapshot);

    let loadedFactoryResolver: ComponentFactoryResolver = null;
    let loadedInjector: Injector = null;

    if (config) {
      loadedFactoryResolver = config.factoryResolver;
      loadedInjector = config.injector;
      resolved.push({provide: ComponentFactoryResolver, useValue: loadedFactoryResolver});
    }
    outlet.activate(
        future, loadedFactoryResolver, loadedInjector, ReflectiveInjector.resolve(resolved),
        outletMap);
  }


private deactivateOutletAndItChildren(outlet: RouterOutlet): void {
    if (outlet && outlet.isActivated) {
      this.deactivateOutletMap(outlet.outletMap);
      outlet.deactivate();
    }
  }


private deactivateOutletMap(outletMap: RouterOutletMap): void {
    forEach(outletMap._outlets, (v: RouterOutlet) => this.deactivateOutletAndItChildren(v));
  }


@Component({
  tag: "koto-input",
  styleUrl: "input.scss",
  shadow: true
})
export class Input {
  @Prop() name!: string;
  @Prop() placeholder: string;

  render() {
    return <input name={this.name} placeholder={this.placeholder} />;
  }
}


render() {
    return <input name={this.name} placeholder={this.placeholder} />;
  }


interface IRegionDocument {
  id: string;
  position: IPositionDocument;
  size: ISizeDocument;
}


interface IOrientationDocument {
  region: IRegionDocument;
}


interface ITemplateDeviceDocument {
  portrait: IOrientationDocument[];
  landscape: IOrientationDocument[];
}


interface ITemplateLayoutDocument {
  communal: ITemplateDeviceDocument;
  personal: ITemplateDeviceDocument;
}


export interface ITemplateDocument {
  deviceType: string;
  layout: ITemplateLayoutDocument;
}


() => {
  it('can be constructed', () => {
    const zuckBucks = new Currency('Zuck Bucks', 'ZB', 2, {
      suffix: 'ZB',
    })
    const formatted = zuckBucks.format('1234')
    expect(formatted).to.equal('12.34ZB')
  })

  it('FiatCurrency', () => {
    const dollar = new FiatCurrency('United States Dollar', 'USD', 2, {
      prefix: '$',
      suffix: ' USD',
    })
    const formatted = dollar.format('1234')
    expect(formatted).to.equal('$12.34 USD')
  })

  it('NativeCurrency', () => {
    const ether = new NativeCurrency('Ether', 'ETH', ChainId.Mainnet)
    const formatted = ether.format('123'.concat('0'.repeat(18)))
    expect(formatted).to.equal('123 ETH')
  })

  it('Token', () => {
    const token = new Token('Fake Dai', 'FDI', ChainId.Mainnet, AddressZero)
    const formatted = token.format('123'.concat('0'.repeat(18)))
    expect(formatted).to.equal('123 FDI')
  })
}


() => {
    const zuckBucks = new Currency('Zuck Bucks', 'ZB', 2, {
      suffix: 'ZB',
    })
    const formatted = zuckBucks.format('1234')
    expect(formatted).to.equal('12.34ZB')
  }


() => {
    const dollar = new FiatCurrency('United States Dollar', 'USD', 2, {
      prefix: '$',
      suffix: ' USD',
    })
    const formatted = dollar.format('1234')
    expect(formatted).to.equal('$12.34 USD')
  }


() => {
    const ether = new NativeCurrency('Ether', 'ETH', ChainId.Mainnet)
    const formatted = ether.format('123'.concat('0'.repeat(18)))
    expect(formatted).to.equal('123 ETH')
  }


() => {
    const token = new Token('Fake Dai', 'FDI', ChainId.Mainnet, AddressZero)
    const formatted = token.format('123'.concat('0'.repeat(18)))
    expect(formatted).to.equal('123 FDI')
  }


export interface ModelUpdatedEvent extends AgGridEvent {
    /** If true, the grid will try and animate the rows to the new positions */
    animate: boolean | undefined;
    /** If true, the grid has new data loaded, eg user called setRowData(), otherwise
     * it's the same data but sorted or filtered, in which case this is true, and rows
     * can animate around (eg rowNode id 24 is the same row node as last time). */
    keepRenderedRows: boolean | undefined;
    /** If true, then this update was a result of setRowData() getting called. This
     * gets the grid to scroll to the top again. */
    newData: boolean | undefined;
    /** True when pagination and a new page is navigated to. */
    newPage: boolean;
}


export interface AgEvent {
    type: string;
}


export interface AgGridEvent extends AgEvent {
    api: GridApi;
    columnApi: ColumnApi;
}


export interface ToolPanelVisibleChangedEvent extends AgGridEvent {
    source: string | undefined;
}


export interface AnimationQueueEmptyEvent extends AgGridEvent {
}


export interface ColumnPivotModeChangedEvent extends AgGridEvent {
}


export interface VirtualColumnsChangedEvent extends AgGridEvent {
}


export interface ColumnEverythingChangedEvent extends AgGridEvent {
    source: string;
}


export interface NewColumnsLoadedEvent extends AgGridEvent {
}


export interface GridColumnsChangedEvent extends AgGridEvent {
}


export interface DisplayedColumnsChangedEvent extends AgGridEvent {
}


export interface RowDataChangedEvent extends AgGridEvent {
}


export interface RowDataUpdatedEvent extends AgGridEvent {
}


export interface PinnedRowDataChangedEvent extends AgGridEvent {
}


export interface SelectionChangedEvent extends AgGridEvent {
}


export interface FilterChangedEvent extends AgGridEvent {
    afterDataChange?: boolean;
    afterFloatingFilter?: boolean;
}


export interface FilterModifiedEvent extends AgGridEvent {
    filterInstance: IFilterComp;
    column: Column;
}


export interface FilterOpenedEvent extends AgGridEvent {
    column: Column;
    source: FilterRequestSource;
    eGui: HTMLElement;
}


export interface SortChangedEvent extends AgGridEvent {
}


export interface GridReadyEvent extends AgGridEvent {
}


export interface DisplayedColumnsWidthChangedEvent extends AgGridEvent {
}


export interface ColumnHoverChangedEvent extends AgGridEvent {
}


export interface BodyHeightChangedEvent extends AgGridEvent {
}


export interface ComponentStateChangedEvent extends AgGridEvent {
}


export interface DragEvent extends AgGridEvent {
    type: string;
    target: HTMLElement;
}


export interface DragStartedEvent extends DragEvent {
}


export interface DragStoppedEvent extends DragEvent {
}


export interface CheckboxChangedEvent extends AgEvent {
    id: string;
    name: string;
    selected?: boolean;
    previousValue: boolean | undefined;
}


export interface GridSizeChangedEvent extends AgGridEvent {
    clientWidth: number;
    clientHeight: number;
}


export interface RowDragEvent extends AgGridEvent {
    node: RowNode;
    nodes: RowNode[];
    y: number;
    vDirection: string;
    event: MouseEvent;
    overIndex: number;
    overNode: RowNode;
}


export interface RowDragEnterEvent extends RowDragEvent {
}


export interface RowDragEndEvent extends RowDragEvent {
}


export interface RowDragMoveEvent extends RowDragEvent {
}


export interface RowDragLeaveEvent extends RowDragEvent {
}


export interface PasteStartEvent extends AgGridEvent {
    source: string;
}


export interface PasteEndEvent extends AgGridEvent {
    source: string;
}


export interface FillStartEvent extends AgGridEvent {
}


export interface FillEndEvent extends AgGridEvent {
    initialRange: CellRange;
    finalRange: CellRange;
}


export interface ViewportChangedEvent extends AgGridEvent {
    firstRow: number;
    lastRow: number;
}


export interface FirstDataRenderedEvent extends AgGridEvent {
    firstRow: number;
    lastRow: number;
}


export interface RangeSelectionChangedEvent extends AgGridEvent {
    id?: string;
    finished: boolean;
    started: boolean;
}


export interface ChartCreated extends AgGridEvent {
    chartId: string;
    chartModel: ChartModel;
}


export interface ChartRangeSelectionChanged extends AgGridEvent {
    id: string;
    chartId: string;
    cellRange: CellRangeParams;
}


export interface ChartOptionsChanged extends AgGridEvent {
    chartId: string;
    chartType: ChartType;
    chartThemeName: string;
    chartOptions: ChartOptions<any>;
}


export interface ChartDestroyed extends AgGridEvent {
    chartId: string;
}


export interface ColumnGroupOpenedEvent extends AgGridEvent {
    columnGroup: OriginalColumnGroup;
}


export interface ItemsAddedEvent extends AgGridEvent {
    items: RowNode[];
}


export interface BodyScrollEvent extends AgGridEvent {
    direction: ScrollDirection;
    left: number;
    top: number;
}


export interface FlashCellsEvent extends AgGridEvent {
    cells: any;
}


export interface PaginationChangedEvent extends AgGridEvent {
    animate?: boolean;
    keepRenderedRows?: boolean;
    newData?: boolean;
    newPage: boolean;
}


export interface PaginationPixelOffsetChangedEvent extends AgGridEvent {
}


export interface CellFocusedEvent extends AgGridEvent {
    rowIndex: number;
    column: Column;
    rowPinned: string;
    forceBrowserFocus: boolean;
    floating: string;
}


export interface ExpandCollapseAllEvent extends AgGridEvent {
    source: string;
}


export interface ColumnEvent extends AgGridEvent {
    column: Column | null;
    columns: Column[] | null;
    source: ColumnEventType;
}


export interface ColumnResizedEvent extends ColumnEvent {
    finished: boolean;
    flexColumns: Column[];
}


export interface ColumnPivotChangedEvent extends ColumnEvent {
}


export interface ColumnRowGroupChangedEvent extends ColumnEvent {
}


export interface ColumnValueChangedEvent extends ColumnEvent {
}


export interface ColumnMovedEvent extends ColumnEvent {
    toIndex: number | undefined;
}


export interface ColumnVisibleEvent extends ColumnEvent {
    visible: boolean | undefined;
}


export interface ColumnPinnedEvent extends ColumnEvent {
    pinned: string | null;
}


/**------------*/
/** ROW EVENTS */
/**------------*/
export interface RowEvent extends AgGridEvent {
    node: RowNode;
    data: any;
    rowIndex: number;
    rowPinned: string;
    context: any;
    event?: Event | null;
}


export interface RowGroupOpenedEvent extends RowEvent {
    expanded: boolean;
}


export interface RowValueChangedEvent extends RowEvent {
}


export interface RowSelectedEvent extends RowEvent {
}


export interface VirtualRowRemovedEvent extends RowEvent {
}


export interface RowClickedEvent extends RowEvent {
}


export interface RowDoubleClickedEvent extends RowEvent {
}


export interface RowEditingStartedEvent extends RowEvent {
}


export interface RowEditingStoppedEvent extends RowEvent {
}


/**------------*/
/** CELL EVENTS */
/**------------*/
export interface CellEvent extends RowEvent {
    column: Column;
    colDef: ColDef;
    value: any;
}


export interface CellKeyDownEvent extends CellEvent {
}


export interface CellKeyPressEvent extends CellEvent {
}


export interface CellClickedEvent extends CellEvent {
}


export interface CellMouseDownEvent extends CellEvent {
}


export interface CellDoubleClickedEvent extends CellEvent {
}


export interface CellMouseOverEvent extends CellEvent {
}


export interface CellMouseOutEvent extends CellEvent {
}


export interface CellContextMenuEvent extends CellEvent {
}


export interface CellEditingStartedEvent extends CellEvent {
}


export interface CellEditingStoppedEvent extends CellEvent {
    oldValue: any;
    newValue: any;
}


export interface CellValueChangedEvent extends CellEvent {
    oldValue: any;
    newValue: any;
    source: string | undefined;
}


export interface ColumnRequestEvent extends AgGridEvent {
    columns: Column[];
}


export interface ColumnRowGroupChangeRequestEvent extends ColumnRequestEvent {
}


export interface ColumnPivotChangeRequestEvent extends ColumnRequestEvent {
}


export interface ColumnValueChangeRequestEvent extends ColumnRequestEvent {
}


export interface ColumnAggFuncChangeRequestEvent extends ColumnRequestEvent {
    aggFunc: any;
}


export interface ScrollVisibilityChangedEvent extends AgGridEvent {
}


export declare type ScrollDirection = 'horizontal' | 'vertical';


/**---------------*/
/** COLUMN EVENTS */
/**---------------*/
export declare type ColumnEventType = "sizeColumnsToFit" | "autosizeColumns" | "alignedGridChanged" | "filterChanged" | "filterDestroyed" | "gridOptionsChanged" | "gridInitializing" | "toolPanelDragAndDrop" | "toolPanelUi" | "uiColumnMoved" | "uiColumnResized" | "uiColumnDragged" | "uiColumnExpanded" | "uiColumnSorted" | "contextMenu" | "columnMenu" | "rowModelUpdated" | "api" | "flex" | "pivotChart";


export default function UploadModal({
    imageUrl,
    toolbox,
    zipUrl,
    open,
    repositoryName,
    defaultYamlFile,
    onHide,
    yamlFiles
}) {
    const { useEffect, useState } = React;

    const [loading, setLoading] = useState(false);
    const [inputValues, setInputValues] = useState(initialInputValues);
    const [uploadState, setUploadState] = useState();
    const [visibility, setVisibility] = useState(Stage.Common.Consts.defaultVisibility);
    const [errors, setErrors] = useState({});

    useEffect(() => {
        if (open) {
            setLoading(false);
            setVisibility(Stage.Common.Consts.defaultVisibility);
            setErrors({});
            if (!_.isEmpty(yamlFiles)) {
                setInputValues({ blueprintName: repositoryName, blueprintYamlFile: defaultYamlFile });
            } else {
                setInputValues(initialInputValues);
            }
        }
    }, [open]);

    function submitUpload() {
        const errorsFound = {};

        if (_.isEmpty(inputValues.blueprintName)) {
            errorsFound.blueprintName = 'Please provide blueprint name';
        }

        if (_.isEmpty(inputValues.blueprintYamlFile)) {
            errorsFound.blueprintYamlFile = 'Please provide blueprint YAML file';
        }

        if (!_.isEmpty(errorsFound)) {
            setErrors(errorsFound);
            return;
        }

        // Disable the form
        setLoading(true);
        setUploadState(BlueprintActions.InProgressBlueprintStates.Pending);

        new BlueprintActions(toolbox)
            .doUpload(
                inputValues.blueprintName,
                inputValues.blueprintYamlFile,
                zipUrl,
                null,
                Stage.Utils.Url.url(imageUrl),
                null,
                visibility
            )
            .then(() => {
                setErrors({});
                toolbox.getEventBus().trigger('blueprints:refresh');
                onHide();
            })
            .catch(err => {
                setErrors({ error: err.message });
                setUploadState(err.state);
            })
            .finally(() => setLoading(false));
    }

    function onApprove() {
        submitUpload();
        return false;
    }

    function onCancel() {
        onHide();
        return true;
    }

    function handleInputChange(proxy, field) {
        setInputValues({ ...inputValues, ...Stage.Basic.Form.fieldNameValue(field) });
    }

    const { Modal, CancelButton, ApproveButton, Icon, VisibilityField } = Stage.Basic;

    return (
        <div>
            <Modal open={open} onClose={() => onHide()}


function submitUpload() {
        const errorsFound = {};

        if (_.isEmpty(inputValues.blueprintName)) {
            errorsFound.blueprintName = 'Please provide blueprint name';
        }

        if (_.isEmpty(inputValues.blueprintYamlFile)) {
            errorsFound.blueprintYamlFile = 'Please provide blueprint YAML file';
        }

        if (!_.isEmpty(errorsFound)) {
            setErrors(errorsFound);
            return;
        }

        // Disable the form
        setLoading(true);
        setUploadState(BlueprintActions.InProgressBlueprintStates.Pending);

        new BlueprintActions(toolbox)
            .doUpload(
                inputValues.blueprintName,
                inputValues.blueprintYamlFile,
                zipUrl,
                null,
                Stage.Utils.Url.url(imageUrl),
                null,
                visibility
            )
            .then(() => {
                setErrors({});
                toolbox.getEventBus().trigger('blueprints:refresh');
                onHide();
            })
            .catch(err => {
                setErrors({ error: err.message });
                setUploadState(err.state);
            })
            .finally(() => setLoading(false));
    }


function onApprove() {
        submitUpload();
        return false;
    }


function onCancel() {
        onHide();
        return true;
    }


function handleInputChange(proxy, field) {
        setInputValues({ ...inputValues, ...Stage.Basic.Form.fieldNameValue(field) });
    }


() => {
        if (open) {
            setLoading(false);
            setVisibility(Stage.Common.Consts.defaultVisibility);
            setErrors({});
            if (!_.isEmpty(yamlFiles)) {
                setInputValues({ blueprintName: repositoryName, blueprintYamlFile: defaultYamlFile });
            } else {
                setInputValues(initialInputValues);
            }
        }
    }


() => {
                setErrors({});
                toolbox.getEventBus().trigger('blueprints:refresh');
                onHide();
            }


err => {
                setErrors({ error: err.message });
                setUploadState(err.state);
            }


function Settings(props: any) {
    const { themeSetClosed } = props;

    return (
        <Window
            y="25"
            x="20"
            title="Settings"
            width="15"
            height="20"
            closable={true}
            {...props}
        >
            <Wrapper>

Theme

                    <Button onClick={() => themeSetClosed(false)}


() => {
    let playbackButton: VgPlaybackButtonComponent;
    let ref: ElementRef;
    let api: VgAPI;

    beforeEach(() => {
        ref = {
            nativeElement: {
                getAttribute: (name) =>
                    name
            }
        };

        api = new VgAPI();
        api.medias = {
            main: {
                state: VgStates.VG_PLAYING
            },
            secondary: {
                state: VgStates.VG_PAUSED
            }
        };

        playbackButton = new VgPlaybackButtonComponent(ref, api);
    });

    it('Should set playbackIndex default value to 1', () => {
        expect(playbackButton.playbackIndex).toEqual(1);
    });

    it('Should get media by id on init', () => {
        spyOn(api, 'getMediaById').and.callFake(() => undefined);

        playbackButton.vgFor = 'test';
        playbackButton.onPlayerReady();

        expect(api.getMediaById).toHaveBeenCalledWith('test');
    });

    describe('onClick (single and multiple media)', () => {
        it('should increase playbackIndex', () => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.playbackIndex).toEqual(2);
        });

        it('should set playbackRate to target media', () => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate).toEqual('1.5');
        });

        it('should set playbackRate to target media', () => {
            const media = {
                playbackRate: {
                    test: '1'
                }
            };

            playbackButton.target = media;
            playbackButton.vgFor = 'test';

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate.test).toEqual('1.5');
        });
    });
}


() => {
        ref = {
            nativeElement: {
                getAttribute: (name) =>
                    name
            }
        };

        api = new VgAPI();
        api.medias = {
            main: {
                state: VgStates.VG_PLAYING
            },
            secondary: {
                state: VgStates.VG_PAUSED
            }
        };

        playbackButton = new VgPlaybackButtonComponent(ref, api);
    }


(name) =>
                    name


() => {
        expect(playbackButton.playbackIndex).toEqual(1);
    }


() => {
        spyOn(api, 'getMediaById').and.callFake(() => undefined);

        playbackButton.vgFor = 'test';
        playbackButton.onPlayerReady();

        expect(api.getMediaById).toHaveBeenCalledWith('test');
    }


() => {
        it('should increase playbackIndex', () => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.playbackIndex).toEqual(2);
        });

        it('should set playbackRate to target media', () => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate).toEqual('1.5');
        });

        it('should set playbackRate to target media', () => {
            const media = {
                playbackRate: {
                    test: '1'
                }
            };

            playbackButton.target = media;
            playbackButton.vgFor = 'test';

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate.test).toEqual('1.5');
        });
    }


() => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.playbackIndex).toEqual(2);
        }


() => {
            api.medias = {
                main: {
                    state: VgStates.VG_PLAYING
                }
            };

            playbackButton.target = api;

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate).toEqual('1.5');
        }


() => {
            const media = {
                playbackRate: {
                    test: '1'
                }
            };

            playbackButton.target = media;
            playbackButton.vgFor = 'test';

            playbackButton.onClick();

            expect(playbackButton.target.playbackRate.test).toEqual('1.5');
        }


export function makeGaugeProvider(
  options: client.GaugeConfiguration<string>,
): Provider {
  return {
    provide: getToken(options.name),
    useFactory(): client.Metric<string> {
      return getOrCreateMetric("Gauge", options);
    },
  };
}


useFactory(): client.Metric<string> {
      return getOrCreateMetric("Gauge", options);
    }


export declare class CloudBase {
    static scfContext: IContext;
    static parseContext(context: IContext): IContext;
    config: ICloudBaseConfig;
    private clsLogger;
    constructor(config?: ICloudBaseConfig);
    init(config?: ICloudBaseConfig): void;
    database(dbConfig?: any): Db;
    /**
     * 调用云函数
     *
     * @param param0
     * @param opts
     */
    callFunction({ name, data }: {
        name: any;
        data: any;
    }, opts?: ICustomReqOpts): Promise<any>;
    auth(): any;
    /**
     * openapi调用
     *
     * @param param0
     * @param opts
     */
    callWxOpenApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;
    /**
     * wxpayapi调用
     *
     * @param param0
     * @param opts
     */
    callWxPayApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;
    /**
     * 微信云调用
     *
     * @param param0
     * @param opts
     */
    callCompatibleWxOpenApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;
    /**
     * 上传文件
     *
     * @param param0
     * @param opts
     */
    uploadFile({ cloudPath, fileContent }: {
        cloudPath: any;
        fileContent: any;
    }, opts?: ICustomReqOpts): Promise<IUploadFileRes>;
    /**
     * 删除文件
     *
     * @param param0
     * @param opts
     */
    deleteFile({ fileList }: {
        fileList: any;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IDeleteFileRes>;
    /**
     * 获取临时连接
     *
     * @param param0
     * @param opts
     */
    getTempFileURL({ fileList }: {
        fileList: any;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IGetFileUrlRes>;
    /**
     * 下载文件
     *
     * @param params
     * @param opts
     */
    downloadFile(params: {
        fileID: string;
        tempFilePath?: string;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IDownloadFileRes>;
    /**
     * 获取上传元数据
     *
     * @param param0
     * @param opts
     */
    getUploadMetadata({ cloudPath }: {
        cloudPath: any;
    }, opts?: ICustomReqOpts): Promise<any>;
    /**
     * 获取logger
     *
     */
    logger(): Log;
}


static parseContext(context: IContext): IContext;


init(config?: ICloudBaseConfig): void;


database(dbConfig?: any): Db;


/**
     * 调用云函数
     *
     * @param param0
     * @param opts
     */
callFunction({ name, data }: {
        name: any;
        data: any;
    }, opts?: ICustomReqOpts): Promise<any>;


auth(): any;


/**
     * openapi调用
     *
     * @param param0
     * @param opts
     */
callWxOpenApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;


/**
     * wxpayapi调用
     *
     * @param param0
     * @param opts
     */
callWxPayApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;


/**
     * 微信云调用
     *
     * @param param0
     * @param opts
     */
callCompatibleWxOpenApi({ apiName, requestData }: {
        apiName: any;
        requestData: any;
    }, opts?: ICustomReqOpts): Promise<any>;


/**
     * 上传文件
     *
     * @param param0
     * @param opts
     */
uploadFile({ cloudPath, fileContent }: {
        cloudPath: any;
        fileContent: any;
    }, opts?: ICustomReqOpts): Promise<IUploadFileRes>;


/**
     * 删除文件
     *
     * @param param0
     * @param opts
     */
deleteFile({ fileList }: {
        fileList: any;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IDeleteFileRes>;


/**
     * 获取临时连接
     *
     * @param param0
     * @param opts
     */
getTempFileURL({ fileList }: {
        fileList: any;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IGetFileUrlRes>;


/**
     * 下载文件
     *
     * @param params
     * @param opts
     */
downloadFile(params: {
        fileID: string;
        tempFilePath?: string;
    }, opts?: ICustomReqOpts): Promise<ICustomErrRes | IDownloadFileRes>;


/**
     * 获取上传元数据
     *
     * @param param0
     * @param opts
     */
getUploadMetadata({ cloudPath }: {
        cloudPath: any;
    }, opts?: ICustomReqOpts): Promise<any>;


/**
     * 获取logger
     *
     */
logger(): Log;


(fill: string, size: number) => (
  <svg
    aria-hidden="true"


export class CreateUnivDto{
    @IsString()
    nameEn: string;

    @IsString()
    nameSp: string;

    @IsString()
    descriptionEn: string;

    @IsString()
    descriptionSp: string;

    @IsString()
    location: string;

    @IsString()
    founded: string;

    @IsString()
    intStudents: string;

    @IsString()
    totalStudents: string;

    @IsString()
    faculty: string;
}


() => {
  const { t } = useTranslation();
  const {
    values: { data },
  } = useFormikContext<FormikValues>();
  const kafkaSource = EventSources.KafkaSource;
  const saslEnable = data?.[kafkaSource]?.net?.sasl?.enable;
  const tlsEnable = data?.[kafkaSource]?.net?.tls?.enable;

  return (
    <>

Net

      <CheckboxField
        data-test-id="kafkasource-sasl-field"
        name={`data.${kafkaSource}.net.sasl.enable`}


t('knative-plugin~Enable')


t('knative-plugin~Password')


t('knative-plugin~CA Certificate')


t('knative-plugin~Certificate')


export class FileSystemFactory {

  public getUserFileSystem(username: string): FileSystemCommunicator {
    return this.getFileSystemCommunicator("filesystem." + username, 80)
  }

  private getFileSystemCommunicator(host: string, port: number): FileSystemCommunicator {
    const client = new ClientCommunicator(host, port)
    return new FileSystemCommunicator(client)
  }
}


public getUserFileSystem(username: string): FileSystemCommunicator {
    return this.getFileSystemCommunicator("filesystem." + username, 80)
  }


private getFileSystemCommunicator(host: string, port: number): FileSystemCommunicator {
    const client = new ClientCommunicator(host, port)
    return new FileSystemCommunicator(client)
  }


(props: { children: any }) => {
  const { children } = props;
  return (

          {children}


(propertyMapping) => propertyMapping.property.value.name === propertyName


(propertyMapping) =>
        propertyMapping.targetSetImplementation &&
        propertyMapping.targetSetImplementation.id.value === targetId


(propertyMapping) => !propertyMapping.isStub


export class PureInstanceSetImplementation
  extends InstanceSetImplementation
  implements Hashable, Stubable
{
  srcClass: OptionalPackageableElementReference<Class>;
  filter?: RawLambda | undefined; // @MARKER GENERATED MODEL DISCREPANCY --- Studio does not process lambda
  declare propertyMappings: PurePropertyMapping[];

  constructor(
    id: InferableMappingElementIdValue,
    parent: Mapping,
    _class: PackageableElementReference<Class>,
    root: InferableMappingElementRoot,
    srcClass: OptionalPackageableElementReference<Class>,
  ) {
    super(id, parent, _class, root);

    makeObservable(this, {
      filter: observable,
      setPropertyMappings: action,
      setSrcClass: action,
      setMappingFilter: action,
      isStub: computed,
      hashCode: computed,
    });

    this.srcClass = srcClass;
  }

  setPropertyMappings(value: PurePropertyMapping[]): void {
    this.propertyMappings = value;
  }
  setSrcClass(value: Class | undefined): void {
    this.srcClass.setValue(value);
  }
  setMappingFilter(value: RawLambda | undefined): void {
    this.filter = value;
  }

  findPropertyMapping(
    propertyName: string,
    targetId: string | undefined,
  ): PurePropertyMapping | undefined {
    let properties = undefined;
    properties = this.propertyMappings.filter(
      (propertyMapping) => propertyMapping.property.value.name === propertyName,
    );
    if (targetId === undefined || properties.length === 1) {
      return properties[0];
    }
    return properties.find(
      (propertyMapping) =>
        propertyMapping.targetSetImplementation &&
        propertyMapping.targetSetImplementation.id.value === targetId,
    );
  }

  override get isStub(): boolean {
    return super.isStub && isStubArray(this.propertyMappings);
  }

  override get hashCode(): string {
    return hashArray([
      CORE_HASH_STRUCTURE.PURE_INSTANCE_SET_IMPLEMENTATION,
      super.hashCode,
      this.srcClass.valueForSerialization ?? '',
      this.filter ?? '',
      hashArray(
        this.propertyMappings.filter(
          (propertyMapping) => !propertyMapping.isStub,
        ),
      ),
    ]);
  }

  accept_SetImplementationVisitor<T>(visitor: SetImplementationVisitor<T>): T {
    return visitor.visit_PureInstanceSetImplementation(this);
  }

  getEmbeddedSetImplmentations(): InstanceSetImplementation[] {
    return [];
  }
}


setPropertyMappings(value: PurePropertyMapping[]): void {
    this.propertyMappings = value;
  }


setSrcClass(value: Class | undefined): void {
    this.srcClass.setValue(value);
  }


setMappingFilter(value: RawLambda | undefined): void {
    this.filter = value;
  }


findPropertyMapping(
    propertyName: string,
    targetId: string | undefined,
  ): PurePropertyMapping | undefined {
    let properties = undefined;
    properties = this.propertyMappings.filter(
      (propertyMapping) => propertyMapping.property.value.name === propertyName,
    );
    if (targetId === undefined || properties.length === 1) {
      return properties[0];
    }
    return properties.find(
      (propertyMapping) =>
        propertyMapping.targetSetImplementation &&
        propertyMapping.targetSetImplementation.id.value === targetId,
    );
  }


accept_SetImplementationVisitor<T>(visitor: SetImplementationVisitor<T>): T {
    return visitor.visit_PureInstanceSetImplementation(this);
  }


getEmbeddedSetImplmentations(): InstanceSetImplementation[] {
    return [];
  }


/**
 * Returns the composition of two foldables
 *
 * @example
 * import { getFoldableComposition } from 'fp-ts/lib/Foldable'
 * import { array } from 'fp-ts/lib/Array'
 * import { option, some, none } from 'fp-ts/lib/Option'
 * import { monoidString } from 'fp-ts/lib/Monoid'
 *
 * const F = getFoldableComposition(array, option)
 * assert.strictEqual(F.reduce([some('a'), some('b'), some('c')], '', monoidString.concat), 'abc')
 * assert.strictEqual(F.reduce([some('a'), none, some('c')], '', monoidString.concat), 'ac')
 *
 * @since 2.0.0
 */
export function getFoldableComposition<F extends URIS2, G extends URIS2, E>(
  F: Foldable2<F>,
  G: Foldable2C<G, E>
): FoldableComposition22C<F, G, E>


export function getFoldableComposition<F extends URIS2, G extends URIS2>(
  F: Foldable2<F>,
  G: Foldable2<G>
): FoldableComposition22<F, G>


export function getFoldableComposition<F extends URIS2, G extends URIS, E>(
  F: Foldable2C<F, E>,
  G: Foldable1<G>
): FoldableComposition2C1<F, G, E>


export function getFoldableComposition<F extends URIS2, G extends URIS>(
  F: Foldable2<F>,
  G: Foldable1<G>
): FoldableComposition21<F, G>


export function getFoldableComposition<F extends URIS, G extends URIS2, E>(
  F: Foldable1<F>,
  G: Foldable2C<G, E>
): FoldableComposition12C<F, G, E>


export function getFoldableComposition<F extends URIS, G extends URIS2>(
  F: Foldable1<F>,
  G: Foldable2<G>
): FoldableComposition12<F, G>


export function getFoldableComposition<F extends URIS, G extends URIS>(
  F: Foldable1<F>,
  G: Foldable1<G>
): FoldableComposition11<F, G>


export function getFoldableComposition<F, G>(F: Foldable<F>, G: Foldable<G>): FoldableComposition<F, G>


export function getFoldableComposition<F, G>(F: Foldable<F>, G: Foldable<G>): FoldableComposition<F, G> {
  return {
    reduce: (fga, b, f) => F.reduce(fga, b, (b, ga) => G.reduce(ga, b, f)),
    foldMap: M => {
      const foldMapF = F.foldMap(M)
      const foldMapG = G.foldMap(M)
      return (fa, f) => foldMapF(fa, ga => foldMapG(ga, f))
    },
    reduceRight: (fa, b, f) => F.reduceRight(fa, b, (ga, b) => G.reduceRight(ga, b, f))
  }
}


/**
 * Similar to 'reduce', but the result is encapsulated in a monad.
 *
 * Note: this function is not generally stack-safe, e.g., for monads which build up thunks a la `IO`.
 *
 * @example
 * import { foldM } from 'fp-ts/lib/Foldable'
 * import { option, some } from 'fp-ts/lib/Option'
 * import { make, tree } from 'fp-ts/lib/Tree'
 *
 * const t = make(1, [make(2, []), make(3, []), make(4, [])])
 * assert.deepStrictEqual(foldM(option, tree)(t, 0, (b, a) => (a > 2 ? some(b + a) : some(b))), some(7))
 *
 * @since 2.0.0
 */
export function foldM<M extends URIS3, F extends URIS>(
  M: Monad3<M>,
  F: Foldable1<F>
): <R, E, A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind3<M, R, E, B>) => Kind3<M, R, E, B>


export function foldM<M extends URIS2, F extends URIS>(
  M: Monad2<M>,
  F: Foldable1<F>
): <E, A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind2<M, E, B>) => Kind2<M, E, B>


export function foldM<M extends URIS2, F extends URIS, E>(
  M: Monad2C<M, E>,
  F: Foldable1<F>
): <A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind2<M, E, B>) => Kind2<M, E, B>


export function foldM<M extends URIS, F extends URIS>(
  M: Monad1<M>,
  F: Foldable1<F>
): <A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind<M, B>) => Kind<M, B>


export function foldM<M, F>(
  M: Monad<M>,
  F: Foldable<F>
): <A, B>(fa: HKT<F, A>, b: B, f: (b: B, a: A) => HKT<M, B>) => HKT<M, B>


export function foldM<M, F>(
  M: Monad<M>,
  F: Foldable<F>
): <A, B>(fa: HKT<F, A>, b: B, f: (b: B, a: A) => HKT<M, B>) => HKT<M, B> {
  return (fa, b, f) => F.reduce(fa, M.of(b), (mb, a) => M.chain(mb, b => f(b, a)))
}


/**
 * Fold a data structure, accumulating values in some `Monoid`, combining adjacent elements using the specified separator
 *
 * @example
 * import { intercalate } from 'fp-ts/lib/Foldable'
 * import { monoidString } from 'fp-ts/lib/Monoid'
 * import { make, tree } from 'fp-ts/lib/Tree'
 *
 * const t = make('a', [make('b', []), make('c', []), make('d', [])])
 * assert.strictEqual(intercalate(monoidString, tree)('|', t), 'a|b|c|d')
 *
 * @since 2.0.0
 */
export function intercalate<M, F extends URIS3>(
  M: Monoid<M>,
  F: Foldable3<F>
): <R, E>(sep: M, fm: Kind3<F, R, E, M>) => M


export function intercalate<M, F extends URIS2>(M: Monoid<M>, F: Foldable2<F>): <E>(sep: M, fm: Kind2<F, E, M>) => M