() => {
                             const mergedTree =
                                 this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
                             const extras = {
                               skipLocationChange: t.extras.skipLocationChange,
                               // The URL is already updated at this point if we have 'eager' URL
                               // updates or if the navigation was triggered by the browser (back
                               // button, URL bar, etc). We want to replace that item in history if
                               // the navigation is rejected.
                               replaceUrl: this.urlUpdateStrategy === 'eager' ||
                                   isBrowserTriggeredNavigation(t.source)
                             };

                             this.scheduleNavigation(
                                 mergedTree, 'imperative', null, extras,
                                 {resolve: t.resolve, reject: t.reject, promise: t.promise});
                           }


event => {
        const source = event['type'] === 'popstate' ? 'popstate' : 'hashchange';
        if (source === 'popstate') {
          // The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
          // hybrid apps.
          setTimeout(() => {
            const extras: NavigationExtras = {replaceUrl: true};
            // Navigations coming from Angular router have a navigationId state
            // property. When this exists, restore the state.
            const state = event.state?.navigationId ? event.state : null;
            if (state) {
              const stateCopy = {...state} as Partial<RestoredState>;
              delete stateCopy.navigationId;
              delete stateCopy.ɵrouterPageId;
              if (Object.keys(stateCopy).length !== 0) {
                extras.state = stateCopy;
              }
            }
            const urlTree = this.parseUrl(event['url']!);
            this.scheduleNavigation(urlTree, source, state, extras);
          }, 0);
        }
      }


() => {
            const extras: NavigationExtras = {replaceUrl: true};
            // Navigations coming from Angular router have a navigationId state
            // property. When this exists, restore the state.
            const state = event.state?.navigationId ? event.state : null;
            if (state) {
              const stateCopy = {...state} as Partial<RestoredState>;
              delete stateCopy.navigationId;
              delete stateCopy.ɵrouterPageId;
              if (Object.keys(stateCopy).length !== 0) {
                extras.state = stateCopy;
              }
            }
            const urlTree = this.parseUrl(event['url']!);
            this.scheduleNavigation(urlTree, source, state, extras);
          }


(result: Params, key: string) => {
      const value: any = params[key];
      if (value !== null && value !== undefined) {
        result[key] = value;
      }
      return result;
    }


t => {
          this.navigated = true;
          this.lastSuccessfulId = t.id;
          this.currentPageId = t.targetPageId;
          (this.events as Subject<Event>)
              .next(new NavigationEnd(
                  t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
          this.lastSuccessfulNavigation = this.currentNavigation;
          t.resolve(true);
        }


e => {
          this.console.warn(`Unhandled Navigation Error: ${e}`);
        }


(res, rej) => {
        resolve = res;
        reject = rej;
      }


(e: any) => {
      return Promise.reject(e);
    }


/**
 * @description
 *
 * Options that modify the `Router` URL.
 * Supply an object containing any of these properties to a `Router` navigation function to
 * control how the target URL should be constructed.
 *
 * @see [Router.navigate() method](api/router/Router#navigate)
 * @see [Router.createUrlTree() method](api/router/Router#createurltree)
 * @see [Routing and Navigation guide](guide/router)
 *
 * @publicApi
 */
export interface UrlCreationOptions {
  /**
   * Specifies a root URI to use for relative navigation.
   *
   * For example, consider the following route configuration where the parent route
   * has two children.
   *
   * ```
   * [{
   *   path: 'parent',
   *   component: ParentComponent,
   *   children: [{
   *     path: 'list',
   *     component: ListComponent
   *   },{
   *     path: 'child',
   *     component: ChildComponent
   *   }]
   * }]
   * ```
   *
   * The following `go()` function navigates to the `list` route by
   * interpreting the destination URI as relative to the activated `child`  route
   *
   * ```
   *  @Component({...})
   *  class ChildComponent {
   *    constructor(private router: Router, private route: ActivatedRoute) {}
   *
   *    go() {
   *      this.router.navigate(['../list'], { relativeTo: this.route });
   *    }
   *  }
   * ```
   *
   * A value of `null` or `undefined` indicates that the navigation commands should be applied
   * relative to the root.
   */
  relativeTo?: ActivatedRoute|null;

  /**
   * Sets query parameters to the URL.
   *
   * ```
   * // Navigate to /results?page=1
   * this.router.navigate(['/results'], { queryParams: { page: 1 } });
   * ```
   */
  queryParams?: Params|null;

  /**
   * Sets the hash fragment for the URL.
   *
   * ```
   * // Navigate to /results#top
   * this.router.navigate(['/results'], { fragment: 'top' });
   * ```
   */
  fragment?: string;

  /**
   * How to handle query parameters in the router link for the next navigation.
   * One of:
   * * `preserve` : Preserve current parameters.
   * * `merge` : Merge new with current parameters.
   *
   * The "preserve" option discards any new query params:
   * ```
   * // from /view1?page=1 to/view2?page=1
   * this.router.navigate(['/view2'], { queryParams: { page: 2 },  queryParamsHandling: "preserve"
   * });
   * ```
   * The "merge" option appends new query params to the params from the current URL:
   * ```
   * // from /view1?page=1 to/view2?page=1&otherKey=2
   * this.router.navigate(['/view2'], { queryParams: { otherKey: 2 },  queryParamsHandling: "merge"
   * });
   * ```
   * In case of a key collision between current parameters and those in the `queryParams` object,
   * the new value is used.
   *
   */
  queryParamsHandling?: QueryParamsHandling|null;

  /**
   * When true, preserves the URL fragment for the next navigation
   *
   * ```
   * // Preserve fragment from /results#top to /view#top
   * this.router.navigate(['/view'], { preserveFragment: true });
   * ```
   */
  preserveFragment?: boolean;
}


/**
 * @description
 *
 * Options that modify the `Router` navigation strategy.
 * Supply an object containing any of these properties to a `Router` navigation function to
 * control how the navigation should be handled.
 *
 * @see [Router.navigate() method](api/router/Router#navigate)
 * @see [Router.navigateByUrl() method](api/router/Router#navigatebyurl)
 * @see [Routing and Navigation guide](guide/router)
 *
 * @publicApi
 */
export interface NavigationBehaviorOptions {
  /**
   * When true, navigates without pushing a new state into history.
   *
   * ```
   * // Navigate silently to /view
   * this.router.navigate(['/view'], { skipLocationChange: true });
   * ```
   */
  skipLocationChange?: boolean;

  /**
   * When true, navigates while replacing the current state in history.
   *
   * ```
   * // Navigate to /view
   * this.router.navigate(['/view'], { replaceUrl: true });
   * ```
   */
  replaceUrl?: boolean;

  /**
   * Developer-defined state that can be passed to any navigation.
   * Access this value through the `Navigation.extras` object
   * returned from the [Router.getCurrentNavigation()
   * method](api/router/Router#getcurrentnavigation) while a navigation is executing.
   *
   * After a navigation completes, the router writes an object containing this
   * value together with a `navigationId` to `history.state`.
   * The value is written when `location.go()` or `location.replaceState()`
   * is called before activating this route.
   *
   * Note that `history.state` does not pass an object equality test because
   * the router adds the `navigationId` on each navigation.
   *
   */
  state?: {[k: string]: any};
}


/**
 * @description
 *
 * Options that modify the `Router` navigation strategy.
 * Supply an object containing any of these properties to a `Router` navigation function to
 * control how the target URL should be constructed or interpreted.
 *
 * @see [Router.navigate() method](api/router/Router#navigate)
 * @see [Router.navigateByUrl() method](api/router/Router#navigatebyurl)
 * @see [Router.createUrlTree() method](api/router/Router#createurltree)
 * @see [Routing and Navigation guide](guide/router)
 * @see UrlCreationOptions
 * @see NavigationBehaviorOptions
 *
 * @publicApi
 */
export interface NavigationExtras extends UrlCreationOptions, NavigationBehaviorOptions {}


/**
 * Information about a navigation operation.
 * Retrieve the most recent navigation object with the
 * [Router.getCurrentNavigation() method](api/router/Router#getcurrentnavigation) .
 *
 * * *id* : The unique identifier of the current navigation.
 * * *initialUrl* : The target URL passed into the `Router#navigateByUrl()` call before navigation.
 * This is the value before the router has parsed or applied redirects to it.
 * * *extractedUrl* : The initial target URL after being parsed with `UrlSerializer.extract()`.
 * * *finalUrl* : The extracted URL after redirects have been applied.
 * This URL may not be available immediately, therefore this property can be `undefined`.
 * It is guaranteed to be set after the `RoutesRecognized` event fires.
 * * *trigger* : Identifies how this navigation was triggered.
 * -- 'imperative'--Triggered by `router.navigateByUrl` or `router.navigate`.
 * -- 'popstate'--Triggered by a popstate event.
 * -- 'hashchange'--Triggered by a hashchange event.
 * * *extras* : A `NavigationExtras` options object that controlled the strategy used for this
 * navigation.
 * * *previousNavigation* : The previously successful `Navigation` object. Only one previous
 * navigation is available, therefore this previous `Navigation` object has a `null` value for its
 * own `previousNavigation`.
 *
 * @publicApi
 */
export interface Navigation {
  /**
   * The unique identifier of the current navigation.
   */
  id: number;
  /**
   * The target URL passed into the `Router#navigateByUrl()` call before navigation. This is
   * the value before the router has parsed or applied redirects to it.
   */
  initialUrl: string|UrlTree;
  /**
   * The initial target URL after being parsed with `UrlSerializer.extract()`.
   */
  extractedUrl: UrlTree;
  /**
   * The extracted URL after redirects have been applied.
   * This URL may not be available immediately, therefore this property can be `undefined`.
   * It is guaranteed to be set after the `RoutesRecognized` event fires.
   */
  finalUrl?: UrlTree;
  /**
   * Identifies how this navigation was triggered.
   *
   * * 'imperative'--Triggered by `router.navigateByUrl` or `router.navigate`.
   * * 'popstate'--Triggered by a popstate event.
   * * 'hashchange'--Triggered by a hashchange event.
   */
  trigger: 'imperative'|'popstate'|'hashchange';
  /**
   * Options that controlled the strategy used for this navigation.
   * See `NavigationExtras`.
   */
  extras: NavigationExtras;
  /**
   * The previously successful `Navigation` object. Only one previous navigation
   * is available, therefore this previous `Navigation` object has a `null` value
   * for its own `previousNavigation`.
   */
  previousNavigation: Navigation|null;
}


/**
 * Error handler that is invoked when a navigation error occurs.
 *
 * If the handler returns a value, the navigation Promise is resolved with this value.
 * If the handler throws an exception, the navigation Promise is rejected with
 * the exception.
 *
 * @publicApi
 */
export type ErrorHandler = (error: any) => any;


export type RestoredState = {
  [k: string]: any,
  // TODO(#27607): Remove `navigationId` and `ɵrouterPageId` and move to `ng` or `ɵ` namespace.
  navigationId: number,
  // The `ɵ` prefix is there to reduce the chance of colliding with any existing user properties on
  // the history state.
  ɵrouterPageId?: number,
};


export type NavigationTransition = {
  id: number,
  targetPageId: number,
  currentUrlTree: UrlTree,
  currentRawUrl: UrlTree,
  extractedUrl: UrlTree,
  urlAfterRedirects: UrlTree,
  rawUrl: UrlTree,
  extras: NavigationExtras,
  resolve: any,
  reject: any,
  promise: Promise<boolean>,
  source: NavigationTrigger,
  restoredState: RestoredState|null,
  currentSnapshot: RouterStateSnapshot,
  targetSnapshot: RouterStateSnapshot|null,
  currentRouterState: RouterState,
  targetRouterState: RouterState|null,
  guards: Checks,
  guardsResult: boolean|UrlTree|null,
};


/**
 * @internal
 */
export type RouterHook = (snapshot: RouterStateSnapshot, runExtras: {
  appliedUrlTree: UrlTree,
  rawUrlTree: UrlTree,
  skipLocationChange: boolean,
  replaceUrl: boolean,
  navigationId: number
}) => Observable<void>;


next() {
                         completed = true;
                       }


complete() {
                         completed = true;
                       }


/**
   * @internal
   * TODO: this should be removed once the constructor of the router made internal
   */
resetRootComponentType(rootComponentType: Type<any>): void {
    this.rootComponentType = rootComponentType;
    // TODO: vsavkin router 4.0 should make the root component set to null
    // this will simplify the lifecycle of the router.
    this.routerState.root.component = this.rootComponentType;
  }


private getTransition(): NavigationTransition {
    const transition = this.transitions.value;
    // TODO(atscott): This comment doesn't make it clear why this value needs to be set. In the case
    // described below (where we don't handle previous or current url), the `browserUrlTree` is set
    // to the `urlAfterRedirects` value. However, these values *are already the same* because of the
    // line below. So it seems that we should be able to remove the line below and the line where
    // `browserUrlTree` is updated when we aren't handling any part of the navigation url.
    // Run TGP to confirm that this can be done.

    // This value needs to be set. Other values such as extractedUrl are set on initial navigation
    // but the urlAfterRedirects may not get set if we aren't processing the new URL *and* not
    // processing the previous URL.
    transition.urlAfterRedirects = this.browserUrlTree;
    return transition;
  }


private setTransition(t: Partial<NavigationTransition>): void {
    this.transitions.next({...this.getTransition(), ...t});
  }


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


/**
   * Sets up the location change listener. This listener detects navigations triggered from outside
   * the Router (the browser back/forward buttons, for example) and schedules a corresponding Router
   * navigation so that the correct events, guards, etc. are triggered.
   */
setUpLocationChangeListener(): void {
    // Don't need to use Zone.wrap any more, because zone.js
    // already patch onPopState, so location change callback will
    // run into ngZone
    if (!this.locationSubscription) {
      this.locationSubscription = this.location.subscribe(event => {
        const source = event['type'] === 'popstate' ? 'popstate' : 'hashchange';
        if (source === 'popstate') {
          // The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
          // hybrid apps.
          setTimeout(() => {
            const extras: NavigationExtras = {replaceUrl: true};
            // Navigations coming from Angular router have a navigationId state
            // property. When this exists, restore the state.
            const state = event.state?.navigationId ? event.state : null;
            if (state) {
              const stateCopy = {...state} as Partial<RestoredState>;
              delete stateCopy.navigationId;
              delete stateCopy.ɵrouterPageId;
              if (Object.keys(stateCopy).length !== 0) {
                extras.state = stateCopy;
              }
            }
            const urlTree = this.parseUrl(event['url']!);
            this.scheduleNavigation(urlTree, source, state, extras);
          }, 0);
        }
      });
    }
  }


/**
   * Returns the current `Navigation` object when the router is navigating,
   * and `null` when idle.
   */
getCurrentNavigation(): Navigation|null {
    return this.currentNavigation;
  }


/** @internal */
triggerEvent(event: Event): void {
    (this.events as Subject<Event>).next(event);
  }


/**
   * Resets the route configuration used for navigation and generating links.
   *
   * @param config The route array for the new configuration.
   *
   * @usageNotes
   *
   * ```
   * 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.map(standardizeConfig);
    this.navigated = false;
    this.lastSuccessfulId = -1;
  }


/** @nodoc */
ngOnDestroy(): void {
    this.dispose();
  }


/** Disposes of the router. */
dispose(): void {
    this.transitions.complete();
    if (this.locationSubscription) {
      this.locationSubscription.unsubscribe();
      this.locationSubscription = undefined;
    }
    this.disposed = true;
  }


/**
   * Appends URL segments to the current URL tree to create a new URL tree.
   *
   * @param commands An array of URL fragments with which to construct the new URL tree.
   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
   * segments, followed by the parameters for each segment.
   * The fragments are applied to the current URL tree or the one provided  in the `relativeTo`
   * property of the options object, if supplied.
   * @param navigationExtras Options that control the navigation strategy.
   * @returns The new URL tree.
   *
   * @usageNotes
   *
   * ```
   * // 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});
   *
   * Note that a value of `null` or `undefined` for `relativeTo` indicates that the
   * tree should be created relative to the root.
   * ```
   */
createUrlTree(commands: any[], navigationExtras: UrlCreationOptions = {}): UrlTree {
    const {relativeTo, queryParams, fragment, queryParamsHandling, preserveFragment} =
        navigationExtras;
    const a = relativeTo || this.routerState.root;
    const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
    let q: Params|null = null;
    switch (queryParamsHandling) {
      case 'merge':
        q = {...this.currentUrlTree.queryParams, ...queryParams};
        break;
      case 'preserve':
        q = this.currentUrlTree.queryParams;
        break;
      default:
        q = queryParams || null;
    }
    if (q !== null) {
      q = this.removeEmptyProps(q);
    }
    return createUrlTree(a, this.currentUrlTree, commands, q, f ?? null);
  }


/**
   * Navigates to a view using an absolute route path.
   *
   * @param url An absolute path for a defined route. The function does not apply any delta to the
   *     current URL.
   * @param extras An object containing properties that modify the navigation strategy.
   *
   * @returns A Promise that resolves to 'true' when navigation succeeds,
   * to 'false' when navigation fails, or is rejected on error.
   *
   * @usageNotes
   *
   * The following calls request navigation to an absolute path.
   *
   * ```
   * router.navigateByUrl("/team/33/user/11");
   *
   * // Navigate without updating the URL
   * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
   * ```
   *
   * @see [Routing and Navigation guide](guide/router)
   *
   */
navigateByUrl(url: string|UrlTree, extras: NavigationBehaviorOptions = {
    skipLocationChange: false
  }): Promise<boolean> {
    if (typeof ngDevMode === 'undefined' ||
        ngDevMode && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
      this.console.warn(
          `Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
    }

    const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
    const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);

    return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
  }


/**
   * Navigate based on the provided array of commands and a starting point.
   * If no starting route is provided, the navigation is absolute.
   *
   * @param commands An array of URL fragments with which to construct the target URL.
   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
   * segments, followed by the parameters for each segment.
   * The fragments are applied to the current URL or the one provided  in the `relativeTo` property
   * of the options object, if supplied.
   * @param extras An options object that determines how the URL should be constructed or
   *     interpreted.
   *
   * @returns A Promise that resolves to `true` when navigation succeeds, to `false` when navigation
   *     fails,
   * or is rejected on error.
   *
   * @usageNotes
   *
   * The following calls request navigation to a dynamic route path relative to the current URL.
   *
   * ```
   * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
   *
   * // Navigate without updating the URL, overriding the default behavior
   * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
   * ```
   *
   * @see [Routing and Navigation guide](guide/router)
   *
   */
navigate(commands: any[], extras: NavigationExtras = {skipLocationChange: false}):
      Promise<boolean> {
    validateCommands(commands);
    return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
  }


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


/** Parses a string into a `UrlTree` */
parseUrl(url: string): UrlTree {
    let urlTree: UrlTree;
    try {
      urlTree = this.urlSerializer.parse(url);
    } catch (e) {
      urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
    }
    return urlTree;
  }


/**
   * Returns whether the url is activated.
   *
   * @deprecated
   * Use `IsActiveMatchOptions` instead.
   *
   * - The equivalent `IsActiveMatchOptions` for `true` is
   * `{paths: 'exact', queryParams: 'exact', fragment: 'ignored', matrixParams: 'ignored'}`.
   * - The equivalent for `false` is
   * `{paths: 'subset', queryParams: 'subset', fragment: 'ignored', matrixParams: 'ignored'}`.
   */
isActive(url: string|UrlTree, exact: boolean): boolean;


/**
   * Returns whether the url is activated.
   */
isActive(url: string|UrlTree, matchOptions: IsActiveMatchOptions): boolean;


/** @internal */
isActive(url: string|UrlTree, matchOptions: boolean|IsActiveMatchOptions): boolean;


isActive(url: string|UrlTree, matchOptions: boolean|IsActiveMatchOptions): boolean {
    let options: IsActiveMatchOptions;
    if (matchOptions === true) {
      options = {...exactMatchOptions};
    } else if (matchOptions === false) {
      options = {...subsetMatchOptions};
    } else {
      options = matchOptions;
    }
    if (isUrlTree(url)) {
      return containsTree(this.currentUrlTree, url, options);
    }

    const urlTree = this.parseUrl(url);
    return containsTree(this.currentUrlTree, urlTree, options);
  }


private removeEmptyProps(params: Params): Params {
    return Object.keys(params).reduce((result: Params, key: string) => {
      const value: any = params[key];
      if (value !== null && value !== undefined) {
        result[key] = value;
      }
      return result;
    }, {});
  }


private processNavigations(): void {
    this.navigations.subscribe(
        t => {
          this.navigated = true;
          this.lastSuccessfulId = t.id;
          this.currentPageId = t.targetPageId;
          (this.events as Subject<Event>)
              .next(new NavigationEnd(
                  t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
          this.lastSuccessfulNavigation = this.currentNavigation;
          t.resolve(true);
        },
        e => {
          this.console.warn(`Unhandled Navigation Error: ${e}`);
        });
  }


private scheduleNavigation(
      rawUrl: UrlTree, source: NavigationTrigger, restoredState: RestoredState|null,
      extras: NavigationExtras,
      priorPromise?: {resolve: any, reject: any, promise: Promise<boolean>}): Promise<boolean> {
    if (this.disposed) {
      return Promise.resolve(false);
    }

    // * Imperative navigations (router.navigate) might trigger additional navigations to the same
    //   URL via a popstate event and the locationChangeListener. We should skip these duplicate
    //   navs. Duplicates may also be triggered by attempts to sync AngularJS and Angular router
    //   states.
    // * Imperative navigations can be cancelled by router guards, meaning the URL won't change. If
    //   the user follows that with a navigation using the back/forward button or manual URL change,
    //   the destination may be the same as the previous imperative attempt. We should not skip
    //   these navigations because it's a separate case from the one above -- it's not a duplicate
    //   navigation.
    const lastNavigation = this.getTransition();
    // We don't want to skip duplicate successful navs if they're imperative because
    // onSameUrlNavigation could be 'reload' (so the duplicate is intended).
    const browserNavPrecededByRouterNav = isBrowserTriggeredNavigation(source) && lastNavigation &&
        !isBrowserTriggeredNavigation(lastNavigation.source);
    const lastNavigationSucceeded = this.lastSuccessfulId === lastNavigation.id;
    // If the last navigation succeeded or is in flight, we can use the rawUrl as the comparison.
    // However, if it failed, we should compare to the final result (urlAfterRedirects).
    const lastNavigationUrl = (lastNavigationSucceeded || this.currentNavigation) ?
        lastNavigation.rawUrl :
        lastNavigation.urlAfterRedirects;
    const duplicateNav = lastNavigationUrl.toString() === rawUrl.toString();
    if (browserNavPrecededByRouterNav && duplicateNav) {
      return Promise.resolve(true);  // return value is not used
    }

    let resolve: any;
    let reject: any;
    let promise: Promise<boolean>;
    if (priorPromise) {
      resolve = priorPromise.resolve;
      reject = priorPromise.reject;
      promise = priorPromise.promise;

    } else {
      promise = new Promise<boolean>((res, rej) => {
        resolve = res;
        reject = rej;
      });
    }

    const id = ++this.navigationId;
    let targetPageId: number;
    if (this.canceledNavigationResolution === 'computed') {
      const isInitialPage = this.currentPageId === 0;
      if (isInitialPage) {
        restoredState = this.location.getState() as RestoredState | null;
      }
      // If the `ɵrouterPageId` exist in the state then `targetpageId` should have the value of
      // `ɵrouterPageId`. This is the case for something like a page refresh where we assign the
      // target id to the previously set value for that page.
      if (restoredState && restoredState.ɵrouterPageId) {
        targetPageId = restoredState.ɵrouterPageId;
      } else {
        // If we're replacing the URL or doing a silent navigation, we do not want to increment the
        // page id because we aren't pushing a new entry to history.
        if (extras.replaceUrl || extras.skipLocationChange) {
          targetPageId = this.browserPageId ?? 0;
        } else {
          targetPageId = (this.browserPageId ?? 0) + 1;
        }
      }
    } else {
      // This is unused when `canceledNavigationResolution` is not computed.
      targetPageId = 0;
    }

    this.setTransition({
      id,
      targetPageId,
      source,
      restoredState,
      currentUrlTree: this.currentUrlTree,
      currentRawUrl: this.rawUrlTree,
      rawUrl,
      extras,
      resolve,
      reject,
      promise,
      currentSnapshot: this.routerState.snapshot,
      currentRouterState: this.routerState
    });

    // Make sure that the error is propagated even though `processNavigations` catch
    // handler does not rethrow
    return promise.catch((e: any) => {
      return Promise.reject(e);
    });
  }


private setBrowserUrl(url: UrlTree, t: NavigationTransition) {
    const path = this.urlSerializer.serialize(url);
    const state = {...t.extras.state, ...this.generateNgRouterState(t.id, t.targetPageId)};
    if (this.location.isCurrentPathEqualTo(path) || !!t.extras.replaceUrl) {
      this.location.replaceState(path, '', state);
    } else {
      this.location.go(path, '', state);
    }
  }


/**
   * Performs the necessary rollback action to restore the browser URL to the
   * state before the transition.
   */
private restoreHistory(t: NavigationTransition, restoringFromCaughtError = false) {
    if (this.canceledNavigationResolution === 'computed') {
      const targetPagePosition = this.currentPageId - t.targetPageId;
      // The navigator change the location before triggered the browser event,
      // so we need to go back to the current url if the navigation is canceled.
      // Also, when navigation gets cancelled while using url update strategy eager, then we need to
      // go back. Because, when `urlUpdateSrategy` is `eager`; `setBrowserUrl` method is called
      // before any verification.
      const browserUrlUpdateOccurred =
          (t.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
           this.currentUrlTree === this.currentNavigation?.finalUrl);
      if (browserUrlUpdateOccurred && targetPagePosition !== 0) {
        this.location.historyGo(targetPagePosition);
      } else if (
          this.currentUrlTree === this.currentNavigation?.finalUrl && targetPagePosition === 0) {
        // We got to the activation stage (where currentUrlTree is set to the navigation's
        // finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
        // We still need to reset the router state back to what it was when the navigation started.
        this.resetState(t);
        // TODO(atscott): resetting the `browserUrlTree` should really be done in `resetState`.
        // Investigate if this can be done by running TGP.
        this.browserUrlTree = t.currentUrlTree;
        this.resetUrlToCurrentUrlTree();
      } else {
        // The browser URL and router state was not updated before the navigation cancelled so
        // there's no restoration needed.
      }
    } else if (this.canceledNavigationResolution === 'replace') {
      // TODO(atscott): It seems like we should _always_ reset the state here. It would be a no-op
      // for `deferred` navigations that haven't change the internal state yet because guards
      // reject. For 'eager' navigations, it seems like we also really should reset the state
      // because the navigation was cancelled. Investigate if this can be done by running TGP.
      if (restoringFromCaughtError) {
        this.resetState(t);
      }
      this.resetUrlToCurrentUrlTree();
    }
  }


private resetState(t: NavigationTransition): void {
    (this as {routerState: RouterState}).routerState = t.currentRouterState;
    this.currentUrlTree = t.currentUrlTree;
    // Note here that we use the urlHandlingStrategy to get the reset `rawUrlTree` because it may be
    // configured to handle only part of the navigation URL. This means we would only want to reset
    // the part of the navigation handled by the Angular router rather than the whole URL. In
    // addition, the URLHandlingStrategy may be configured to specifically preserve parts of the URL
    // when merging, such as the query params so they are not lost on a refresh.
    this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
  }


private resetUrlToCurrentUrlTree(): void {
    this.location.replaceState(
        this.urlSerializer.serialize(this.rawUrlTree), '',
        this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
  }


private cancelNavigationTransition(t: NavigationTransition, reason: string) {
    const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason);
    this.triggerEvent(navCancel);
    t.resolve(false);
  }


private generateNgRouterState(navigationId: number, routerPageId?: number) {
    if (this.canceledNavigationResolution === 'computed') {
      return {navigationId, ɵrouterPageId: routerPageId};
    }
    return {navigationId};
  }


<P extends InjectedProjectProps>(
  WrappedComponent: React.ComponentType<P>
) =>
  class extends React.Component<
    Omit<P, keyof InjectedProjectProps> & Partial<InjectedProjectProps>
  > {
    static displayName = `withProject(${getDisplayName(WrappedComponent)})`;
    static contextTypes = {
      project: SentryTypes.Project,
    };

    render() {
      return (
        <WrappedComponent
          project={this.context.project as Project}
          {...(this.props as P)}
        />


type InjectedProjectProps = {
  project: Project;
};


render() {
      return (
        <WrappedComponent
          project={this.context.project as Project}
          {...(this.props as P)}
        />


/** Methods to use when ordering `Hero`. */
export enum HeroesOrderBy {
  Natural = 'NATURAL',
  IdAsc = 'ID_ASC',
  IdDesc = 'ID_DESC',
  NameAsc = 'NAME_ASC',
  NameDesc = 'NAME_DESC',
  PrimaryKeyAsc = 'PRIMARY_KEY_ASC',
  PrimaryKeyDesc = 'PRIMARY_KEY_DESC'
}


/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
  /** A location in a connection that can be used for resuming pagination. */
  Cursor: any;
};


/** All input for the create `Hero` mutation. */
export type CreateHeroInput = {
  /**
   * An arbitrary string value with no semantic meaning. Will be included in the
   * payload verbatim. May be used to track mutations by the client.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The `Hero` to be created by this mutation. */
  hero: HeroInput;
};


/** The output of our create `Hero` mutation. */
export type CreateHeroPayload = {
   __typename?: 'CreateHeroPayload';
  /**
   * The exact same `clientMutationId` that was provided in the mutation input,
   * unchanged and unused. May be used by a client to track mutations.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The `Hero` that was created by this mutation. */
  hero?: Maybe<Hero>;
  /** Our root query field type. Allows us to run any query from our mutation payload. */
  query?: Maybe<Query>;
  /** An edge for our `Hero`. May be used by Relay 1. */
  heroEdge?: Maybe<HeroesEdge>;
};


/** The output of our create `Hero` mutation. */
export type CreateHeroPayloadHeroEdgeArgs = {
  orderBy?: Maybe<Array<HeroesOrderBy>>;
};


/** All input for the `deleteHeroById` mutation. */
export type DeleteHeroByIdInput = {
  /**
   * An arbitrary string value with no semantic meaning. Will be included in the
   * payload verbatim. May be used to track mutations by the client.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  id: Scalars['Int'];
};


/** All input for the `deleteHero` mutation. */
export type DeleteHeroInput = {
  /**
   * An arbitrary string value with no semantic meaning. Will be included in the
   * payload verbatim. May be used to track mutations by the client.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The globally unique `ID` which will identify a single `Hero` to be deleted. */
  nodeId: Scalars['ID'];
};


/** The output of our delete `Hero` mutation. */
export type DeleteHeroPayload = {
   __typename?: 'DeleteHeroPayload';
  /**
   * The exact same `clientMutationId` that was provided in the mutation input,
   * unchanged and unused. May be used by a client to track mutations.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The `Hero` that was deleted by this mutation. */
  hero?: Maybe<Hero>;
  deletedHeroId?: Maybe<Scalars['ID']>;
  /** Our root query field type. Allows us to run any query from our mutation payload. */
  query?: Maybe<Query>;
  /** An edge for our `Hero`. May be used by Relay 1. */
  heroEdge?: Maybe<HeroesEdge>;
};


/** The output of our delete `Hero` mutation. */
export type DeleteHeroPayloadHeroEdgeArgs = {
  orderBy?: Maybe<Array<HeroesOrderBy>>;
};


export type Hero = Node & {
   __typename?: 'Hero';
  /** A globally unique identifier. Can be used in various places throughout the system to identify this single value. */
  nodeId: Scalars['ID'];
  id: Scalars['Int'];
  name: Scalars['String'];
};


/** A condition to be used against `Hero` object types. All fields are tested for equality and combined with a logical ‘and.’ */
export type HeroCondition = {
  /** Checks for equality with the object’s `id` field. */
  id?: Maybe<Scalars['Int']>;
  /** Checks for equality with the object’s `name` field. */
  name?: Maybe<Scalars['String']>;
};


/** A connection to a list of `Hero` values. */
export type HeroesConnection = {
   __typename?: 'HeroesConnection';
  /** A list of `Hero` objects. */
  nodes: Array<Maybe<Hero>>;
  /** A list of edges which contains the `Hero` and cursor to aid in pagination. */
  edges: Array<HeroesEdge>;
  /** Information to aid in pagination. */
  pageInfo: PageInfo;
  /** The count of *all* `Hero` you could get from the connection. */
  totalCount: Scalars['Int'];
};


/** A `Hero` edge in the connection. */
export type HeroesEdge = {
   __typename?: 'HeroesEdge';
  /** A cursor for use in pagination. */
  cursor?: Maybe<Scalars['Cursor']>;
  /** The `Hero` at the end of the edge. */
  node?: Maybe<Hero>;
};


/** An input for mutations affecting `Hero` */
export type HeroInput = {
  id?: Maybe<Scalars['Int']>;
  name: Scalars['String'];
};


/** Represents an update to a `Hero`. Fields that are set will be updated. */
export type HeroPatch = {
  id?: Maybe<Scalars['Int']>;
  name?: Maybe<Scalars['String']>;
};


/** The root mutation type which contains root level fields which mutate data. */
export type Mutation = {
   __typename?: 'Mutation';
  /** Creates a single `Hero`. */
  createHero?: Maybe<CreateHeroPayload>;
  /** Updates a single `Hero` using its globally unique id and a patch. */
  updateHero?: Maybe<UpdateHeroPayload>;
  /** Updates a single `Hero` using a unique key and a patch. */
  updateHeroById?: Maybe<UpdateHeroPayload>;
  /** Deletes a single `Hero` using its globally unique id. */
  deleteHero?: Maybe<DeleteHeroPayload>;
  /** Deletes a single `Hero` using a unique key. */
  deleteHeroById?: Maybe<DeleteHeroPayload>;
};


/** The root mutation type which contains root level fields which mutate data. */
export type MutationCreateHeroArgs = {
  input: CreateHeroInput;
};


/** The root mutation type which contains root level fields which mutate data. */
export type MutationUpdateHeroArgs = {
  input: UpdateHeroInput;
};


/** The root mutation type which contains root level fields which mutate data. */
export type MutationUpdateHeroByIdArgs = {
  input: UpdateHeroByIdInput;
};


/** The root mutation type which contains root level fields which mutate data. */
export type MutationDeleteHeroArgs = {
  input: DeleteHeroInput;
};


/** The root mutation type which contains root level fields which mutate data. */
export type MutationDeleteHeroByIdArgs = {
  input: DeleteHeroByIdInput;
};


/** An object with a globally unique `ID`. */
export type Node = {
  /** A globally unique identifier. Can be used in various places throughout the system to identify this single value. */
  nodeId: Scalars['ID'];
};


/** Information about pagination in a connection. */
export type PageInfo = {
   __typename?: 'PageInfo';
  /** When paginating forwards, are there more items? */
  hasNextPage: Scalars['Boolean'];
  /** When paginating backwards, are there more items? */
  hasPreviousPage: Scalars['Boolean'];
  /** When paginating backwards, the cursor to continue. */
  startCursor?: Maybe<Scalars['Cursor']>;
  /** When paginating forwards, the cursor to continue. */
  endCursor?: Maybe<Scalars['Cursor']>;
};


/** The root query type which gives access points into the data universe. */
export type Query = Node & {
   __typename?: 'Query';
  /**
   * Exposes the root query type nested one level down. This is helpful for Relay 1
   * which can only query top level fields if they are in a particular form.
   */
  query: Query;
  /** The root query type must be a `Node` to work well with Relay 1 mutations. This just resolves to `query`. */
  nodeId: Scalars['ID'];
  /** Fetches an object given its globally unique `ID`. */
  node?: Maybe<Node>;
  /** Reads and enables pagination through a set of `Hero`. */
  allHeroes?: Maybe<HeroesConnection>;
  heroById?: Maybe<Hero>;
  /** Reads and enables pagination through a set of `Hero`. */
  herowithterm: HeroesConnection;
  /** Reads a single `Hero` using its globally unique `ID`. */
  hero?: Maybe<Hero>;
};


/** The root query type which gives access points into the data universe. */
export type QueryNodeArgs = {
  nodeId: Scalars['ID'];
};


/** The root query type which gives access points into the data universe. */
export type QueryAllHeroesArgs = {
  first?: Maybe<Scalars['Int']>;
  last?: Maybe<Scalars['Int']>;
  offset?: Maybe<Scalars['Int']>;
  before?: Maybe<Scalars['Cursor']>;
  after?: Maybe<Scalars['Cursor']>;
  orderBy?: Maybe<Array<HeroesOrderBy>>;
  condition?: Maybe<HeroCondition>;
};


/** The root query type which gives access points into the data universe. */
export type QueryHeroByIdArgs = {
  id: Scalars['Int'];
};


/** The root query type which gives access points into the data universe. */
export type QueryHerowithtermArgs = {
  term?: Maybe<Scalars['String']>;
  first?: Maybe<Scalars['Int']>;
  last?: Maybe<Scalars['Int']>;
  offset?: Maybe<Scalars['Int']>;
  before?: Maybe<Scalars['Cursor']>;
  after?: Maybe<Scalars['Cursor']>;
};


/** The root query type which gives access points into the data universe. */
export type QueryHeroArgs = {
  nodeId: Scalars['ID'];
};


/** All input for the `updateHeroById` mutation. */
export type UpdateHeroByIdInput = {
  /**
   * An arbitrary string value with no semantic meaning. Will be included in the
   * payload verbatim. May be used to track mutations by the client.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** An object where the defined keys will be set on the `Hero` being updated. */
  heroPatch: HeroPatch;
  id: Scalars['Int'];
};


/** All input for the `updateHero` mutation. */
export type UpdateHeroInput = {
  /**
   * An arbitrary string value with no semantic meaning. Will be included in the
   * payload verbatim. May be used to track mutations by the client.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The globally unique `ID` which will identify a single `Hero` to be updated. */
  nodeId: Scalars['ID'];
  /** An object where the defined keys will be set on the `Hero` being updated. */
  heroPatch: HeroPatch;
};


/** The output of our update `Hero` mutation. */
export type UpdateHeroPayload = {
   __typename?: 'UpdateHeroPayload';
  /**
   * The exact same `clientMutationId` that was provided in the mutation input,
   * unchanged and unused. May be used by a client to track mutations.
   */
  clientMutationId?: Maybe<Scalars['String']>;
  /** The `Hero` that was updated by this mutation. */
  hero?: Maybe<Hero>;
  /** Our root query field type. Allows us to run any query from our mutation payload. */
  query?: Maybe<Query>;
  /** An edge for our `Hero`. May be used by Relay 1. */
  heroEdge?: Maybe<HeroesEdge>;
};


/** The output of our update `Hero` mutation. */
export type UpdateHeroPayloadHeroEdgeArgs = {
  orderBy?: Maybe<Array<HeroesOrderBy>>;
};


({ navigation, color }: any) => {
    console.log(navigation);
    return (
        <TouchableOpacity
            onPress={()


async (chainId: number, address: string) => {
  const fullMatch = await fetch(
    `https://repo.sourcify.dev/contracts/full_match/${chainId}/${address}/metadata.json`
  )
    .then((r) => (r.ok ? r.json() : null))
    .catch((err) => {
      console.error(err);
      return null;
    });

  if (fullMatch) {
    return { metadata: fullMatch, partial: false };
  }
  const partialMatch = await fetch(
    `https://repo.sourcify.dev/contracts/partial_match/${chainId}/${address}/metadata.json`
  )
    .then((r) => (r.ok ? r.json() : null))
    .catch((err) => {
      console.error(err);
      return null;
    });
  return { metadata: partialMatch, partial: true };
}


(r) => (r.ok ? r.json() : null)


(err) => {
      console.error(err);
      return null;
    }


async (
  partial: boolean,
  chainId: number,
  address: string,
  metadata: Metadata
) => {
  const sourceFiles = Object.keys(metadata.sources);
  return Promise.all(
    sourceFiles.map(async (file) => {
      const sanitized = file.replace("@", "_");
      const content = await fetch(
        `https://repo.sourcify.dev/contracts/${
          partial ? "partial" : "full"
        }_match/${chainId}/${address}/sources/${sanitized}`
      )
        .then((r) => (r.ok ? r.text() : null))
        .catch((err) => {
          console.error(err);
          return null;
        });

      return { file, content };
    })
  );
}


async (file) => {
      const sanitized = file.replace("@", "_");
      const content = await fetch(
        `https://repo.sourcify.dev/contracts/${
          partial ? "partial" : "full"
        }_match/${chainId}/${address}/sources/${sanitized}`
      )
        .then((r) => (r.ok ? r.text() : null))
        .catch((err) => {
          console.error(err);
          return null;
        });

      return { file, content };
    }


(r) => (r.ok ? r.text() : null)


(err) => {
          console.error(err);
          return null;
        }


export interface Metadata {
  compiler: {
    version: string;
  };
  language: string;
  output: any;
  settings: {
    optimizer: {
      enabled: boolean;
      runs: number;
    };
  };
  sources: Record<
    string,
    {
      keccak256: string;
      license: string;
      urls: string[];
    }
  >;
}


export interface Source {
  file: string;
  content: string;
}


export class CreateServerRequest extends jspb.Message {
  getOwnerId(): number;
  setOwnerId(value: number): void;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): CreateServerRequest.AsObject;
  static toObject(includeInstance: boolean, msg: CreateServerRequest): CreateServerRequest.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: CreateServerRequest, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): CreateServerRequest;
  static deserializeBinaryFromReader(message: CreateServerRequest, reader: jspb.BinaryReader): CreateServerRequest;
}


export class CreateServerResponse extends jspb.Message {
  getId(): number;
  setId(value: number): void;

  getPort(): number;
  setPort(value: number): void;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): CreateServerResponse.AsObject;
  static toObject(includeInstance: boolean, msg: CreateServerResponse): CreateServerResponse.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: CreateServerResponse, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): CreateServerResponse;
  static deserializeBinaryFromReader(message: CreateServerResponse, reader: jspb.BinaryReader): CreateServerResponse;
}


export class GetServersRequest extends jspb.Message {
  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): GetServersRequest.AsObject;
  static toObject(includeInstance: boolean, msg: GetServersRequest): GetServersRequest.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: GetServersRequest, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): GetServersRequest;
  static deserializeBinaryFromReader(message: GetServersRequest, reader: jspb.BinaryReader): GetServersRequest;
}


export class GetServersResponse extends jspb.Message {
  clearIdList(): void;
  getIdList(): Array<number>;
  setIdList(value: Array<number>): void;
  addId(value: number, index?: number): number;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): GetServersResponse.AsObject;
  static toObject(includeInstance: boolean, msg: GetServersResponse): GetServersResponse.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: GetServersResponse, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): GetServersResponse;
  static deserializeBinaryFromReader(message: GetServersResponse, reader: jspb.BinaryReader): GetServersResponse;
}


export class MyServerRequest extends jspb.Message {
  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): MyServerRequest.AsObject;
  static toObject(includeInstance: boolean, msg: MyServerRequest): MyServerRequest.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: MyServerRequest, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): MyServerRequest;
  static deserializeBinaryFromReader(message: MyServerRequest, reader: jspb.BinaryReader): MyServerRequest;
}


export class MyServerResponse extends jspb.Message {
  getId(): number;
  setId(value: number): void;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): MyServerResponse.AsObject;
  static toObject(includeInstance: boolean, msg: MyServerResponse): MyServerResponse.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: MyServerResponse, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): MyServerResponse;
  static deserializeBinaryFromReader(message: MyServerResponse, reader: jspb.BinaryReader): MyServerResponse;
}


export class TransferOwnershipRequest extends jspb.Message {
  getServerId(): number;
  setServerId(value: number): void;

  getOwnerId(): number;
  setOwnerId(value: number): void;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): TransferOwnershipRequest.AsObject;
  static toObject(includeInstance: boolean, msg: TransferOwnershipRequest): TransferOwnershipRequest.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: TransferOwnershipRequest, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): TransferOwnershipRequest;
  static deserializeBinaryFromReader(message: TransferOwnershipRequest, reader: jspb.BinaryReader): TransferOwnershipRequest;
}


export class TransferOwnershipResponse extends jspb.Message {
  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): TransferOwnershipResponse.AsObject;
  static toObject(includeInstance: boolean, msg: TransferOwnershipResponse): TransferOwnershipResponse.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: TransferOwnershipResponse, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): TransferOwnershipResponse;
  static deserializeBinaryFromReader(message: TransferOwnershipResponse, reader: jspb.BinaryReader): TransferOwnershipResponse;
}


export class DeleteServerRequest extends jspb.Message {
  getId(): number;
  setId(value: number): void;

  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): DeleteServerRequest.AsObject;
  static toObject(includeInstance: boolean, msg: DeleteServerRequest): DeleteServerRequest.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: DeleteServerRequest, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): DeleteServerRequest;
  static deserializeBinaryFromReader(message: DeleteServerRequest, reader: jspb.BinaryReader): DeleteServerRequest;
}


export class DeleteServerResponse extends jspb.Message {
  serializeBinary(): Uint8Array;
  toObject(includeInstance?: boolean): DeleteServerResponse.AsObject;
  static toObject(includeInstance: boolean, msg: DeleteServerResponse): DeleteServerResponse.AsObject;
  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
  static serializeBinaryToWriter(message: DeleteServerResponse, writer: jspb.BinaryWriter): void;
  static deserializeBinary(bytes: Uint8Array): DeleteServerResponse;
  static deserializeBinaryFromReader(message: DeleteServerResponse, reader: jspb.BinaryReader): DeleteServerResponse;
}


export type AsObject = {
    ownerId: number,
  }


export type AsObject = {
    id: number,
    port: number,
  }


export type AsObject = {
  }


export type AsObject = {
    idList: Array<number>,
  }


export type AsObject = {
    id: number,
  }


export type AsObject = {
    serverId: number,
    ownerId: number,
  }


getOwnerId(): number;


setOwnerId(value: number): void;


toObject(includeInstance?: boolean): CreateServerRequest.AsObject;


static toObject(includeInstance: boolean, msg: CreateServerRequest): CreateServerRequest.AsObject;


static serializeBinaryToWriter(message: CreateServerRequest, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): CreateServerRequest;


static deserializeBinaryFromReader(message: CreateServerRequest, reader: jspb.BinaryReader): CreateServerRequest;


getId(): number;


setId(value: number): void;


getPort(): number;


setPort(value: number): void;


toObject(includeInstance?: boolean): CreateServerResponse.AsObject;


static toObject(includeInstance: boolean, msg: CreateServerResponse): CreateServerResponse.AsObject;


static serializeBinaryToWriter(message: CreateServerResponse, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): CreateServerResponse;


static deserializeBinaryFromReader(message: CreateServerResponse, reader: jspb.BinaryReader): CreateServerResponse;


toObject(includeInstance?: boolean): GetServersRequest.AsObject;


static toObject(includeInstance: boolean, msg: GetServersRequest): GetServersRequest.AsObject;


static serializeBinaryToWriter(message: GetServersRequest, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): GetServersRequest;


static deserializeBinaryFromReader(message: GetServersRequest, reader: jspb.BinaryReader): GetServersRequest;


clearIdList(): void;


getIdList(): Array<number>;


setIdList(value: Array<number>): void;


addId(value: number, index?: number): number;


toObject(includeInstance?: boolean): GetServersResponse.AsObject;


static toObject(includeInstance: boolean, msg: GetServersResponse): GetServersResponse.AsObject;


static serializeBinaryToWriter(message: GetServersResponse, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): GetServersResponse;


static deserializeBinaryFromReader(message: GetServersResponse, reader: jspb.BinaryReader): GetServersResponse;


toObject(includeInstance?: boolean): MyServerRequest.AsObject;


static toObject(includeInstance: boolean, msg: MyServerRequest): MyServerRequest.AsObject;


static serializeBinaryToWriter(message: MyServerRequest, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): MyServerRequest;


static deserializeBinaryFromReader(message: MyServerRequest, reader: jspb.BinaryReader): MyServerRequest;


toObject(includeInstance?: boolean): MyServerResponse.AsObject;


static toObject(includeInstance: boolean, msg: MyServerResponse): MyServerResponse.AsObject;


static serializeBinaryToWriter(message: MyServerResponse, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): MyServerResponse;


static deserializeBinaryFromReader(message: MyServerResponse, reader: jspb.BinaryReader): MyServerResponse;


getServerId(): number;


setServerId(value: number): void;


toObject(includeInstance?: boolean): TransferOwnershipRequest.AsObject;


static toObject(includeInstance: boolean, msg: TransferOwnershipRequest): TransferOwnershipRequest.AsObject;


static serializeBinaryToWriter(message: TransferOwnershipRequest, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): TransferOwnershipRequest;


static deserializeBinaryFromReader(message: TransferOwnershipRequest, reader: jspb.BinaryReader): TransferOwnershipRequest;


toObject(includeInstance?: boolean): TransferOwnershipResponse.AsObject;


static toObject(includeInstance: boolean, msg: TransferOwnershipResponse): TransferOwnershipResponse.AsObject;


static serializeBinaryToWriter(message: TransferOwnershipResponse, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): TransferOwnershipResponse;


static deserializeBinaryFromReader(message: TransferOwnershipResponse, reader: jspb.BinaryReader): TransferOwnershipResponse;


toObject(includeInstance?: boolean): DeleteServerRequest.AsObject;


static toObject(includeInstance: boolean, msg: DeleteServerRequest): DeleteServerRequest.AsObject;


static serializeBinaryToWriter(message: DeleteServerRequest, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): DeleteServerRequest;


static deserializeBinaryFromReader(message: DeleteServerRequest, reader: jspb.BinaryReader): DeleteServerRequest;


toObject(includeInstance?: boolean): DeleteServerResponse.AsObject;


static toObject(includeInstance: boolean, msg: DeleteServerResponse): DeleteServerResponse.AsObject;


static serializeBinaryToWriter(message: DeleteServerResponse, writer: jspb.BinaryWriter): void;


static deserializeBinary(bytes: Uint8Array): DeleteServerResponse;


static deserializeBinaryFromReader(message: DeleteServerResponse, reader: jspb.BinaryReader): DeleteServerResponse;


export class MasterChefJoeV3__factory extends ContractFactory {
  constructor(
    ...args: [signer: Signer] | ConstructorParameters<typeof ContractFactory>
  ) {
    if (args.length === 1) {
      super(_abi, _bytecode, args[0]);
    } else {
      super(...args);
    }
  }

  deploy(
    _MASTER_CHEF_V2: string,
    _joe: string,
    _MASTER_PID: BigNumberish,
    overrides?: Overrides & { from?: string | Promise<string> }
  ): Promise<MasterChefJoeV3> {
    return super.deploy(
      _MASTER_CHEF_V2,
      _joe,
      _MASTER_PID,
      overrides || {}
    ) as Promise<MasterChefJoeV3>;
  }
  getDeployTransaction(
    _MASTER_CHEF_V2: string,
    _joe: string,
    _MASTER_PID: BigNumberish,
    overrides?: Overrides & { from?: string | Promise<string> }
  ): TransactionRequest {
    return super.getDeployTransaction(
      _MASTER_CHEF_V2,
      _joe,
      _MASTER_PID,
      overrides || {}
    );
  }
  attach(address: string): MasterChefJoeV3 {
    return super.attach(address) as MasterChefJoeV3;
  }
  connect(signer: Signer): MasterChefJoeV3__factory {
    return super.connect(signer) as MasterChefJoeV3__factory;
  }
  static readonly bytecode = _bytecode;
  static readonly abi = _abi;
  static createInterface(): MasterChefJoeV3Interface {
    return new utils.Interface(_abi) as MasterChefJoeV3Interface;
  }
  static connect(
    address: string,
    signerOrProvider: Signer | Provider
  ): MasterChefJoeV3 {
    return new Contract(address, _abi, signerOrProvider) as MasterChefJoeV3;
  }
}


deploy(
    _MASTER_CHEF_V2: string,
    _joe: string,
    _MASTER_PID: BigNumberish,
    overrides?: Overrides & { from?: string | Promise<string> }
  ): Promise<MasterChefJoeV3> {
    return super.deploy(
      _MASTER_CHEF_V2,
      _joe,
      _MASTER_PID,
      overrides || {}
    ) as Promise<MasterChefJoeV3>;
  }


getDeployTransaction(
    _MASTER_CHEF_V2: string,
    _joe: string,
    _MASTER_PID: BigNumberish,
    overrides?: Overrides & { from?: string | Promise<string> }
  ): TransactionRequest {
    return super.getDeployTransaction(
      _MASTER_CHEF_V2,
      _joe,
      _MASTER_PID,
      overrides || {}
    );
  }


attach(address: string): MasterChefJoeV3 {
    return super.attach(address) as MasterChefJoeV3;
  }


connect(signer: Signer): MasterChefJoeV3__factory {
    return super.connect(signer) as MasterChefJoeV3__factory;
  }


static createInterface(): MasterChefJoeV3Interface {
    return new utils.Interface(_abi) as MasterChefJoeV3Interface;
  }


static connect(
    address: string,
    signerOrProvider: Signer | Provider
  ): MasterChefJoeV3 {
    return new Contract(address, _abi, signerOrProvider) as MasterChefJoeV3;
  }


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'ngxtend-fire-testing-demo';
}


(response: any) => {
          if (response) {
            const dataResponse = {
              token: response.access_token,
              userName: loginData.userName,
              refreshToken: response.refresh_token,
              useRefreshTokens: true,
              roles: response.roles.split(','),
              isFirstAccess: response.isFirstAccess,
              isFirstDayAccess: response.isFirstDayAccess,
              referralToken: response.referralToken
            };
            this.authentication = dataResponse;
            localStorage.setItem('authorizationData', JSON.stringify(dataResponse));
          }
        }


@Injectable({
  providedIn: 'root',
})
export class AuthService {
  baseApiUrl = environment.baseUrl + 'token';
  authentication = new Authentication();
  constructor(private http: HttpClient, private router: Router ) {
    this.authentication = JSON.parse(localStorage.getItem('authorizationData'));
  }

  logOut() {
    localStorage.setItem('authorizationData', JSON.stringify({}));
    this.authentication = new Authentication();
  }

  login(loginData) {
    const data = 'grant_type=password&username=' + encodeURIComponent(loginData.userName) +
      '&password=' + loginData.password +
      '&deviceToken=' + loginData.deviceToken +
      '&deviceModel=' + loginData.deviceModel +
      '&devicePlatform=' + loginData.devicePlatform +
      '&client_id=ionicApp';
    return this.http.post(this.baseApiUrl, data, { headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }) })
      .pipe(
        map((response: any) => {
          if (response) {
            const dataResponse = {
              token: response.access_token,
              userName: loginData.userName,
              refreshToken: response.refresh_token,
              useRefreshTokens: true,
              roles: response.roles.split(','),
              isFirstAccess: response.isFirstAccess,
              isFirstDayAccess: response.isFirstDayAccess,
              referralToken: response.referralToken
            };
            this.authentication = dataResponse;
            localStorage.setItem('authorizationData', JSON.stringify(dataResponse));
          }
        })
      );
  }

  isAuthenticated(){
    return this.authentication.token != null ;
  }
}


logOut() {
    localStorage.setItem('authorizationData', JSON.stringify({}));
    this.authentication = new Authentication();
  }


login(loginData) {
    const data = 'grant_type=password&username=' + encodeURIComponent(loginData.userName) +
      '&password=' + loginData.password +
      '&deviceToken=' + loginData.deviceToken +
      '&deviceModel=' + loginData.deviceModel +
      '&devicePlatform=' + loginData.devicePlatform +
      '&client_id=ionicApp';
    return this.http.post(this.baseApiUrl, data, { headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }) })
      .pipe(
        map((response: any) => {
          if (response) {
            const dataResponse = {
              token: response.access_token,
              userName: loginData.userName,
              refreshToken: response.refresh_token,
              useRefreshTokens: true,
              roles: response.roles.split(','),
              isFirstAccess: response.isFirstAccess,
              isFirstDayAccess: response.isFirstDayAccess,
              referralToken: response.referralToken
            };
            this.authentication = dataResponse;
            localStorage.setItem('authorizationData', JSON.stringify(dataResponse));
          }
        })
      );
  }


isAuthenticated(){
    return this.authentication.token != null ;
  }


() => {
	const [amountToBurn, onBurnChange] = useRecoilState(amountToBurnState);
	const [burnType, onBurnTypeChange] = useRecoilState(burnTypeState);

	const {
		useSynthsBalancesQuery,
		useETHBalanceQuery,
		useSynthetixTxn,
		useEVMTxn,
	} = useSynthetixQueries();

	const {
		percentageTargetCRatio,
		debtBalance,
		issuableSynths,
		targetCRatio,
		SNXRate,
		currentCRatio,
	} = useStakingCalculations();
	const walletAddress = useRecoilValue(walletAddressState);
	const delegateWallet = useRecoilValue(delegateWalletState);
	const { synthetixjs } = Connector.useContainer();
	const { t } = useTranslation();

	const [txModalOpen, setTxModalOpen] = useState<boolean>(false);
	const [gasPrice, setGasPrice] = useState<Wei>(wei(0));
	const [waitingPeriod, setWaitingPeriod] = useState(0);
	const [issuanceDelay, setIssuanceDelay] = useState(0);

	const synthsBalancesQuery = useSynthsBalancesQuery(delegateWallet?.address ?? walletAddress);
	const synthBalances =
		synthsBalancesQuery.isSuccess && synthsBalancesQuery.data != null
			? synthsBalancesQuery.data
			: null;

	const sUSDBalance = synthBalances?.balancesMap.sUSD
		? synthBalances.balancesMap.sUSD.balance
		: wei(0);

	const {
		needToBuy,
		debtBalanceWithBuffer,
		missingSUSDWithBuffer,
		quoteAmount,
		swapData,
	} = useClearDebtCalculations(debtBalance, sUSDBalance, walletAddress!);

	const ethBalanceQuery = useETHBalanceQuery(delegateWallet?.address ?? walletAddress);
	const ethBalance = ethBalanceQuery.data ?? wei(0);

	const amountToBurnBN = Wei.max(wei(0), parseSafeWei(amountToBurn, wei(0)));

	const isToTarget = burnType === BurnActionType.TARGET;

	const getMaxSecsLeftInWaitingPeriod = useCallback(async () => {
		const {
			contracts: { Exchanger },
			utils: { formatBytes32String },
		} = synthetixjs!;

		try {
			const maxSecsLeftInWaitingPeriod = await Exchanger.maxSecsLeftInWaitingPeriod(
				delegateWallet?.address ?? walletAddress,
				formatBytes32String('sUSD')
			);
			setWaitingPeriod(Number(maxSecsLeftInWaitingPeriod));
		} catch (e) {
			console.log(e);
		}
	}, [walletAddress, delegateWallet, synthetixjs]);

	const getIssuanceDelay = useCallback(async () => {
		const {
			contracts: { Issuer },
		} = synthetixjs!;
		try {
			const [canBurnSynths, lastIssueEvent, minimumStakeTime] = await Promise.all([
				Issuer.canBurnSynths(delegateWallet?.address ?? walletAddress),
				Issuer.lastIssueEvent(delegateWallet?.address ?? walletAddress),
				Issuer.minimumStakeTime(),
			]);

			if (Number(lastIssueEvent) && Number(minimumStakeTime)) {
				const burnUnlockDate = addSeconds(Number(lastIssueEvent) * 1000, Number(minimumStakeTime));
				const issuanceDelayInSeconds = differenceInSeconds(burnUnlockDate, new Date());
				setIssuanceDelay(
					issuanceDelayInSeconds > 0 ? issuanceDelayInSeconds : canBurnSynths ? 0 : 1
				);
			}
		} catch (e) {
			console.log(e);
		}
		// eslint-disable-next-line
	}, [walletAddress, debtBalance, delegateWallet, synthetixjs]);

	const burnCall: [string, any[]] = !!delegateWallet
		? isToTarget
			? ['burnSynthsToTargetOnBehalf', [delegateWallet.address]]
			: ['burnSynthsOnBehalf', [delegateWallet.address, amountToBurnBN.toBN()]]
		: isToTarget
		? ['burnSynthsToTarget', []]
		: ['burnSynths', [amountToBurnBN.toBN()]];

	const swapTxn = useEVMTxn(swapData, {
		onSuccess: () => txn.mutate(),
		enabled: true,
	});

	const txn = useSynthetixTxn(
		'Synthetix',
		burnCall[0],
		burnCall[1],
		{
			gasPrice: gasPrice.toBN(),
		},
		{
			enabled: burnType !== BurnActionType.CLEAR || !needToBuy || swapTxn.txnStatus === 'confirmed',
		}
	);

	useEffect(() => {
		if (swapTxn.txnStatus === 'prompting' || txn.txnStatus === 'prompting') setTxModalOpen(true);
	}, [txn, swapTxn.txnStatus]);

	useEffect(() => {
		getMaxSecsLeftInWaitingPeriod();
		getIssuanceDelay();
	}, [getMaxSecsLeftInWaitingPeriod, getIssuanceDelay]);

	const maxBurnAmount = debtBalance.gt(sUSDBalance) ? wei(sUSDBalance) : debtBalance;

	let error: string | null = null;

	if (debtBalance.eq(0)) error = t('staking.actions.burn.action.error.no-debt');
	else if (
		((!!amountToBurn && wei(amountToBurn).gt(sUSDBalance)) || maxBurnAmount.eq(0)) &&
		burnType !== BurnActionType.CLEAR
	)
		error = t('staking.actions.burn.action.error.insufficient');
	else if (burnType === BurnActionType.CLEAR && wei(quoteAmount).gt(ethBalance)) {
		error = t('staking.actions.burn.action.error.insufficient-eth-1inch');
	} else if (waitingPeriod) {
		error = t('staking.actions.burn.action.error.waiting-period', {
			date: toFutureDate(waitingPeriod),
		});
	} else if (issuanceDelay && burnType !== BurnActionType.TARGET) {
		error = t('staking.actions.burn.action.error.issuance-period', {
			date: toFutureDate(issuanceDelay),
		});
	}

	return {
		debtBalance,
		sUSDBalance,
		issuableSynths,
		onBurnChange,
		txn,
		burnType,
		needToBuy,
		amountToBurn,
		onBurnTypeChange,
		debtBalanceWithBuffer,
		swapTxn,
		quoteAmount,
		missingSUSDWithBuffer,
		percentageTargetCRatio,
		error,
		txModalOpen,
		setTxModalOpen,
		setGasPrice,
		isWalletConnected: !!walletAddress,
		targetCRatio,
		SNXRate,
		currentCRatio,
	};
}


async () => {
		const {
			contracts: { Exchanger },
			utils: { formatBytes32String },
		} = synthetixjs!;

		try {
			const maxSecsLeftInWaitingPeriod = await Exchanger.maxSecsLeftInWaitingPeriod(
				delegateWallet?.address ?? walletAddress,
				formatBytes32String('sUSD')
			);
			setWaitingPeriod(Number(maxSecsLeftInWaitingPeriod));
		} catch (e) {
			console.log(e);
		}
	}


async () => {
		const {
			contracts: { Issuer },
		} = synthetixjs!;
		try {
			const [canBurnSynths, lastIssueEvent, minimumStakeTime] = await Promise.all([
				Issuer.canBurnSynths(delegateWallet?.address ?? walletAddress),
				Issuer.lastIssueEvent(delegateWallet?.address ?? walletAddress),
				Issuer.minimumStakeTime(),
			]);

			if (Number(lastIssueEvent) && Number(minimumStakeTime)) {
				const burnUnlockDate = addSeconds(Number(lastIssueEvent) * 1000, Number(minimumStakeTime));
				const issuanceDelayInSeconds = differenceInSeconds(burnUnlockDate, new Date());
				setIssuanceDelay(
					issuanceDelayInSeconds > 0 ? issuanceDelayInSeconds : canBurnSynths ? 0 : 1
				);
			}
		} catch (e) {
			console.log(e);
		}
		// eslint-disable-next-line
	}


() => txn.mutate()


() => {
		if (swapTxn.txnStatus === 'prompting' || txn.txnStatus === 'prompting') setTxModalOpen(true);
	}


() => {
		getMaxSecsLeftInWaitingPeriod();
		getIssuanceDelay();
	}


@Component({
    selector: 'aio-lazy-ce',
    template: '',
})
export class LazyCustomElementComponent implements OnInit {
    @Input() selector = '';

    constructor(
        private elementRef: ElementRef,
        private elementsLoader: ElementsLoader,
        private logger: Logger,
    ) {}

    ngOnInit() {
        if (!this.selector || /[^\w-]/.test(this.selector)) {
            this.logger.error(new Error(`Invalid selector for 'aio-lazy-ce': ${this.selector}`));
            return;
        }

        this.elementRef.nativeElement.innerHTML = `<${this.selector}></${this.selector}>`;
        this.elementsLoader.loadCustomElement(this.selector);
    }
}


ngOnInit() {
        if (!this.selector || /[^\w-]/.test(this.selector)) {
            this.logger.error(new Error(`Invalid selector for 'aio-lazy-ce': ${this.selector}`));
            return;
        }

        this.elementRef.nativeElement.innerHTML = `<${this.selector}></${this.selector}>`;
        this.elementsLoader.loadCustomElement(this.selector);
    }


/**
 *  @description Creates a custom element class based on an Angular component.
 *
 * Builds a class that encapsulates the functionality of the provided component and
 * uses the configuration information to provide more context to the class.
 * Takes the component factory's inputs and outputs to convert them to the proper
 * custom element API and add hooks to input changes.
 *
 * The configuration's injector is the initial injector set on the class,
 * and used by default for each created instance.This behavior can be overridden with the
 * static property to affect all newly created instances, or as a constructor argument for
 * one-off creations.
 *
 * @param component The component to transform.
 * @param config A configuration that provides initialization information to the created class.
 * @returns The custom-element construction class, which can be registered with
 * a browser's `CustomElementRegistry`.
 *
 * @publicApi
 */
export function createCustomElement<P>(
    component: Type<any>, config: NgElementConfig): NgElementConstructor<P> {
  const inputs = getComponentInputs(component, config.injector);

  const strategyFactory =
      config.strategyFactory || new ComponentNgElementStrategyFactory(component, config.injector);

  const attributeToPropertyInputs = getDefaultAttributeToPropertyInputs(inputs);

  class NgElementImpl extends NgElement {
    // Work around a bug in closure typed optimizations(b/79557487) where it is not honoring static
    // field externs. So using quoted access to explicitly prevent renaming.
    static readonly['observedAttributes'] = Object.keys(attributeToPropertyInputs);

    constructor(injector?: Injector) {
      super();

      // Note that some polyfills (e.g. document-register-element) do not call the constructor.
      // Do not assume this strategy has been created.
      // TODO(andrewseguin): Add e2e tests that cover cases where the constructor isn't called. For
      // now this is tested using a Google internal test suite.
      this.ngElementStrategy = strategyFactory.create(injector || config.injector);
    }

    attributeChangedCallback(
        attrName: string, oldValue: string|null, newValue: string, namespace?: string): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      const propName = attributeToPropertyInputs[attrName] !;
      this.ngElementStrategy.setInputValue(propName, newValue);
    }

    connectedCallback(): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      this.ngElementStrategy.connect(this);

      // Listen for events from the strategy and dispatch them as custom events
      this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => {
        const customEvent = createCustomEvent(this.ownerDocument !, e.name, e.value);
        this.dispatchEvent(customEvent);
      });
    }

    disconnectedCallback(): void {
      if (this.ngElementStrategy) {
        this.ngElementStrategy.disconnect();
      }

      if (this.ngElementEventsSubscription) {
        this.ngElementEventsSubscription.unsubscribe();
        this.ngElementEventsSubscription = null;
      }
    }
  }

  // Add getters and setters to the prototype for each property input. If the config does not
  // contain property inputs, use all inputs by default.
  inputs.map(({propName}) => propName).forEach(property => {
    Object.defineProperty(NgElementImpl.prototype, property, {
      get: function() { return this.ngElementStrategy.getInputValue(property); },
      set: function(newValue: any) { this.ngElementStrategy.setInputValue(property, newValue); },
      configurable: true,
      enumerable: true,
    });
  });

  return (NgElementImpl as any) as NgElementConstructor<P>;
}


e => {
        const customEvent = createCustomEvent(this.ownerDocument !, e.name, e.value);
        this.dispatchEvent(customEvent);
      }


({propName}) => propName


property => {
    Object.defineProperty(NgElementImpl.prototype, property, {
      get: function() { return this.ngElementStrategy.getInputValue(property); },
      set: function(newValue: any) { this.ngElementStrategy.setInputValue(property, newValue); },
      configurable: true,
      enumerable: true,
    });
  }


/**
 * Implements the functionality needed for a custom element.
 *
 * @publicApi
 */
export abstract class NgElement extends HTMLElement {
  /**
   * The strategy that controls how a component is transformed in a custom element.
   */
  // TODO(issue/24571): remove '!'.
  protected ngElementStrategy !: NgElementStrategy;
  /**
   * A subscription to change, connect, and disconnect events in the custom element.
   */
  protected ngElementEventsSubscription: Subscription|null = null;

  /**
    * Prototype for a handler that responds to a change in an observed attribute.
    * @param attrName The name of the attribute that has changed.
    * @param oldValue The previous value of the attribute.
    * @param newValue The new value of the attribute.
    * @param namespace The namespace in which the attribute is defined.
    * @returns Nothing.
    */
  abstract attributeChangedCallback(
      attrName: string, oldValue: string|null, newValue: string, namespace?: string): void;
  /**
   * Prototype for a handler that responds to the insertion of the custom element in the DOM.
   * @returns Nothing.
   */
  abstract connectedCallback(): void;
  /**
   * Prototype for a handler that responds to the deletion of the custom element from the DOM.
   * @returns Nothing.
   */
  abstract disconnectedCallback(): void;
}


class NgElementImpl extends NgElement {
    // Work around a bug in closure typed optimizations(b/79557487) where it is not honoring static
    // field externs. So using quoted access to explicitly prevent renaming.
    static readonly['observedAttributes'] = Object.keys(attributeToPropertyInputs);

    constructor(injector?: Injector) {
      super();

      // Note that some polyfills (e.g. document-register-element) do not call the constructor.
      // Do not assume this strategy has been created.
      // TODO(andrewseguin): Add e2e tests that cover cases where the constructor isn't called. For
      // now this is tested using a Google internal test suite.
      this.ngElementStrategy = strategyFactory.create(injector || config.injector);
    }

    attributeChangedCallback(
        attrName: string, oldValue: string|null, newValue: string, namespace?: string): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      const propName = attributeToPropertyInputs[attrName] !;
      this.ngElementStrategy.setInputValue(propName, newValue);
    }

    connectedCallback(): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      this.ngElementStrategy.connect(this);

      // Listen for events from the strategy and dispatch them as custom events
      this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => {
        const customEvent = createCustomEvent(this.ownerDocument !, e.name, e.value);
        this.dispatchEvent(customEvent);
      });
    }

    disconnectedCallback(): void {
      if (this.ngElementStrategy) {
        this.ngElementStrategy.disconnect();
      }

      if (this.ngElementEventsSubscription) {
        this.ngElementEventsSubscription.unsubscribe();
        this.ngElementEventsSubscription = null;
      }
    }
  }


/**
 * Prototype for a class constructor based on an Angular component
 * that can be used for custom element registration. Implemented and returned
 * by the {@link createCustomElement createCustomElement() function}.
 *
 * @publicApi
 */
export interface NgElementConstructor<P> {
  /**
   * An array of observed attribute names for the custom element,
   * derived by transforming input property names from the source component.
   */
  readonly observedAttributes: string[];

  /**
   * Initializes a constructor instance.
   * @param injector If provided, overrides the configured injector.
   */
  new (injector?: Injector): NgElement&WithProperties<P>;
}


/**
 * A configuration that initializes an NgElementConstructor with the
 * dependencies and strategy it needs to transform a component into
 * a custom element class.
 *
 * @publicApi
 */
export interface NgElementConfig {
  /**
   * The injector to use for retrieving the component's factory.
   */
  injector: Injector;
  /**
   * An optional custom strategy factory to use instead of the default.
   * The strategy controls how the transformation is performed.
   */
  strategyFactory?: NgElementStrategyFactory;
}


/**
 * Additional type information that can be added to the NgElement class,
 * for properties that are added based
 * on the inputs and methods of the underlying component.
 *
 * @publicApi
 */
export type WithProperties<P> = {
  [property in keyof P]: P[property]
};


/**
    * Prototype for a handler that responds to a change in an observed attribute.
    * @param attrName The name of the attribute that has changed.
    * @param oldValue The previous value of the attribute.
    * @param newValue The new value of the attribute.
    * @param namespace The namespace in which the attribute is defined.
    * @returns Nothing.
    */
abstract attributeChangedCallback(
      attrName: string, oldValue: string|null, newValue: string, namespace?: string): void;


/**
   * Prototype for a handler that responds to the insertion of the custom element in the DOM.
   * @returns Nothing.
   */
abstract connectedCallback(): void;


/**
   * Prototype for a handler that responds to the deletion of the custom element from the DOM.
   * @returns Nothing.
   */
abstract disconnectedCallback(): void;


attributeChangedCallback(
        attrName: string, oldValue: string|null, newValue: string, namespace?: string): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      const propName = attributeToPropertyInputs[attrName] !;
      this.ngElementStrategy.setInputValue(propName, newValue);
    }


connectedCallback(): void {
      if (!this.ngElementStrategy) {
        this.ngElementStrategy = strategyFactory.create(config.injector);
      }

      this.ngElementStrategy.connect(this);

      // Listen for events from the strategy and dispatch them as custom events
      this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => {
        const customEvent = createCustomEvent(this.ownerDocument !, e.name, e.value);
        this.dispatchEvent(customEvent);
      });
    }


disconnectedCallback(): void {
      if (this.ngElementStrategy) {
        this.ngElementStrategy.disconnect();
      }

      if (this.ngElementEventsSubscription) {
        this.ngElementEventsSubscription.unsubscribe();
        this.ngElementEventsSubscription = null;
      }
    }


@Component({
  selector: 'modals',
  styles: [require('./modals.scss')],
  template: require('./modals.html')
})
export class Modals {
  @ViewChild('childModal') childModal: ModalDirective;

  showChildModal(): void {
    this.childModal.show();
  }

  hideChildModal(): void {
    this.childModal.hide();
  }
}


showChildModal(): void {
    this.childModal.show();
  }


hideChildModal(): void {
    this.childModal.hide();
  }


function Demo() {
  return (
    <Grid>
      <Col span={4}>1</Col>
      <Col span={4}>2</Col>
      <Col span={4}>3</Col>
    </Grid>
  );
}


async (req: Request) => {

  // Initializing Response:
  let response = initResponse(req);

  // Fetching Response Data:
  if(response.status === 'ok') {
    try {
      let wallet = req.query.address as Address;
      response.data.push(...(await getPoolBalances(wallet)));
    } catch(err: any) {
      console.error(err);
      response.status = 'error';
      response.data = [{error: 'Internal API Error'}];
    }
  }

  // Returning Response:
  return JSON.stringify(response, null, ' ');
}


async (wallet: Address) => {
  let balances: (Token | LPToken)[] = [];
  let poolCount = parseInt(await query(chain, masterChef, bouje.masterChefABI, 'poolLength', []));
  let poolList = [...Array(poolCount).keys()];
  let promises = poolList.map(poolID => (async () => {
    let balance = parseInt((await query(chain, masterChef, bouje.masterChefABI, 'userInfo', [poolID, wallet])).amount);
    if(balance > 0) {
      let token = (await query(chain, masterChef, bouje.masterChefABI, 'poolInfo', [poolID])).lpToken;
      let symbol = await query(chain, token, minABI, 'symbol', []);
      if(symbol === 'spLP') {
        let newToken = await addLPToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      } else {
        let newToken = await addToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      }
      let rewards = parseInt(await query(chain, masterChef, bouje.masterChefABI, 'pendingBastille', [poolID, wallet]));
      if(rewards > 0) {
        let newToken = await addToken(chain, project, 'unclaimed', bastille, rewards, wallet);
        balances.push(newToken);
      }
    }
  })());
  await Promise.all(promises);
  return balances;
}


poolID => (async () => {
    let balance = parseInt((await query(chain, masterChef, bouje.masterChefABI, 'userInfo', [poolID, wallet])).amount);
    if(balance > 0) {
      let token = (await query(chain, masterChef, bouje.masterChefABI, 'poolInfo', [poolID])).lpToken;
      let symbol = await query(chain, token, minABI, 'symbol', []);
      if(symbol === 'spLP') {
        let newToken = await addLPToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      } else {
        let newToken = await addToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      }
      let rewards = parseInt(await query(chain, masterChef, bouje.masterChefABI, 'pendingBastille', [poolID, wallet]));
      if(rewards > 0) {
        let newToken = await addToken(chain, project, 'unclaimed', bastille, rewards, wallet);
        balances.push(newToken);
      }
    }
  })()


async () => {
    let balance = parseInt((await query(chain, masterChef, bouje.masterChefABI, 'userInfo', [poolID, wallet])).amount);
    if(balance > 0) {
      let token = (await query(chain, masterChef, bouje.masterChefABI, 'poolInfo', [poolID])).lpToken;
      let symbol = await query(chain, token, minABI, 'symbol', []);
      if(symbol === 'spLP') {
        let newToken = await addLPToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      } else {
        let newToken = await addToken(chain, project, 'staked', token, balance, wallet);
        balances.push(newToken);
      }
      let rewards = parseInt(await query(chain, masterChef, bouje.masterChefABI, 'pendingBastille', [poolID, wallet]));
      if(rewards > 0) {
        let newToken = await addToken(chain, project, 'unclaimed', bastille, rewards, wallet);
        balances.push(newToken);
      }
    }
  }


//@ts-ignore
(item: keyof typeof variables) => variables[item] || item


failCase => !target.includes(failCase)


(cur: any) =>
        `${cur.sourceDescription} ${cur.fn ? cur.fnDescription : ''}`


(cur: any) =>
        `source:${cur.sourceDescription}${
          cur.fn ? `, fn:${cur.fnDescription}` : ''
        }`


fn({target}) {
      return target.map(
        //@ts-ignore
        (item: keyof typeof variables) => variables[item] || item,
      )
    }


fn({noFalsePositive, fn, target, source}) {
      if (noFalsePositive) return false
      if (fn) return failCases.ab.every(failCase => !target.includes(failCase))
      return failCases[source as keyof typeof failCases].every(
        failCase => !target.includes(failCase),
      )
    }


({ deselectElement, isWriteable }) => {
  const interactivePageLayout = useRef<CommitFn | null>(null); // future versions may enable editing on multiple pages => use array then

  const registerLayout = (newLayout: CommitFn) => {
    if (interactivePageLayout.current !== newLayout) {
      interactivePageLayout.current = newLayout;
    }
  };

  const unregisterLayout = (oldLayout: CommitFn) => {
    if (interactivePageLayout.current === oldLayout) {
      interactivePageLayout.current = null;
    }
  };

  const commit = interactivePageLayout.current || (() => {});

  return (

              <WorkpadHeader commit={commit} />

              {/* NOTE: canvasWorkpadContainer is used for exporting */}

                <Workpad registerLayout={registerLayout} unregisterLayout={unregisterLayout} />

          {isWriteable && (

              <Sidebar commit={commit} />


(newLayout: CommitFn) => {
    if (interactivePageLayout.current !== newLayout) {
      interactivePageLayout.current = newLayout;
    }
  }


(oldLayout: CommitFn) => {
    if (interactivePageLayout.current === oldLayout) {
      interactivePageLayout.current = null;
    }
  }


interface Props {
  deselectElement?: MouseEventHandler;
  isWriteable: boolean;
}


enter(path: Path): TransformExitResult {
    const {node} = path;

    if (node.type === 'BinaryExpression' && (node.operator === 'in' ||
            node.operator ===
            'instanceof') && node.left.type === 'UnaryExpression' &&
          node.left.operator ===
          '!') {
      return path.context.addFixableDiagnostic({
        old: node,
        fixed: unaryExpression.create({
          operator: node.left.operator,
          argument: {
            ...node,
            left: node.left.argument,
          },
        }),
      }, descriptions.LINT.UNSAFE_NEGATION);
    }

    return node;
  }


async connection => {

    const app = express();
    app.use(express.json());
    app.use(cors());
    app.use(morgan('dev'));

    // prettier-ignore
    const registerRoute = (route: IRoute) => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: NextFunction) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        });
    }

    Routes.forEach(registerRoute)
    app.listen(8000);

    console.log("The server has started on the port 8000.");

}


(route: IRoute) => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: NextFunction) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        });
    }


(req: Request, res: Response, next: NextFunction) => {
            const result = (new (route.controller as any))[route.action](req, res, next);
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

            } else if (result !== null && result !== undefined) {
                res.json(result);
            }
        }


result => result !== null && result !== undefined ? res.send(result) : undefined


interface Request {
      authenticatedUser?: { id: number }
    }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let resyncTx = Container.get(ResyncTx);
          const data = await resyncTx.run({txid: Req.params.txid});
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let syncTxStatus = Container.get(SyncTxStatus);
          let data = await syncTxStatus.run({ txid: Req.params.txid });
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          if (error instanceof TransactionStillProcessingError) {
            sendResponseWrapper(Req, res, 202, {});
            return;
          }
          if (error instanceof ResourceNotFoundError) {
            sendErrorWrapper(res, 404, error.toString());
            return;
          }
          if (error instanceof TransactionDataMissingError) {
            sendErrorWrapper(res, 422, error.toString());
            return;
          }
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let getTxsForSync = Container.get(GetTxsForSync);
          let data = await getTxsForSync.run();
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let getTx = Container.get(GetTx);
          let data = await getTx.run({ txid: Req.params.txid, channel: null, rawtx: Req.query.rawtx === '0' ? false : true });
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          if (error instanceof ResourceNotFoundError) {
            sendErrorWrapper(res, 404, error.toString());
            return;
          }
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let getTx = Container.get(GetTx);
          let data = await getTx.run({ txid: Req.params.txid, channel: Req.params.channel, rawtx: Req.query.rawtx === '0' ? false : true });
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          if (error instanceof ResourceNotFoundError) {
            sendErrorWrapper(res, 404, error.toString());
            return;
          }
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let getTx = Container.get(GetTx);
          let data = await getTx.run({ txid: Req.params.txid, rawtx: Req.query.rawtx === '0' ? false : true });
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          if (error instanceof ResourceNotFoundError) {
            sendErrorWrapper(res, 404, error.toString());
            return;
          }
          next(error);
        }
      }


async (Req: Request, res: Response, next: NextFunction) => {
        try {
          let saveTxs = Container.get(SaveTxs);
          let data = await saveTxs.run({
            channel: Req.body.channel,
            set: Req.body.set
          });
          sendResponseWrapper(Req, res, 200, data.result);
        } catch (error) {
          if (error instanceof TxhashMismatchError || error instanceof InvalidParamError) {
            sendErrorWrapper(res, 422, error.toString());
            return;
          }
          next(error);
        }
      }


function buildEventsWithoutIds(): EventInput[] {
    return [
      { title: 'event zero', start: '2014-06-24', className: 'event-zero' },
      { title: 'event one', start: '2014-06-24', className: 'event-non-zero event-one' },
      { title: 'event two', start: '2014-06-24', className: 'event-non-zero event-two' },
    ]
  }


function buildEventsWithIds() {
    let events = buildEventsWithoutIds()
    let i

    for (i = 0; i < events.length; i += 1) {
      events[i].id = i
    }

    return events
  }


// Verifies the actions in removeFunc executed correctly by calling checkFunc.
function go(events, removeFunc, checkFunc, doneFunc) {
    initCalendar({
      events,
    })

    checkAllEvents() // make sure all events initially rendered correctly
    removeFunc() // remove the events
    setTimeout(() => { // because the event rerender will be queued because we're a level deep
      checkFunc() // check correctness

      // move the calendar back out of view, then back in
      currentCalendar.next()
      currentCalendar.prev()

      // array event sources should maintain the same state
      // whereas "dynamic" event sources should refetch and reset the state
      if ($.isArray(events)) {
        checkFunc() // for issue 2187
      } else {
        checkAllEvents()
      }

      doneFunc()
    }, 0)
  }