export interface IESPNSchedule {
    events: Array<IESPNPastEvent>;
    requestedSeason: {
        year: number;
        type: number;
        name: string;
        displayName: string;
    };
    season: {
        year: number;
        type: number;
        name: string;
        displayName: string;
    };
    status: string;
    team: {
        abbreviation: string;
        clubhouse: string;
        color: string;
        displayName: string;
        groups: {
            id: string;
            parent: {
                id: string;
            };
            isConference: boolean;
        };
        id: string;
        location: string;
        logo: string;
        name: string;
        recordSummary: string;
        seasonSummary: string;
        standingSummary: string;
        venueLink: string;
    };
    timestamp: string;
}


/**
 * Injectable
 */
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
  /**
   * Creates an instance of jwt strategy.
   */
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: true,
      secretOrKey: 'super-secret-cat',
    });
  }

  /**
   * Validates jwt strategy
   * @param payload
   * @returns
   */
  async validate(payload: any) {
    console.log('validate()', payload);
    return payload;
  }
}


/**
   * Validates jwt strategy
   * @param payload
   * @returns
   */
async validate(payload: any) {
    console.log('validate()', payload);
    return payload;
  }


({
  schedules,
  getSchedulesError,
  isLoading,
  getSchedules,
}) => {
  const nextScheduleIndex = useMemo(() => {
    let index = -1;
    if (
      !schedules.some((schedule, i) => {
        if (isNotStartedSchedule(schedule)) {
          index = i;
          return true;
        }
      })
    ) {
      index = 4;
    }
    return index;
  }, [schedules]);

  useEffect(() => {
    getSchedules();
  }, []);

  useEffect(() => {
    alert('오픈 기간이 아닙니다.');
    window.history.back();
    window.location.href = 'https://www.google.com/';
    if (getSchedulesError.status) {
      // alert(`Error code: ${getSchedulesError.status} 일정 불러오기 실패!`);
    }
  }, [getSchedulesError]);

  return (
    <S.MainWrapper>
      <div>
        <S.LeftBackgroundImage />
        <S.MainContainer>
          <S.ContentBlock>
            <ContentHeader
              padding='160px 0 220px'
              subTitle='대덕소프트웨어마이스터고등학교'
              title='2021 신입생 모집'
              underLineLength={315}
              titleFontSize={46}
            />
            {!!schedules.length ? (
              isNotStartedSchedule(schedules[0]) ? (
                <Explain schedule={schedules[0]} isProgressing={false} />


() => {
    let index = -1;
    if (
      !schedules.some((schedule, i) => {
        if (isNotStartedSchedule(schedule)) {
          index = i;
          return true;
        }
      })
    ) {
      index = 4;
    }
    return index;
  }


(schedule, i) => {
        if (isNotStartedSchedule(schedule)) {
          index = i;
          return true;
        }
      }


() => {
    getSchedules();
  }


() => {
    alert('오픈 기간이 아닙니다.');
    window.history.back();
    window.location.href = 'https://www.google.com/';
    if (getSchedulesError.status) {
      // alert(`Error code: ${getSchedulesError.status} 일정 불러오기 실패!`);
    }
  }


interface Props {
  schedules: Schedule[];
  getSchedulesError: ErrorType;
  isLoading: boolean;
  getSchedules: () => void;
}


({timestamp, ...data}) => {
      return {
        id: recipientId,
        time: timestamp,
        messaging: [
          {
            timestamp,
            sender: {id: senderId},
            recipient: {id: recipientId},
            ...data,
          },
        ],
      } as EventEntry
    }


export class EventBuilder extends Builder<WebhookEvent, EventBuilderData> {
  from(senderId: string) {
    return this.clone({senderId})
  }

  to(recipientId: string) {
    return this.clone({recipientId})
  }

  at(timestamp: number) {
    return this.clone({timestamp})
  }

  postback(title: string, payload?: string) {
    const mid = `m-${nextFakeMessageId++}`
    const item = {timestamp: this.data.timestamp, postback: {mid, title, payload: payload || title}}
    return this.clone({items: [...this.data.items, item]})
  }

  accountLinked(authorizationCode: string) {
    const item: AccountLinkingItem = {
      timestamp: this.data.timestamp,
      account_linking: {status: 'linked', authorization_code: authorizationCode},
    }
    return this.clone({items: [...this.data.items, item]})
  }

  text(content: string) {
    return this.message({text: content})
  }

  quickReply(text: string, payload?: string) {
    return this.message({text, quick_reply: {payload: payload || text}})
  }

  replyTo(id: string, text: string) {
    return this.message({text, reply_to: {mid: id}})
  }

  image(url: string) {
    return this.attachment({type: 'image', payload: {url}})
  }

  audio(url: string) {
    return this.attachment({type: 'audio', payload: {url}})
  }

  video(url: string) {
    return this.attachment({type: 'video', payload: {url}})
  }

  file(url: string) {
    return this.attachment({type: 'file', payload: {url}})
  }

  location(lat: number, long: number, url: string) {
    return this.attachment({type: 'location', payload: {url, coordinates: {lat, long}}})
  }

  protected validate() {
    const {recipientId, senderId, items} = this.data
    if (recipientId === undefined)
      throw `The recipient is missing, use .to(recipientId) to set the recipient`
    if (senderId === undefined) throw `The sender is missing, use .from(senderId) to set the sender`
    if (items.length === 0) throw `The message to send with the event is missing`
  }

  protected build() {
    const {recipientId, senderId, items} = this.data
    const entry = items.map(({timestamp, ...data}) => {
      return {
        id: recipientId,
        time: timestamp,
        messaging: [
          {
            timestamp,
            sender: {id: senderId},
            recipient: {id: recipientId},
            ...data,
          },
        ],
      } as EventEntry
    })
    return {object: 'page', entry} as WebhookEvent
  }

  private message(data: Omit<MessageEvent, 'mid'>) {
    const mid = `m-${nextFakeMessageId++}`
    const item = {timestamp: this.data.timestamp, message: {mid, ...data}}
    return this.clone({items: [...this.data.items, item]})
  }

  private attachment(data: EventAttachment) {
    return this.message({attachments: [data]})
  }
}


export type EventBuilderData = {
  senderId?: string
  recipientId?: string
  timestamp: number
  items: Array<MessageItem | PostbackItem | AccountLinkingItem>
}


type MessageItem = {timestamp: number; message: MessageEvent}


type PostbackItem = {timestamp: number; postback: PostbackEvent}


type AccountLinkingItem = {timestamp: number; account_linking: AccountLinkingEvent}


from(senderId: string) {
    return this.clone({senderId})
  }


to(recipientId: string) {
    return this.clone({recipientId})
  }


at(timestamp: number) {
    return this.clone({timestamp})
  }


postback(title: string, payload?: string) {
    const mid = `m-${nextFakeMessageId++}`
    const item = {timestamp: this.data.timestamp, postback: {mid, title, payload: payload || title}}
    return this.clone({items: [...this.data.items, item]})
  }


accountLinked(authorizationCode: string) {
    const item: AccountLinkingItem = {
      timestamp: this.data.timestamp,
      account_linking: {status: 'linked', authorization_code: authorizationCode},
    }
    return this.clone({items: [...this.data.items, item]})
  }


text(content: string) {
    return this.message({text: content})
  }


quickReply(text: string, payload?: string) {
    return this.message({text, quick_reply: {payload: payload || text}})
  }


replyTo(id: string, text: string) {
    return this.message({text, reply_to: {mid: id}})
  }


image(url: string) {
    return this.attachment({type: 'image', payload: {url}})
  }


audio(url: string) {
    return this.attachment({type: 'audio', payload: {url}})
  }


video(url: string) {
    return this.attachment({type: 'video', payload: {url}})
  }


file(url: string) {
    return this.attachment({type: 'file', payload: {url}})
  }


location(lat: number, long: number, url: string) {
    return this.attachment({type: 'location', payload: {url, coordinates: {lat, long}}})
  }


protected validate() {
    const {recipientId, senderId, items} = this.data
    if (recipientId === undefined)
      throw `The recipient is missing, use .to(recipientId) to set the recipient`
    if (senderId === undefined) throw `The sender is missing, use .from(senderId) to set the sender`
    if (items.length === 0) throw `The message to send with the event is missing`
  }


protected build() {
    const {recipientId, senderId, items} = this.data
    const entry = items.map(({timestamp, ...data}) => {
      return {
        id: recipientId,
        time: timestamp,
        messaging: [
          {
            timestamp,
            sender: {id: senderId},
            recipient: {id: recipientId},
            ...data,
          },
        ],
      } as EventEntry
    })
    return {object: 'page', entry} as WebhookEvent
  }


private message(data: Omit<MessageEvent, 'mid'>) {
    const mid = `m-${nextFakeMessageId++}`
    const item = {timestamp: this.data.timestamp, message: {mid, ...data}}
    return this.clone({items: [...this.data.items, item]})
  }


private attachment(data: EventAttachment) {
    return this.message({attachments: [data]})
  }


async function fetchPackageDetail() {
    try {
      const detailPkg = await API.getPackage({
        packageName: packageName,
        version: version,
        repositoryKind: repositoryKind,
        repositoryName: repositoryName,
      });
      let metaTitle = `${detailPkg.normalizedName} ${detailPkg.version} · ${
        detailPkg.repository.userAlias || detailPkg.repository.organizationName
      }/${detailPkg.repository.name}`;
      updateMetaIndex(metaTitle, detailPkg.description);
      setDetail(detailPkg);
      if (currentHash) {
        setCurrentHash(undefined);
      }
      if (isUndefined(activeChannel) && detailPkg.repository.kind === RepositoryKind.OLM) {
        if (detailPkg.defaultChannel) {
          setActiveChannel(detailPkg.defaultChannel);
        } else if (detailPkg.channels && detailPkg.channels.length > 0) {
          setActiveChannel(detailPkg.channels[0].name);
        }
      }
      setApiError(null);
      window.scrollTo(0, 0); // Scroll to top when a new version is loaded
      setIsLoadingPackage(false);
      scrollIntoView();
    } catch (err) {
      if (err.kind === ErrorKind.NotFound) {
        setApiError(
          <>
            <div className={`mb-4 mb-lg-5 h2 ${styles.noDataTitleContent}`}>
              Sorry, the package you requested was not found.

            <p className={`h5 mb-4 mb-lg-5 ${styles.noDataTitleContent}`}>
              The package you are looking for may have been deleted by the provider, or it may now belong to a different
              repository. Please try searching for it, as it may help locating the package in a different repository or
              discovering other alternatives.

            <p className={`h6 ${styles.noDataContent}`}


(props: Props) => {
  const history = useHistory();
  const [isLoadingPackage, setIsLoadingPackage] = useState(false);
  const [packageName, setPackageName] = useState(props.packageName);
  const [repositoryKind, setRepositoryKind] = useState(props.repositoryKind);
  const [repositoryName, setRepositoryName] = useState(props.repositoryName);
  const [version, setVersion] = useState(props.version);
  const [detail, setDetail] = useState<Package | null | undefined>(undefined);
  const { tsQueryWeb, tsQuery, pageNumber, filters, deprecated, operators, verifiedPublisher, official } =
    props.searchUrlReferer || {};
  const [apiError, setApiError] = useState<null | string | JSX.Element>(null);
  const [activeChannel, setActiveChannel] = useState<string | undefined>(props.channel);
  const [currentHash, setCurrentHash] = useState<string | undefined>(props.hash);

  useScrollRestorationFix();

  useEffect(() => {
    if (!isUndefined(props.packageName) && !isLoadingPackage) {
      setPackageName(props.packageName);
      setVersion(props.version);
      setRepositoryKind(props.repositoryKind);
      setRepositoryName(props.repositoryName);
    }
  }, [props, isLoadingPackage]);

  async function fetchPackageDetail() {
    try {
      const detailPkg = await API.getPackage({
        packageName: packageName,
        version: version,
        repositoryKind: repositoryKind,
        repositoryName: repositoryName,
      });
      let metaTitle = `${detailPkg.normalizedName} ${detailPkg.version} · ${
        detailPkg.repository.userAlias || detailPkg.repository.organizationName
      }/${detailPkg.repository.name}`;
      updateMetaIndex(metaTitle, detailPkg.description);
      setDetail(detailPkg);
      if (currentHash) {
        setCurrentHash(undefined);
      }
      if (isUndefined(activeChannel) && detailPkg.repository.kind === RepositoryKind.OLM) {
        if (detailPkg.defaultChannel) {
          setActiveChannel(detailPkg.defaultChannel);
        } else if (detailPkg.channels && detailPkg.channels.length > 0) {
          setActiveChannel(detailPkg.channels[0].name);
        }
      }
      setApiError(null);
      window.scrollTo(0, 0); // Scroll to top when a new version is loaded
      setIsLoadingPackage(false);
      scrollIntoView();
    } catch (err) {
      if (err.kind === ErrorKind.NotFound) {
        setApiError(
          <>
            <div className={`mb-4 mb-lg-5 h2 ${styles.noDataTitleContent}`}>
              Sorry, the package you requested was not found.

            <p className={`h5 mb-4 mb-lg-5 ${styles.noDataTitleContent}`}>
              The package you are looking for may have been deleted by the provider, or it may now belong to a different
              repository. Please try searching for it, as it may help locating the package in a different repository or
              discovering other alternatives.

            <p className={`h6 ${styles.noDataContent}`}>
              NOTE: The official Helm stable and{' '}
              incubator repositories were removed from Artifact Hub on
              November 6th as part of the deprecation plan announced by the Helm project. For more information please
              see <ExternalLink href="https://helm.sh/blog/charts-repo-deprecation/">this blog post</ExternalLink> and{' '}
              <ExternalLink href="https://github.com/helm/charts/issues/23944">this Github issue</ExternalLink>.

          </>


() => {
    if (!isUndefined(props.packageName) && !isLoadingPackage) {
      setPackageName(props.packageName);
      setVersion(props.version);
      setRepositoryKind(props.repositoryKind);
      setRepositoryName(props.repositoryName);
    }
  }


() => {
    setIsLoadingPackage(true);
    fetchPackageDetail();
    /* eslint-disable react-hooks/exhaustive-deps */
  }


() => {
    return () => {
      setIsLoadingPackage(false);
    };
  }


() => {
      setIsLoadingPackage(false);
    }


(channel: string) => {
    history.replace({
      search: `?channel=${channel}`,
    });
    setActiveChannel(channel);
  }


(wrapperClassName?: string): JSX.Element | null => (
    <div className={wrapperClassName}>
      <InstallationModal
        package


(): string | FalcoRules | undefined => {
    let rules: string | FalcoRules | undefined;
    if (
      !isUndefined(detail) &&
      !isNull(detail) &&
      !isNull(detail.data) &&
      !isUndefined(detail.data) &&
      !isUndefined(detail.data.rules)
    ) {
      if (isArray(detail.data.rules)) {
        rules = map(detail.data.rules, 'Raw').join(' ');
      } else {
        rules = detail.data.rules as FalcoRules;
      }
    }
    return rules;
  }


(): OPAPolicies | undefined => {
    let policies: OPAPolicies | undefined;
    if (
      !isUndefined(detail) &&
      !isNull(detail) &&
      !isNull(detail.data) &&
      !isUndefined(detail.data) &&
      !isUndefined(detail.data.policies)
    ) {
      policies = detail.data.policies;
    }
    return policies;
  }


(): string | undefined => {
    let manifest: string | undefined;
    if (
      !isUndefined(detail) &&
      !isNull(detail) &&
      !isNull(detail.data) &&
      !isUndefined(detail.data) &&
      !isUndefined(detail.data.manifestRaw)
    ) {
      manifest = detail.data.manifestRaw as string;
    }
    return manifest;
  }


(): CustomResourcesDefinition[] | undefined => {
    let resources: CustomResourcesDefinition[] | undefined;
    if (detail && detail.crds) {
      let examples: CustomResourcesDefinitionExample[] = detail.crdsExamples || [];
      resources = detail.crds.map((resourceDefinition: CustomResourcesDefinition) => {
        return {
          ...resourceDefinition,
          example: examples.find((info: any) => info.kind === resourceDefinition.kind),
        };
      });
    }
    return resources;
  }


(resourceDefinition: CustomResourcesDefinition) => {
        return {
          ...resourceDefinition,
          example: examples.find((info: any) => info.kind === resourceDefinition.kind),
        };
      }


(info: any) => info.kind === resourceDefinition.kind


(): JSX.Element | null => {
    const resources = getCRDs();
    if (!isUndefined(resources) && resources.length > 0) {
      return (
        <div className={`mb-5 ${styles.codeWrapper}`}>
          <AnchorHeader level={2} scrollIntoView={scrollIntoView} title="Custom Resource Definitions" />

          <CustomResourceDefinition resources={resources} normalizedName={detail!.normalizedName} />
        </div>


(withRepoInfo: boolean, extraStyle?: string): JSX.Element => (
    <>
      <OfficialBadge official={isPackageOfficial(detail)}


() => {
    if (props.hash !== currentHash) {
      setCurrentHash(props.hash);
      if (isUndefined(props.hash) || props.hash === '') {
        window.scrollTo(0, 0);
      } else {
        scrollIntoView();
      }
    }
  }


(id?: string) => {
      const elId = id || props.hash;
      if (isUndefined(elId) || elId === '') return;

      try {
        const element = document.querySelector(elId);
        if (element) {
          element.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });

          if (isUndefined(id)) {
            history.replace({
              pathname: history.location.pathname,
              hash: elId,
              state: {
                searchUrlReferer: props.searchUrlReferer,
                fromStarredPage: props.fromStarredPage,
              },
            });
          } else if (props.hash !== elId) {
            history.push({
              pathname: history.location.pathname,
              hash: elId,
              state: {
                searchUrlReferer: props.searchUrlReferer,
                fromStarredPage: props.fromStarredPage,
              },
            });
          }
        }
      } finally {
        return;
      }
    }


(): { content: JSX.Element; titles: string } | null => {
    if (isNull(detail) || isUndefined(detail)) return null;
    let additionalTitles = '';
    const additionalContent = (
      <>
        {(() => {
          switch (detail.repository.kind) {
            case RepositoryKind.Falco:
              let rules: string | FalcoRules | undefined = getFalcoRules();
              if (!isUndefined(rules)) {
                additionalTitles += '# Rules\n';
              }
              return (
                <>
                  {!isUndefined(rules) && (
                    <div className={`mb-5 ${styles.codeWrapper}`}>
                      <AnchorHeader level={2} scrollIntoView={scrollIntoView} title="Rules" />

                      {(() => {
                        switch (typeof rules) {
                          case 'string':
                            return (

                                <BlockCodeButtons content={rules} filename={`${detail.normalizedName}-rules.yaml`} />
                                <SyntaxHighlighter
                                  language="yaml"
                                  style={tomorrowNight}
                                  customStyle={{ padding: '1.5rem' }}
                                >
                                  {rules}
                                </SyntaxHighlighter>

                            );
                          default:
                            return (
                              <ResourcesList
                                resources={rules}
                                normalizedName={detail.normalizedName}
                                kind={detail.repository.kind}
                              />
                            );
                        }


() => {
          switch (detail.repository.kind) {
            case RepositoryKind.Falco:
              let rules: string | FalcoRules | undefined = getFalcoRules();
              if (!isUndefined(rules)) {
                additionalTitles += '# Rules\n';
              }
              return (
                <>
                  {!isUndefined(rules) && (
                    <div className={`mb-5 ${styles.codeWrapper}`}>
                      <AnchorHeader level={2} scrollIntoView={scrollIntoView} title="Rules" />

                      {(() => {
                        switch (typeof rules) {
                          case 'string':
                            return (

                                <BlockCodeButtons content={rules} filename={`${detail.normalizedName}-rules.yaml`} />
                                <SyntaxHighlighter
                                  language="yaml"
                                  style={tomorrowNight}
                                  customStyle={{ padding: '1.5rem' }}
                                >
                                  {rules}
                                </SyntaxHighlighter>

                            );
                          default:
                            return (
                              <ResourcesList
                                resources={rules}
                                normalizedName={detail.normalizedName}
                                kind={detail.repository.kind}
                              />


() => {
                        switch (typeof rules) {
                          case 'string':
                            return (
                              <div className="d-flex d-xxl-inline-block mw-100 position-relative">
                                <BlockCodeButtons content={rules} filename={`${detail.normalizedName}-rules.yaml`} />
                                <SyntaxHighlighter
                                  language="yaml"
                                  style={tomorrowNight}
                                  customStyle={{ padding: '1.5rem' }}


() => {
                            switch (detail.repository.kind) {
                              case RepositoryKind.TektonTask:
                                return (
                                  <TektonManifestModal
                                    normalizedName={detail.normalizedName}
                                    manifestRaw={getManifestRaw()}
                                  />
                                );

                              case RepositoryKind.Helm:
                                return (
                                  <div className="mb-2">
                                    <ValuesSchema
                                      hasValuesSchema={detail.hasValuesSchema}
                                      packageId={detail.packageId}
                                      version={detail.version!}
                                      normalizedName={detail.normalizedName}
                                      searchUrlReferer={props.searchUrlReferer}
                                      fromStarredPage={props.fromStarredPage}
                                      visibleValuesSchema={
                                        !isUndefined(props.visibleModal) && props.visibleModal === 'values-schema'
                                      }
                                      visibleValuesSchemaPath={
                                        !isUndefined(props.visibleModal) && props.visibleModal === 'values-schema'
                                          ? props.visibleValuesSchemaPath
                                          : undefined
                                      }


interface Props {
  searchUrlReferer?: SearchFiltersURL;
  fromStarredPage?: boolean;
  packageName: string;
  version?: string;
  repositoryKind: string;
  repositoryName: string;
  hash?: string;
  channel?: string;
  visibleModal?: string;
  visibleValuesSchemaPath?: string;
  visibleTemplate?: string;
}


isPackageOfficial(detail)


tsQueryWeb ? (
              <


getBadges(false, 'mt-1')


getBadges(true, 'mt-3 mt-md-0')


isNull(detail)


isNull(apiError)


getManifestRaw()


isNull(detail


isNull(additionalInfo)


export default interface DataProps {
    title?: string;
    content?: string;
    date?: string;
    location?: string;
    picture?: string;
    initialValue?:any;
    clear?:any;
  }


(s: number[]) => this.onSelectionChanged(s)


() => (this.defaultPointColor as any)


/**
   * Create points, set their locations and actually instantiate the
   * geometry.
   */
private addSprites(scene: THREE.Scene) {
    // Create geometry.
    this.geometry = new THREE.BufferGeometry();
    this.createBufferAttributes();
    let canvas = document.createElement('canvas');
    let image = this.image || canvas;
    // TODO(b/31390553): Pass sprite dim to the renderer.
    let spriteDim = 28.0;
    let tex = this.createTexture(image);
    let pointSize = (this.sceneIs3D ? this.pointSize3D : this.pointSize2D);
    if (this.image) {
      pointSize = IMAGE_SIZE;
    }

    this.uniforms = {
      texture: {type: 't', value: tex},
      imageWidth: {type: 'f', value: image.width / spriteDim},
      imageHeight: {type: 'f', value: image.height / spriteDim},
      fogColor: {type: 'c', value: this.fog.color},
      fogNear: {type: 'f', value: this.fog.near},
      fogFar: {type: 'f', value: this.fog.far},
      sizeAttenuation: {type: 'bool', value: this.sceneIs3D},
      isImage: {type: 'bool', value: !!this.image},
      pointSize: {type: 'f', value: pointSize}
    };

    let haveImage = (this.image != null);

    this.renderMaterial = new THREE.ShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: VERTEX_SHADER,
      fragmentShader: FRAGMENT_SHADER,
      transparent: !haveImage,
      depthTest: haveImage,
      depthWrite: haveImage,
      fog: true,
      blending: (this.image ? THREE.NormalBlending : this.blending),
    });

    this.pickingMaterial = new THREE.ShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: VERTEX_SHADER,
      fragmentShader: FRAGMENT_SHADER,
      transparent: false,
      depthTest: true,
      depthWrite: true,
      fog: false,
      blending: (this.image ? THREE.NormalBlending : this.blending),
    });

    // And finally initialize it and add it to the scene.
    this.points = new THREE.Points(this.geometry, this.renderMaterial);
    scene.add(this.points);
  }


private calibratePointSize() {
    let numPts = this.dataSet.points.length;
    let scaleConstant = 200;
    let logBase = 8;
    // Scale point size inverse-logarithmically to the number of points.
    this.pointSize3D = scaleConstant / Math.log(numPts) / Math.log(logBase);
    this.pointSize2D = this.pointSize3D / 1.5;
  }


private setFogDistances(nearestPointZ: number, farthestPointZ: number) {
    if (this.sceneIs3D) {
      this.fog.near = nearestPointZ;
      // If there are fewer points we want less fog. We do this
      // by making the "far" value (that is, the distance from the camera to the
      // far edge of the fog) proportional to the number of points.
      let multiplier = 2 -
          Math.min(this.dataSet.points.length, NUM_POINTS_FOG_THRESHOLD) /
              NUM_POINTS_FOG_THRESHOLD;
      this.fog.far = farthestPointZ * multiplier;
    } else {
      this.fog.near = Infinity;
      this.fog.far = Infinity;
    }
  }


/**
   * Set up buffer attributes to be used for the points/images.
   */
private createBufferAttributes() {
    let numPoints = this.dataSet.points.length;
    this.pickingColors = new Float32Array(numPoints * RGB_NUM_BYTES);
    let colors = new THREE.BufferAttribute(this.pickingColors, RGB_NUM_BYTES);

    // Fill pickingColors with each point's unique id as its color.
    for (let i = 0; i < numPoints; i++) {
      let color = new THREE.Color(i);
      colors.setXYZ(i, color.r, color.g, color.b);
    }

    this.renderColors = new Float32Array(numPoints * RGB_NUM_BYTES);
    colors.array = this.renderColors;

    /** Indices cooresponding to highlighted points. */
    let hiArr = new Float32Array(numPoints);
    let highlights = new THREE.BufferAttribute(hiArr, INDEX_NUM_BYTES);

    /**
     * The actual indices of the points which we use for sizeAttenuation in
     * the shader.
     */
    let indicesShader =
        new THREE.BufferAttribute(new Float32Array(numPoints), 1);

    // Create the array of indices.
    for (let i = 0; i < numPoints; i++) {
      indicesShader.setX(i, this.dataSet.points[i].dataSourceIndex);
    }

    // Finally, add all attributes to the geometry.
    this.geometry.addAttribute('position', this.positionBuffer);
    this.positionBuffer.needsUpdate = true;
    this.geometry.addAttribute('color', colors);
    this.geometry.addAttribute('vertexIndex', indicesShader);
    this.geometry.addAttribute('isHighlight', highlights);

    this.colorSprites(null);
    this.highlightSprites(null, null);
  }


private colorSprites(colorAccessor: (index: number) => string) {
    if (this.geometry == null) {
      return;
    }
    let colors = this.geometry.getAttribute('color') as THREE.BufferAttribute;
    colors.array = this.renderColors;
    let getColor: (index: number) => string = (() => undefined);
    if (this.image == null) {
      getColor =
          colorAccessor ? colorAccessor : () => (this.defaultPointColor as any);
    }
    for (let i = 0; i < this.dataSet.points.length; i++) {
      let color = new THREE.Color(getColor(i));
      colors.setXYZ(i, color.r, color.g, color.b);
    }
    colors.needsUpdate = true;
  }


private highlightSprites(
      highlightedPoints: number[], highlightStroke: (index: number) => string) {
    if (this.geometry == null) {
      return;
    }
    let highlights =
        this.geometry.getAttribute('isHighlight') as THREE.BufferAttribute;
    for (let i = 0; i < this.dataSet.points.length; i++) {
      highlights.setX(i, 0.0);
    }
    if (highlightedPoints && highlightStroke) {
      let colors = this.geometry.getAttribute('color') as THREE.BufferAttribute;
      // Traverse in reverse so that the point we are hovering over
      // (highlightedPoints[0]) is painted last.
      for (let i = highlightedPoints.length - 1; i >= 0; i--) {
        let assocPoint = highlightedPoints[i];
        let color = new THREE.Color(highlightStroke(i));
        // Fill colors array (single array of numPoints*3 elements,
        // triples of which refer to the rgb values of a single vertex).
        colors.setXYZ(assocPoint, color.r, color.g, color.b);
        highlights.setX(assocPoint, 1.0);
      }
      colors.needsUpdate = true;
    }
    highlights.needsUpdate = true;
  }


/* Updates the positions buffer array to reflect the actual data. */
private updatePositionsArray() {
    // Update the points.
    for (let i = 0; i < this.dataSet.points.length; i++) {
      // Set position based on projected point.
      let pp = this.dataSet.points[i].projectedPoint;
      this.positionBuffer.setXYZ(i, pp[0], pp[1], pp[2]);
    }

    if (this.geometry) {
      this.positionBuffer.needsUpdate = true;
    }
  }


removeAllFromScene(scene: THREE.Scene) {
    scene.remove(this.points);
  }


/**
   * Generate a texture for the points/images and sets some initial params
   */
createTexture(image: HTMLImageElement|HTMLCanvasElement): THREE.Texture {
    let tex = new THREE.Texture(image);
    tex.needsUpdate = true;
    // Used if the texture isn't a power of 2.
    tex.minFilter = THREE.LinearFilter;
    tex.generateMipmaps = false;
    tex.flipY = false;
    return tex;
  }


onDataSet(dataSet: DataSet, spriteImage: HTMLImageElement) {
    this.dataSet = dataSet;
    this.image = spriteImage;
    this.points = null;
    if (this.geometry) {
      this.geometry.dispose();
    }
    this.geometry = null;
    this.calibratePointSize();

    let positions =
        new Float32Array(this.dataSet.points.length * XYZ_NUM_BYTES);
    this.positionBuffer = new THREE.BufferAttribute(positions, XYZ_NUM_BYTES);
  }


onSelectionChanged(selection: number[]) {
    this.defaultPointColor =
        (selection.length > 0) ? POINT_COLOR_GRAYED : POINT_COLOR;
  }


onSetDayNightMode(isNight: boolean) {
    this.blending = (isNight ? BLENDING_NIGHT : BLENDING_DAY);
  }


onRecreateScene(
      scene: THREE.Scene, sceneIs3D: boolean, backgroundColor: number) {
    this.sceneIs3D = sceneIs3D;
    this.fog = new THREE.Fog(backgroundColor);
    scene.fog = this.fog;
    this.addSprites(scene);
    this.colorSprites(null);
    this.highlightSprites(null, null);
  }


onUpdate() {
    this.updatePositionsArray();
  }


onResize(newWidth: number, newHeight: number) {}


onPickingRender(camera: THREE.Camera, cameraTarget: THREE.Vector3) {
    if (!this.geometry) {
      return;
    }
    // Fog changes point colors, which alters the IDs.
    this.fog.near = Infinity;
    this.fog.far = Infinity;

    this.points.material = this.pickingMaterial;
    this.pickingMaterial.uniforms.isImage.value = false;

    let colors = this.geometry.getAttribute('color') as THREE.BufferAttribute;
    colors.array = this.pickingColors;
    colors.needsUpdate = true;
  }


onRender(rc: RenderContext) {
    if (!this.geometry) {
      return;
    }
    this.colorSprites(rc.colorAccessor);
    this.highlightSprites(rc.highlightedPoints, rc.highlightStroke);

    this.setFogDistances(
        rc.nearestCameraSpacePointZ, rc.farthestCameraSpacePointZ);

    this.points.material = this.renderMaterial;
    this.renderMaterial.uniforms.isImage.value = !!this.image;

    let colors = this.geometry.getAttribute('color') as THREE.BufferAttribute;
    colors.array = this.renderColors;
    colors.needsUpdate = true;
  }


export function Home() {
  const history = useHistory();
  const { user, signInWithGoogle } = useAuth();
  const [roomCode, setRoomCode] = useState('');

  async function handleCreateRoom() {
    if (!user) {
      await signInWithGoogle();
    }

    history.push('/rooms/new');
  }

  async function handleJoinRoom(event: FormEvent) {
    event.preventDefault();

    if (roomCode.trim() === '') return;

    const roomRef = await database.ref(`rooms/${roomCode}`).get();

    if (!roomRef.exists()) {
      toast.error('Room does not exists.');
      return;
    }

    if (roomRef.val().endedAt) {
      toast.info('Room already closed.');
      return;
    }

    history.push(`/rooms/${roomCode}`);
  }

  return (
    <Container>

        <ImgBackground
          src={illustrationImg}
          alt="Ilustração simbolizando perguntas e respostas"
        />
        Crie salas de Q&A ao-vivo
        <TextAside>Tire as dúvidas da sua audiência em tempo-real</TextAside>

        <MainContent>
          <Logo>Letmeask</Logo>
          <ButtonMain onClick={handleCreateRoom}>
            <ImgButton src={googleIconImg} alt="Logo do Google" />
            Crie sua sala com o Google
          </ButtonMain>
          <Separator>ou entre em uma sala</Separator>
          <Form onSubmit={handleJoinRoom}>
            <Input
              type="text"
              placeholder="Digite o código da sala"
              onChange={(event) => setRoomCode(event.target.value)}


async function handleCreateRoom() {
    if (!user) {
      await signInWithGoogle();
    }

    history.push('/rooms/new');
  }


async function handleJoinRoom(event: FormEvent) {
    event.preventDefault();

    if (roomCode.trim() === '') return;

    const roomRef = await database.ref(`rooms/${roomCode}`).get();

    if (!roomRef.exists()) {
      toast.error('Room does not exists.');
      return;
    }

    if (roomRef.val().endedAt) {
      toast.info('Room already closed.');
      return;
    }

    history.push(`/rooms/${roomCode}`);
  }


() => {
  const baseComponent = (props?: object) => <TestThemeProvider><DisabledPanel id='disabled-panel' {


(props?: object) => <TestThemeProvider><DisabledPanel id


() => {
    it('matches the snapshot', () => {
      const component = baseComponent()
      const tree = create(component).toJSON()
      expect(tree).toMatchSnapshot()
    })

    it('renders the component', () => {
      const wrapper = shallow(baseComponent())
      const assertion = wrapper.find('#disabled-panel').length
      expect(assertion).toBe(1)
    })
  }


() => {
      const component = baseComponent()
      const tree = create(component).toJSON()
      expect(tree).toMatchSnapshot()
    }


() => {
      const wrapper = shallow(baseComponent())
      const assertion = wrapper.find('#disabled-panel').length
      expect(assertion).toBe(1)
    }


props => {
  const Slots = getSlots<ICollapsibleSectionTitleProps, ICollapsibleSectionTitleSlots>(props, {
    root: 'button',
    chevron: Icon,
    text: Text,
  });

  const buttonProps = getNativeProps<React.HTMLAttributes<HTMLButtonElement>>(props, buttonProperties);

  return (
    <Slots.root {...buttonProps} ref={props.focusElementRef}>
      {!props.chevronDisabled && <Slots.chevron iconName="ChevronDown" />}


/**
 * The content and the mode of a file.
 * Default file mode is a text file which has code '100644'.
 * If `content` is not null, then `content` must be the entire file content.
 * See https://developer.github.com/v3/git/trees/#tree-object for details on mode.
 */
export declare class FileData {
    readonly mode: FileMode;
    readonly content: string | null;
    constructor(content: string | null, mode?: FileMode);
}


export declare class PatchSyntaxError extends Error {
    constructor(message: string);
}


/**
 * GitHub definition of tree
 */
export interface TreeObject {
    path: string;
    mode: FileMode;
    type: 'blob' | 'tree' | 'commit';
    sha?: string | null;
    content?: string;
}


/**
 * The domain of a repository
 */
export interface RepoDomain {
    repo: string;
    owner: string;
}


/**
 * The domain for a branch
 */
export interface BranchDomain extends RepoDomain {
    branch: string;
}


/**
 * The descriptive properties for any entity
 */
export interface Description {
    title: string;
    body: string;
}


/**
 * The user options for creating GitHub PRs
 */
export interface CreatePullRequestUserOptions {
    upstreamOwner: string;
    upstreamRepo: string;
    message: string;
    description: string;
    title: string;
    branch?: string;
    force?: boolean;
    fork?: boolean;
    primary?: string;
    maintainersCanModify?: boolean;
}


/**
 * GitHub data needed for creating a PR
 */
export interface CreatePullRequest {
    upstreamOwner: string;
    upstreamRepo: string;
    message: string;
    description: string;
    title: string;
    branch: string;
    force: boolean;
    primary: string;
    maintainersCanModify: boolean;
}


/**
 * The user options for creating GitHub PR review comment
 */
export interface CreateReviewCommentUserOptions {
    owner: string;
    repo: string;
    pullNumber: number;
    pageSize?: number;
}


/**
 * The user options for creating GitHub PR review comment
 */
export interface CreateReviewComment {
    owner: string;
    repo: string;
    pullNumber: number;
    pageSize: number;
}


/**
 * The file content of the original content and the patched content
 */
export interface FileDiffContent {
    readonly oldContent: string;
    readonly newContent: string;
}


export interface Hunk {
    readonly oldStart: number;
    readonly oldEnd: number;
    readonly newStart: number;
    readonly newEnd: number;
    readonly newContent: string[];
    readonly previousLine?: string;
    readonly nextLine?: string;
}


export declare type FileMode = '100644' | '100755' | '040000' | '160000' | '120000';


/**
 * The map of a path to its content data.
 * The content must be the entire file content.
 */
export declare type Changes = Map<string, FileData>;


export function getJsonObj(obj: ConditionalInputLink, isParentJsonObj?: boolean): object {
    const jsonObj = {
      ...(isParentJsonObj ? obj : (model.FlowPortLink.getJsonObj(obj) as ConditionalInputLink)),
      ...{
        "fromLink": obj.fromLink ? model.OutputLink.getJsonObj(obj.fromLink) : undefined,
        "fieldMap": obj.fieldMap ? model.FieldMap.getJsonObj(obj.fieldMap) : undefined,
        "condition": obj.condition ? model.Expression.getJsonObj(obj.condition) : undefined
      }
    };

    return jsonObj;
  }


/**
 * The information about the conditional input link.
 */
export interface ConditionalInputLink extends model.FlowPortLink {
  "fromLink"?: model.OutputLink;
  "fieldMap"?:
    | model.RuleBasedFieldMap
    | model.DirectFieldMap
    | model.CompositeFieldMap
    | model.DirectNamedFieldMap;
  "condition"?: model.Expression;

  "modelType": string;
}


(val?: string) => true


(val: string) => {
            context.emit("update:modelValue", val);
            context.emit("onUpdate:modelValue", val);
        }


() => <ElCheckbox class


setup(props, context) {
        const checkboxValue = ref(props.modelValue);
        watch(checkboxValue, (val: string) => {
            context.emit("update:modelValue", val);
            context.emit("onUpdate:modelValue", val);
        }, { immediate: true })
        return () => <ElCheckbox class="low-code-checkbox" v-model={checkboxValue.value}></ElCheckbox>
    }


function buildStatements({ statements }: SerializedBlock, blocks: SerializedBlock[], symbolTable: SymbolTable, env: Environment): Program {
  if (statements.length === 0) return EMPTY_PROGRAM;
  return new BlockScanner(statements, blocks, symbolTable, env).scan();
}


export default class Scanner {
  constructor(private block: SerializedTemplateBlock, private meta: TemplateMeta, private env: Environment) {
  }

  scanEntryPoint(): EntryPoint {
    let { block, meta } = this;

    let symbolTable = SymbolTable.forEntryPoint(meta);
    let program = buildStatements(block, block.blocks, symbolTable, this.env);
    return new EntryPoint(program, symbolTable);
  }

  scanLayout(): Layout {
    let { block, meta } = this;
    let { blocks, named, yields, hasPartials } = block;

    let symbolTable = SymbolTable.forLayout(named, yields, hasPartials, meta);
    let program = buildStatements(block, blocks, symbolTable, this.env);

    return new Layout(program, symbolTable, named, yields, hasPartials);
  }

  scanPartial(symbolTable: SymbolTable): PartialBlock {
    let { block } = this;
    let { blocks, locals } = block;

    let program = buildStatements(block, blocks, symbolTable, this.env);

    return new PartialBlock(program, symbolTable, locals);
  }
}


export class BlockScanner {
  public env: Environment;

  private stack = new Stack<ChildBlockScanner>();
  private reader: SyntaxReader;

  constructor(statements: SerializedStatement[], private blocks: SerializedBlock[], private symbolTable: SymbolTable, env: Environment) {
    this.stack.push(new ChildBlockScanner(symbolTable));
    this.reader = new SyntaxReader(statements, symbolTable, this);
    this.env = env;
  }

  scan(): Program {
    let statement: StatementSyntax;

    while (statement = this.reader.next()) {
      this.addStatement(statement);
    }

    return this.stack.current.program;
  }

  blockFor(symbolTable: SymbolTable, id: number): InlineBlock {
    let block = this.blocks[id];
    let childTable = SymbolTable.forBlock(this.symbolTable, block.locals);
    let program = buildStatements(block, this.blocks, childTable, this.env);
    return new InlineBlock(program, childTable, block.locals);
  }

  startBlock(locals: string[]) {
    let childTable = SymbolTable.forBlock(this.symbolTable, locals);
    this.stack.push(new ChildBlockScanner(childTable));
  }

  endBlock(locals: string[]): InlineBlock {
    let { program, symbolTable } = this.stack.pop();
    let block = new InlineBlock(program, symbolTable, locals);
    this.addChild(block);
    return block;
  }

  addChild(block: InlineBlock) {
    this.stack.current.addChild(block);
  }

  addStatement(statement: StatementSyntax) {
    this.stack.current.addStatement(statement.scan(this));
  }

  next(): StatementSyntax {
    return this.reader.next();
  }
}


class ChildBlockScanner {
  public children: InlineBlock[] = [];
  public program = new LinkedList<StatementSyntax>();

  constructor(public symbolTable: SymbolTable) {}

  addChild(block: InlineBlock) {
    this.children.push(block);
  }

  addStatement(statement: StatementSyntax) {
    this.program.append(statement);
  }
}


class SyntaxReader {
  current: number = 0;
  last: StatementSyntax = null;

  constructor(private statements: SerializedStatement[], private symbolTable: SymbolTable, private scanner: BlockScanner) {}

  next(): StatementSyntax {
    let last = this.last;
    if (last) {
      this.last = null;
      return last;
    } else if (this.current === this.statements.length) {
      return null;
    }

    let sexp = this.statements[this.current++];
    return buildStatement(sexp, this.symbolTable, this.scanner);
  }
}


scanEntryPoint(): EntryPoint {
    let { block, meta } = this;

    let symbolTable = SymbolTable.forEntryPoint(meta);
    let program = buildStatements(block, block.blocks, symbolTable, this.env);
    return new EntryPoint(program, symbolTable);
  }


scanLayout(): Layout {
    let { block, meta } = this;
    let { blocks, named, yields, hasPartials } = block;

    let symbolTable = SymbolTable.forLayout(named, yields, hasPartials, meta);
    let program = buildStatements(block, blocks, symbolTable, this.env);

    return new Layout(program, symbolTable, named, yields, hasPartials);
  }


scanPartial(symbolTable: SymbolTable): PartialBlock {
    let { block } = this;
    let { blocks, locals } = block;

    let program = buildStatements(block, blocks, symbolTable, this.env);

    return new PartialBlock(program, symbolTable, locals);
  }


scan(): Program {
    let statement: StatementSyntax;

    while (statement = this.reader.next()) {
      this.addStatement(statement);
    }

    return this.stack.current.program;
  }


blockFor(symbolTable: SymbolTable, id: number): InlineBlock {
    let block = this.blocks[id];
    let childTable = SymbolTable.forBlock(this.symbolTable, block.locals);
    let program = buildStatements(block, this.blocks, childTable, this.env);
    return new InlineBlock(program, childTable, block.locals);
  }


startBlock(locals: string[]) {
    let childTable = SymbolTable.forBlock(this.symbolTable, locals);
    this.stack.push(new ChildBlockScanner(childTable));
  }


endBlock(locals: string[]): InlineBlock {
    let { program, symbolTable } = this.stack.pop();
    let block = new InlineBlock(program, symbolTable, locals);
    this.addChild(block);
    return block;
  }


addChild(block: InlineBlock) {
    this.stack.current.addChild(block);
  }


addStatement(statement: StatementSyntax) {
    this.stack.current.addStatement(statement.scan(this));
  }


next(): StatementSyntax {
    return this.reader.next();
  }


addChild(block: InlineBlock) {
    this.children.push(block);
  }


addStatement(statement: StatementSyntax) {
    this.program.append(statement);
  }


next(): StatementSyntax {
    let last = this.last;
    if (last) {
      this.last = null;
      return last;
    } else if (this.current === this.statements.length) {
      return null;
    }

    let sexp = this.statements[this.current++];
    return buildStatement(sexp, this.symbolTable, this.scanner);
  }


export declare function mergeMapTo<O extends ObservableInput<unknown>>(innerObservable: O, concurrent?: number): OperatorFunction<any, ObservedValueOf<O>>;


/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */
export declare function mergeMapTo<T, R, O extends ObservableInput<unknown>>(innerObservable: O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>;


/**
 * @name ExtrinsicPayloadUnknown
 * @description
 * A default handler for payloads where the version is not known (default throw)
 */
export default class ExtrinsicPayloadUnknown extends Struct {
  constructor (value?: any, { version = 0 }: Partial<ExtrinsicPayloadOptions> = {}) {
    super({});

    throw new Error(`Unsupported extrinsic payload version ${version}`);
  }
}


(styles: any) => ({
        ...styles,
        backgroundColor: '#676767',
        color: 'white',
        border: 0,
        width: 400,
    })


(styles: any) => {
        return {
            backgroundColor: '#AAAAAA',
            color: 'white',
        }
    }


(styles: any) => ({ ...styles, color: 'white' })


(page: ICustomPages, index: number) => {
                return { label: page.label, value: index }
            }


(a, b) => {
                    return a - b
                }


(event: ChangeEvent<HTMLInputElement>) => {
        this.setState({ label: event.target.value })
        this.pageList[this.state.pageIndex].label = event.target.value
        let nextPages: ICustomPages[] = [...this.props.customPages]
        nextPages[this.state.pageIndex].label = event.target.value

        window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
        window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
    }


() => {
        window.socketIoClient.emit(SOCKET_GET_PAGES_LIST)
        this.props.dispatch(storeShowPagesSetup())
    }


(fader: IFader, index: number) => {
                    return (
                        <div
                            key={index}
                            className={ClassNames('pages-settings-tick', {
                                checked: this.props.customPages[
                                    this.state.pageIndex
                                ].faders.includes(index),
                            }


(state: any, props: any): IPagesSettingsInjectProps => {
    return {
        customPages: state.settings[0].customPages,
        fader: state.faders[0].fader,
    }
}


class PagesSettings extends React.PureComponent<
    IPagesSettingsInjectProps & Store
> {
    pageList: { label: string; value: number }[]
    state = { pageIndex: 0, label: '' }

    constructor(props: any) {
        super(props)

        this.pageList = this.props.customPages.map(
            (page: ICustomPages, index: number) => {
                return { label: page.label, value: index }
            }
        )
    }

    componentDidMount() {
        this.setState({ label: this.props.customPages[0].label })
    }

    handleSelectPage(event: any) {
        this.setState({ pageIndex: event.value })
        this.setState({
            label: this.props.customPages[event.value].label,
        })
        console.log('PAGE SELECTED', this.state.pageIndex)
    }

    handleAssignFader(fader: number, event: any) {
        if (event.target.checked === false) {
            console.log('Unbinding Fader')
            if (
                window.confirm(
                    'Unbind Fader from page ' +
                        String(fader + 1) +
                        ' from Page ' +
                        String(this.state.pageIndex + 1)
                )
            ) {
                let nextPages: ICustomPages[] = [...this.props.customPages]
                nextPages[this.state.pageIndex].faders.splice(
                    this.props.customPages[this.state.pageIndex].faders.indexOf(
                        fader
                    ),
                    1
                )
                window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
                window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
            }
        } else {
            console.log('Binding Channel')
            if (
                window.confirm(
                    'Bind Fader ' +
                        String(fader + 1) +
                        ' to Page ' +
                        String(this.state.pageIndex + 1) +
                        '?'
                )
            ) {
                let nextPages: ICustomPages[] = [...this.props.customPages]
                nextPages[this.state.pageIndex].faders.push(fader)
                nextPages[this.state.pageIndex].faders.sort((a, b) => {
                    return a - b
                })
                window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
                window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
            }
        }
    }

    handleLabel = (event: ChangeEvent<HTMLInputElement>) => {
        this.setState({ label: event.target.value })
        this.pageList[this.state.pageIndex].label = event.target.value
        let nextPages: ICustomPages[] = [...this.props.customPages]
        nextPages[this.state.pageIndex].label = event.target.value

        window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
        window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
    }

    handleClearRouting() {
        if (window.confirm('REMOVE ALL FADER ASSIGNMENTS????')) {
            let nextPages: ICustomPages[] = [...this.props.customPages]
            nextPages[this.state.pageIndex].faders = []
            window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
            window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
        }
    }

    handleClose = () => {
        window.socketIoClient.emit(SOCKET_GET_PAGES_LIST)
        this.props.dispatch(storeShowPagesSetup())
    }

    renderFaderList() {
        return (
            <div>
                {this.props.fader.map((fader: IFader, index: number) => {
                    return (
                        <div
                            key={index}
                            className={ClassNames('pages-settings-tick', {
                                checked: this.props.customPages[
                                    this.state.pageIndex
                                ].faders.includes(index),
                            })}
                        >
                            {' Fader ' + (index + 1) + ' - ' + getFaderLabel(index) + ' : '}
                            {}
                            <input
                                type="checkbox"
                                checked={this.props.customPages[
                                    this.state.pageIndex
                                ].faders.includes(index)}
                                onChange={(event) =>
                                    this.handleAssignFader(index, event)
                                }


interface IPagesSettingsInjectProps {
    customPages: ICustomPages[]
    fader: IFader[]
}


componentDidMount() {
        this.setState({ label: this.props.customPages[0].label })
    }


handleSelectPage(event: any) {
        this.setState({ pageIndex: event.value })
        this.setState({
            label: this.props.customPages[event.value].label,
        })
        console.log('PAGE SELECTED', this.state.pageIndex)
    }


handleAssignFader(fader: number, event: any) {
        if (event.target.checked === false) {
            console.log('Unbinding Fader')
            if (
                window.confirm(
                    'Unbind Fader from page ' +
                        String(fader + 1) +
                        ' from Page ' +
                        String(this.state.pageIndex + 1)
                )
            ) {
                let nextPages: ICustomPages[] = [...this.props.customPages]
                nextPages[this.state.pageIndex].faders.splice(
                    this.props.customPages[this.state.pageIndex].faders.indexOf(
                        fader
                    ),
                    1
                )
                window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
                window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
            }
        } else {
            console.log('Binding Channel')
            if (
                window.confirm(
                    'Bind Fader ' +
                        String(fader + 1) +
                        ' to Page ' +
                        String(this.state.pageIndex + 1) +
                        '?'
                )
            ) {
                let nextPages: ICustomPages[] = [...this.props.customPages]
                nextPages[this.state.pageIndex].faders.push(fader)
                nextPages[this.state.pageIndex].faders.sort((a, b) => {
                    return a - b
                })
                window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
                window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
            }
        }
    }


handleClearRouting() {
        if (window.confirm('REMOVE ALL FADER ASSIGNMENTS????')) {
            let nextPages: ICustomPages[] = [...this.props.customPages]
            nextPages[this.state.pageIndex].faders = []
            window.storeRedux.dispatch(storeUpdatePagesList(nextPages))
            window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages)
        }
    }


renderFaderList() {
        return (
            <div>
                {this.props.fader.map((fader: IFader, index: number) => {
                    return (
                        <div
                            key={index}
                            className={ClassNames('pages-settings-tick', {
                                checked: this.props.customPages[
                                    this.state.pageIndex
                                ].faders.includes(index),
                            })}
                        >
                            {' Fader ' + (index + 1) + ' - ' + getFaderLabel(index) + ' : '}
                            {}
                            <input
                                type="checkbox"
                                checked={this.props.customPages[
                                    this.state.pageIndex
                                ].faders.includes(index)}
                                onChange={(event) =>
                                    this.handleAssignFader(index, event)
                                }


ClassNames('pages-settings-tick', {
                                checked: this


export default function Duration(props: DurationProps): ReactElement {
    return (
        // @ts-ignore: Property 'duration' does not exist on type
        <DurationGridCell {...props}>
            <Span>
                {props.duration === 60 ? '1h' : `${props.duration}m`}
            </Span>
        </DurationGridCell>
    );
}


function colorDuration(duration: number): string {
    if (duration <= 15) return '#F1F6F8';
    if (duration <= 30) return '#E5F0F3';
    if (duration <= 45) return '#DAE7EA';
    return '#CBDDE2';
}


(props) => colorDuration(props.duration)


export interface DurationProps extends GridCellProps {
    /** The task's duration. */
    readonly duration: number
}


interface DurationGridCellProps {
    readonly duration: number
}


@Component({
    selector: 'uni-icon',
    templateUrl: 'icon.component.html',
    styleUrls: ['icon.component.scss']
})
export class UniIconComponent {

    @HostBinding('class.uni-icon') componentClass = true;
    @Input() icon: string;
    @Input() size: string;
}


export type BaseModel = {
  id?: string | number;
  cratedAt?: Date;
  updatedAt?: Date;
};


function Intersect(props: IconProps) {
  return <Svg viewBox="0 0 256 256" width={props.size} height={props.size} {...props}><Rect width={256} height={256} fill="none" /><Circle cx={96} cy={96} r={72} fill="none" stroke={props.color} strokeLinecap="round" strokeLinejoin="round" strokeWidth={12} /><Circle cx={160} cy={160} r={72} fill="none" stroke={props.color} strokeLinecap="round" strokeLinejoin="round" strokeWidth={12} /><Line x1={122.5} y1={98.5} x2={157.5} y2={133.5} fill="none" stroke={props.color} strokeLinecap="round" strokeLinejoin="round" strokeWidth={12} /><Line x1={98.5} y1={122.5} x2={133.5} y2={157.5} fill="none" stroke={props.color} strokeLinecap="round" strokeLinejoin="round" strokeWidth={12} /></Svg>;
}


() => {
                EventService.subscribers = EventService.subscribers.filter(p => p.id !== id);
            }


p => p.id !== id


export class EventService {

    private static subscribers: Array<{
        id: number;
        event: string;
        // @ts-ignore
        callback: SubscribeCallback<any>;
    }> = [];

    static subscribe<T>(event: string, callback: SubscribeCallback<T>): Unsubscribe {
        const id = Date.now();

        EventService.subscribers.push({
            id, event, callback
        });

        // Unsubscribe
        return {
            unsubscribe: () => {
                EventService.subscribers = EventService.subscribers.filter(p => p.id !== id);
            },
        };
    }

    static emit<T>(event: string, payload: T) {
        for (let sub of EventService.subscribers) {
            if (event === sub.event && sub.callback) {
                try {
                    sub.callback(payload, event);
                } catch (ex) {
                    logger.error(`Error in emit() for ${event}:`, ex, payload);
                }
            }
        }
    }

}


export type SubscribeCallback<T> = (payload: T, event?: string) => void;


export type Unsubscribe = {
    unsubscribe: (() => void)
};


static subscribe<T>(event: string, callback: SubscribeCallback<T>): Unsubscribe {
        const id = Date.now();

        EventService.subscribers.push({
            id, event, callback
        });

        // Unsubscribe
        return {
            unsubscribe: () => {
                EventService.subscribers = EventService.subscribers.filter(p => p.id !== id);
            },
        };
    }


static emit<T>(event: string, payload: T) {
        for (let sub of EventService.subscribers) {
            if (event === sub.event && sub.callback) {
                try {
                    sub.callback(payload, event);
                } catch (ex) {
                    logger.error(`Error in emit() for ${event}:`, ex, payload);
                }
            }
        }
    }


function doCut (d: string): VBox[] {
      let dim1 = d + '1'
      let dim2 = d + '2'
      let d1 = vbox.dimension[dim1]
      let d2 = vbox.dimension[dim2]
      let vbox1 = vbox.clone()
      let vbox2 = vbox.clone()
      let left = splitPoint - d1
      let right = d2 - splitPoint
      if (left <= right) {
        d2 = Math.min(d2 - 1, ~~(splitPoint + right / 2))
        d2 = Math.max(0, d2)
      } else {
        d2 = Math.max(d1, ~~(splitPoint - 1 - left / 2))
        d2 = Math.min(vbox.dimension[dim2], d2)
      }

      while (!accSum![d2]) d2++

      let c2 = reverseSum[d2]
      while (!c2 && accSum![d2 - 1]) c2 = reverseSum[--d2]

      vbox1.dimension[dim2] = d2
      vbox2.dimension[dim1] = d2 + 1

      return [vbox1, vbox2]
    }


export interface Dimension {
  r1: number
  r2: number
  g1: number
  g2: number
  b1: number
  b2: number
  [d: string]: number
}


static build (pixels: Pixels, shouldIgnore?: Filter): VBox {
    let hn = 1 << (3 * SIGBITS)
    let hist = new Uint32Array(hn)
    let rmax: number
    let rmin: number
    let gmax: number
    let gmin: number
    let bmax: number
    let bmin: number
    let r: number
    let g: number
    let b: number
    let a: number
    rmax = gmax = bmax = 0
    rmin = gmin = bmin = Number.MAX_VALUE
    let n = pixels.length / 4
    let i = 0

    while (i < n) {
      let offset = i * 4
      i++
      r = pixels[offset + 0]
      g = pixels[offset + 1]
      b = pixels[offset + 2]
      a = pixels[offset + 3]

      // Ignored pixels' alpha is marked as 0 in filtering stage
      if (a === 0) continue

      r = r >> RSHIFT
      g = g >> RSHIFT
      b = b >> RSHIFT

      let index = getColorIndex(r, g, b)
      hist[index] += 1

      if (r > rmax) rmax = r
      if (r < rmin) rmin = r
      if (g > gmax) gmax = g
      if (g < gmin) gmin = g
      if (b > bmax) bmax = b
      if (b < bmin) bmin = b
    }
    return new VBox(rmin, rmax, gmin, gmax, bmin, bmax, hist)
  }


invalidate (): void {
    this._volume = this._count = -1
    this._avg = null
  }


volume (): number {
    if (this._volume < 0) {
      let { r1, r2, g1, g2, b1, b2 } = this.dimension
      this._volume = (r2 - r1 + 1) * (g2 - g1 + 1) * (b2 - b1 + 1)
    }
    return this._volume
  }


count (): number {
    if (this._count < 0) {
      let { hist } = this
      let { r1, r2, g1, g2, b1, b2 } = this.dimension
      let c = 0

      for (let r = r1; r <= r2; r++) {
        for (let g = g1; g <= g2; g++) {
          for (let b = b1; b <= b2; b++) {
            let index = getColorIndex(r, g, b)
            c += hist[index]
          }
        }
      }
      this._count = c
    }
    return this._count
  }


clone (): VBox {
    let { hist } = this
    let { r1, r2, g1, g2, b1, b2 } = this.dimension
    return new VBox(r1, r2, g1, g2, b1, b2, hist)
  }


avg (): Vec3 {
    if (!this._avg) {
      let { hist } = this
      let { r1, r2, g1, g2, b1, b2 } = this.dimension
      let ntot = 0
      let mult = 1 << (8 - SIGBITS)
      let rsum: number
      let gsum: number
      let bsum: number
      rsum = gsum = bsum = 0

      for (let r = r1; r <= r2; r++) {
        for (let g = g1; g <= g2; g++) {
          for (let b = b1; b <= b2; b++) {
            var index = getColorIndex(r, g, b)
            var h = hist[index]
            ntot += h
            rsum += (h * (r + 0.5) * mult)
            gsum += (h * (g + 0.5) * mult)
            bsum += (h * (b + 0.5) * mult)
          }
        }
      }
      if (ntot) {
        this._avg = [
          ~~(rsum / ntot),
          ~~(gsum / ntot),
          ~~(bsum / ntot)
        ]
      } else {
        this._avg = [
          ~~(mult * (r1 + r2 + 1) / 2),
          ~~(mult * (g1 + g2 + 1) / 2),
          ~~(mult * (b1 + b2 + 1) / 2)
        ]
      }
    }
    return this._avg
  }


contains (rgb: Vec3): boolean {
    let [r, g, b] = rgb
    let { r1, r2, g1, g2, b1, b2 } = this.dimension
    r >>= RSHIFT
    g >>= RSHIFT
    b >>= RSHIFT

    return r >= r1 && r <= r2 &&
      g >= g1 && g <= g2 &&
      b >= b1 && b <= b2
  }


split (): VBox[] {
    let { hist } = this
    let { r1, r2, g1, g2, b1, b2 } = this.dimension
    let count = this.count()
    if (!count) return []
    if (count === 1) return [this.clone()]
    let rw = r2 - r1 + 1
    let gw = g2 - g1 + 1
    let bw = b2 - b1 + 1

    let maxw = Math.max(rw, gw, bw)
    let accSum: Uint32Array | null = null
    let sum: number
    let total: number
    sum = total = 0

    let maxd: 'r' | 'g' | 'b' | null = null

    if (maxw === rw) {
      maxd = 'r'
      accSum = new Uint32Array(r2 + 1)
      for (let r = r1; r <= r2; r++) {
        sum = 0
        for (let g = g1; g <= g2; g++) {
          for (let b = b1; b <= b2; b++) {
            let index = getColorIndex(r, g, b)
            sum += hist[index]
          }
        }
        total += sum
        accSum[r] = total
      }
    } else if (maxw === gw) {
      maxd = 'g'
      accSum = new Uint32Array(g2 + 1)
      for (let g = g1; g <= g2; g++) {
        sum = 0
        for (let r = r1; r <= r2; r++) {
          for (let b = b1; b <= b2; b++) {
            let index = getColorIndex(r, g, b)
            sum += hist[index]
          }
        }
        total += sum
        accSum[g] = total
      }
    } else {
      maxd = 'b'
      accSum = new Uint32Array(b2 + 1)
      for (let b = b1; b <= b2; b++) {
        sum = 0
        for (let r = r1; r <= r2; r++) {
          for (let g = g1; g <= g2; g++) {
            let index = getColorIndex(r, g, b)
            sum += hist[index]
          }
        }
        total += sum
        accSum[b] = total
      }
    }

    let splitPoint = -1
    let reverseSum = new Uint32Array(accSum.length)
    for (let i = 0; i < accSum.length; i++) {
      let d = accSum[i]
      if (splitPoint < 0 && d > total / 2) splitPoint = i
      reverseSum[i] = total - d
    }

    let vbox = this

    function doCut (d: string): VBox[] {
      let dim1 = d + '1'
      let dim2 = d + '2'
      let d1 = vbox.dimension[dim1]
      let d2 = vbox.dimension[dim2]
      let vbox1 = vbox.clone()
      let vbox2 = vbox.clone()
      let left = splitPoint - d1
      let right = d2 - splitPoint
      if (left <= right) {
        d2 = Math.min(d2 - 1, ~~(splitPoint + right / 2))
        d2 = Math.max(0, d2)
      } else {
        d2 = Math.max(d1, ~~(splitPoint - 1 - left / 2))
        d2 = Math.min(vbox.dimension[dim2], d2)
      }

      while (!accSum![d2]) d2++

      let c2 = reverseSum[d2]
      while (!c2 && accSum![d2 - 1]) c2 = reverseSum[--d2]

      vbox1.dimension[dim2] = d2
      vbox2.dimension[dim1] = d2 + 1

      return [vbox1, vbox2]
    }

    return doCut(maxd)
  }


@Component({
  selector: "div[check-list-item]",
  templateUrl: "./check-list-item.component.html",
  styleUrls: ["./check-list-item.component.less"],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CheckListItemComponent extends BaseElementComponent implements OnInit {
  static type = 'check-list-item';

  constructor(
    @Inject(KEY_TOKEN) readonly key: Key,
    public deps: NsDepsService,
    public editorService: NsEditorService,
    public elementRef: ElementRef,
    public cdr: ChangeDetectorRef,
  ) {
    super(key, deps, editorService, elementRef, cdr);
  }

  ngOnInit(): void {
    this.init();
    this.watchDeps();
  }

  handleCheckboxChange($event: any) {
    const path = AngularEditor.findPath(this.editorService.editor, this.cNode);
    const newProperties: Partial<SlateElement & {checked: boolean}> = {
      checked: $event.target?.checked
    };
    Transforms.setNodes(this.editorService.editor, newProperties, { at: path });
  }
}


ngOnInit(): void {
    this.init();
    this.watchDeps();
  }


handleCheckboxChange($event: any) {
    const path = AngularEditor.findPath(this.editorService.editor, this.cNode);
    const newProperties: Partial<SlateElement & {checked: boolean}> = {
      checked: $event.target?.checked
    };
    Transforms.setNodes(this.editorService.editor, newProperties, { at: path });
  }


async (context, req, res) =>
      res.ok({ body: { version: '0.0.1' } })


async (context, req, res): Promise<RequestHandlerContext['core']> => {
        const savedObjectsClient = this.coreStart!.savedObjects.getScopedClient(req);
        const uiSettingsClient = coreSetup.uiSettings.asScopedToClient(savedObjectsClient);

        return {
          rendering: {
            render: async (options = {}) =>
              rendering.render(req, uiSettingsClient, {
                ...options,
                vars: await this.legacy.legacyInternals!.getVars('core', req),
              }),
          },
          savedObjects: {
            client: savedObjectsClient,
            typeRegistry: this.coreStart!.savedObjects.getTypeRegistry(),
          },
          elasticsearch: {
            adminClient: coreSetup.elasticsearch.adminClient.asScoped(req),
            dataClient: coreSetup.elasticsearch.dataClient.asScoped(req),
          },
          uiSettings: {
            client: uiSettingsClient,
          },
        };
      }


async (options = {}) =>
              rendering.render(req, uiSettingsClient, {
                ...options,
                vars: await this.legacy.legacyInternals!.getVars('core', req),
              })


public async setup() {
    this.log.debug('setting up server');

    // Discover any plugins before continuing. This allows other systems to utilize the plugin dependency graph.
    const pluginDependencies = await this.plugins.discover();
    const legacyPlugins = await this.legacy.discoverPlugins();

    // Immediately terminate in case of invalid configuration
    await this.configService.validate();
    await ensureValidConfiguration(this.configService, legacyPlugins);

    const contextServiceSetup = this.context.setup({
      // We inject a fake "legacy plugin" with dependencies on every plugin so that legacy plugins:
      // 1) Can access context from any NP plugin
      // 2) Can register context providers that will only be available to other legacy plugins and will not leak into
      //    New Platform plugins.
      pluginDependencies: new Map([
        ...pluginDependencies,
        [this.legacy.legacyId, [...pluginDependencies.keys()]],
      ]),
    });

    const uuidSetup = await this.uuid.setup();

    const httpSetup = await this.http.setup({
      context: contextServiceSetup,
    });

    this.registerDefaultRoute(httpSetup);

    const capabilitiesSetup = this.capabilities.setup({ http: httpSetup });

    const elasticsearchServiceSetup = await this.elasticsearch.setup({
      http: httpSetup,
    });

    const savedObjectsSetup = await this.savedObjects.setup({
      http: httpSetup,
      elasticsearch: elasticsearchServiceSetup,
      legacyPlugins,
    });

    const uiSettingsSetup = await this.uiSettings.setup({
      http: httpSetup,
      savedObjects: savedObjectsSetup,
    });

    const metricsSetup = await this.metrics.setup({ http: httpSetup });

    const coreSetup: InternalCoreSetup = {
      capabilities: capabilitiesSetup,
      context: contextServiceSetup,
      elasticsearch: elasticsearchServiceSetup,
      http: httpSetup,
      uiSettings: uiSettingsSetup,
      savedObjects: savedObjectsSetup,
      uuid: uuidSetup,
      metrics: metricsSetup,
    };

    const pluginsSetup = await this.plugins.setup(coreSetup);

    const renderingSetup = await this.rendering.setup({
      http: httpSetup,
      legacyPlugins,
      plugins: pluginsSetup,
    });

    await this.legacy.setup({
      core: { ...coreSetup, plugins: pluginsSetup, rendering: renderingSetup },
      plugins: mapToObject(pluginsSetup.contracts),
    });

    this.registerCoreContext(coreSetup, renderingSetup);

    return coreSetup;
  }


public async start() {
    this.log.debug('starting server');
    const savedObjectsStart = await this.savedObjects.start({});
    const capabilitiesStart = this.capabilities.start();
    const uiSettingsStart = await this.uiSettings.start();

    const pluginsStart = await this.plugins.start({
      capabilities: capabilitiesStart,
      savedObjects: savedObjectsStart,
      uiSettings: uiSettingsStart,
    });

    this.coreStart = {
      capabilities: capabilitiesStart,
      savedObjects: savedObjectsStart,
      uiSettings: uiSettingsStart,
    };

    await this.legacy.start({
      core: {
        ...this.coreStart,
        plugins: pluginsStart,
      },
      plugins: mapToObject(pluginsStart.contracts),
    });

    await this.http.start();
    await this.rendering.start();
    await this.metrics.start();

    return this.coreStart;
  }


public async stop() {
    this.log.debug('stopping server');

    await this.legacy.stop();
    await this.plugins.stop();
    await this.savedObjects.stop();
    await this.elasticsearch.stop();
    await this.http.stop();
    await this.uiSettings.stop();
    await this.rendering.stop();
    await this.metrics.stop();
  }


private registerDefaultRoute(httpSetup: InternalHttpServiceSetup) {
    const router = httpSetup.createRouter('/core');
    router.get({ path: '/', validate: false }, async (context, req, res) =>
      res.ok({ body: { version: '0.0.1' } })
    );
  }


private registerCoreContext(coreSetup: InternalCoreSetup, rendering: RenderingServiceSetup) {
    coreSetup.http.registerRouteHandlerContext(
      coreId,
      'core',
      async (context, req, res): Promise<RequestHandlerContext['core']> => {
        const savedObjectsClient = this.coreStart!.savedObjects.getScopedClient(req);
        const uiSettingsClient = coreSetup.uiSettings.asScopedToClient(savedObjectsClient);

        return {
          rendering: {
            render: async (options = {}) =>
              rendering.render(req, uiSettingsClient, {
                ...options,
                vars: await this.legacy.legacyInternals!.getVars('core', req),
              }),
          },
          savedObjects: {
            client: savedObjectsClient,
            typeRegistry: this.coreStart!.savedObjects.getTypeRegistry(),
          },
          elasticsearch: {
            adminClient: coreSetup.elasticsearch.adminClient.asScoped(req),
            dataClient: coreSetup.elasticsearch.dataClient.asScoped(req),
          },
          uiSettings: {
            client: uiSettingsClient,
          },
        };
      }
    );
  }


public async setupCoreConfig() {
    const schemas: Array<[ConfigPath, Type<unknown>]> = [
      [pathConfig.path, pathConfig.schema],
      [cspConfig.path, cspConfig.schema],
      [elasticsearchConfig.path, elasticsearchConfig.schema],
      [loggingConfig.path, loggingConfig.schema],
      [httpConfig.path, httpConfig.schema],
      [pluginsConfig.path, pluginsConfig.schema],
      [devConfig.path, devConfig.schema],
      [kibanaConfig.path, kibanaConfig.schema],
      [savedObjectsConfig.path, savedObjectsConfig.schema],
      [savedObjectsMigrationConfig.path, savedObjectsMigrationConfig.schema],
      [uiSettingsConfig.path, uiSettingsConfig.schema],
      [opsConfig.path, opsConfig.schema],
    ];

    this.configService.addDeprecationProvider(rootConfigPath, coreDeprecationProvider);
    this.configService.addDeprecationProvider(
      elasticsearchConfig.path,
      elasticsearchConfig.deprecations!
    );
    this.configService.addDeprecationProvider(
      uiSettingsConfig.path,
      uiSettingsConfig.deprecations!
    );

    for (const [path, schema] of schemas) {
      await this.configService.setSchema(path, schema);
    }
  }


class HtmlRenderer {
  private readonly templates: { [key: string]: Template }

  constructor() {
    this.templates = {}
  }

  public addTemplate(template: Template): void {
    if (this.templates[template.getId()]) {
      throw new Error(`Template with key "${template.getId()}" already exists.`)
    }

    this.templates[template.getId()] = template
  }

  public getTemplate(key: string): Template {
    if (!this.templates[key]) {
      throw new Error(`Template with key "${key}" does not exists.`)
    }

    return this.templates[key]
  }

  public getIds(): Array<string> {
    return Object.keys(this.templates)
  }

  public render(key: string, data: Record<string, unknown> = {}): string {
    const template = this.getTemplate(key)

    const errors = template.validate(data)

    if (errors.length) {
      throw new ValidationError(`Template with key "${key}" is not valid.`, errors)
    }

    return pug.renderFile(template.getPath(), { cache: true, ...data })
  }
}


public addTemplate(template: Template): void {
    if (this.templates[template.getId()]) {
      throw new Error(`Template with key "${template.getId()}" already exists.`)
    }

    this.templates[template.getId()] = template
  }


public getTemplate(key: string): Template {
    if (!this.templates[key]) {
      throw new Error(`Template with key "${key}" does not exists.`)
    }

    return this.templates[key]
  }


public getIds(): Array<string> {
    return Object.keys(this.templates)
  }


public render(key: string, data: Record<string, unknown> = {}): string {
    const template = this.getTemplate(key)

    const errors = template.validate(data)

    if (errors.length) {
      throw new ValidationError(`Template with key "${key}" is not valid.`, errors)
    }

    return pug.renderFile(template.getPath(), { cache: true, ...data })
  }


export class SidenavItem {
  name: string;
  icon?: string;
  routeOrFunction?: any;
  parent?: SidenavItem;
  subItems?: SidenavItem[];
  position?: number;
  pathMatchExact?: boolean;
  badge?: string;
  badgeColor?: string;
}


export declare class KinveyError extends Error {
    debug: string;
    constructor(message?: string, debug?: string);
}


// Declare state
export type State = typeof state;


export function activate(_context: vscode.ExtensionContext) {
	// Set context as a global as some tests depend on it
	(global as any).testExtensionContext = _context;
}


function getTarget(): vscode.ConfigurationTarget {
    return (vscode.workspace.workspaceFolders) ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Global;
}


class Settings {
    private readonly settings: vscode.WorkspaceConfiguration;

    /**
     * create the Settings object.
     * @param resource The path to a resource to which the settings should apply, or undefined if global settings are desired
     */
    constructor(section: string, resource?: vscode.Uri) {
        this.settings = vscode.workspace.getConfiguration(section, resource ? resource : null);
    }

    protected get Section(): vscode.WorkspaceConfiguration { return this.settings; }
}


export class CppSettings extends Settings {
    constructor(resource?: vscode.Uri) {
        super("C_Cpp", resource);
    }

    public get clangFormatPath(): string { return super.Section.get<string>("clang_format_path"); }
    public get clangFormatStyle(): string { return super.Section.get<string>("clang_format_style"); }
    public get clangFormatFallbackStyle(): string { return super.Section.get<string>("clang_format_fallbackStyle"); }
    public get clangFormatSortIncludes(): string { return super.Section.get<string>("clang_format_sortIncludes"); }
    public get clangFormatOnSave(): string { return super.Section.get<string>("clang_format_formatOnSave"); }
    public get formatting(): string { return super.Section.get<string>("formatting"); }
    public get experimentalFeatures(): string { return super.Section.get<string>("experimentalFeatures"); }
    public get suggestSnippets(): boolean { return super.Section.get<boolean>("suggestSnippets"); }
    public get intelliSenseEngine(): string { return super.Section.get<string>("intelliSenseEngine"); }
    public get intelliSenseEngineFallback(): string { return super.Section.get<string>("intelliSenseEngineFallback"); }
    public get intelliSenseCachePath(): string { return super.Section.get<string>("intelliSenseCachePath"); }
    public get intelliSenseCacheSize(): number { return super.Section.get<number>("intelliSenseCacheSize"); }
    public get errorSquiggles(): string { return super.Section.get<string>("errorSquiggles"); }
    public get inactiveRegionOpacity(): number { return super.Section.get<number>("inactiveRegionOpacity"); }
    public get inactiveRegionForegroundColor(): string { return super.Section.get<string>("inactiveRegionForegroundColor"); }
    public get inactiveRegionBackgroundColor(): string { return super.Section.get<string>("inactiveRegionBackgroundColor"); }
    public get autoComplete(): string { return super.Section.get<string>("autocomplete"); }
    public get loggingLevel(): string { return super.Section.get<string>("loggingLevel"); }
    public get navigationLength(): number { return super.Section.get<number>("navigation.length", 60); }
    public get autoAddFileAssociations(): boolean { return super.Section.get<boolean>("autoAddFileAssociations"); }
    public get workspaceParsingPriority(): string { return super.Section.get<string>("workspaceParsingPriority"); }
    public get workspaceSymbols(): string { return super.Section.get<string>("workspaceSymbols"); }
    public get exclusionPolicy(): string { return super.Section.get<string>("exclusionPolicy"); }
    public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); }
    public get configurationWarnings(): string { return super.Section.get<string>("configurationWarnings"); }
    public get preferredPathSeparator(): string { return super.Section.get<string>("preferredPathSeparator"); }
    public get updateChannel(): string { return super.Section.get<string>("updateChannel"); }
    public get vcpkgEnabled(): boolean { return super.Section.get<boolean>("vcpkg.enabled"); }
    public get renameRequiresIdentifier(): boolean { return super.Section.get<boolean>("renameRequiresIdentifier"); }
    public get defaultIncludePath(): string[] { return super.Section.get<string[]>("default.includePath"); }
    public get defaultDefines(): string[] { return super.Section.get<string[]>("default.defines"); }
    public get defaultMacFrameworkPath(): string[] { return super.Section.get<string[]>("default.macFrameworkPath"); }
    public get defaultWindowsSdkVersion(): string { return super.Section.get<string>("default.windowsSdkVersion"); }
    public get defaultCompileCommands(): string { return super.Section.get<string>("default.compileCommands"); }
    public get defaultForcedInclude(): string[] { return super.Section.get<string[]>("default.forcedInclude"); }
    public get defaultIntelliSenseMode(): string { return super.Section.get<string>("default.intelliSenseMode"); }
    public get defaultCompilerPath(): string { return super.Section.get<string>("default.compilerPath"); }
    public get defaultCompilerArgs(): string[] { return super.Section.get<string[]>("default.compilerArgs"); }
    public get defaultCStandard(): string { return super.Section.get<string>("default.cStandard"); }
    public get defaultCppStandard(): string { return super.Section.get<string>("default.cppStandard"); }
    public get defaultConfigurationProvider(): string { return super.Section.get<string>("default.configurationProvider"); }
    public get defaultBrowsePath(): string[] { return super.Section.get<string[]>("default.browse.path"); }
    public get defaultDatabaseFilename(): string { return super.Section.get<string>("default.browse.databaseFilename"); }
    public get defaultLimitSymbolsToIncludedHeaders(): boolean { return super.Section.get<boolean>("default.browse.limitSymbolsToIncludedHeaders"); }
    public get defaultSystemIncludePath(): string[] { return super.Section.get<string[]>("default.systemIncludePath"); }
    public get defaultEnableConfigurationSquiggles(): boolean { return super.Section.get<boolean>("default.enableConfigurationSquiggles"); }

    public get enhancedColorization(): boolean {
        return super.Section.get<string>("enhancedColorization") === "Enabled"
            && super.Section.get<string>("intelliSenseEngine") === "Default"
            && vscode.workspace.getConfiguration("workbench").get<string>("colorTheme") !== "Default High Contrast";
    }

    public get dimInactiveRegions(): boolean {
        return super.Section.get<boolean>("dimInactiveRegions")
            && super.Section.get<string>("intelliSenseEngine") === "Default"
            && vscode.workspace.getConfiguration("workbench").get<string>("colorTheme") !== "Default High Contrast";
    }

    public toggleSetting(name: string, value1: string, value2: string): void {
        let value: string = super.Section.get<string>(name);
        super.Section.update(name, value === value1 ? value2 : value1, getTarget());
    }
    public update<T>(name: string, value: T): void {
        super.Section.update(name, value);
    }
}


export class OtherSettings {
    private resource: vscode.Uri;

    constructor(resource?: vscode.Uri) {
        if (!resource) {
            resource = null;
        }
        this.resource = resource;
    }

    public get editorTabSize(): number { return vscode.workspace.getConfiguration("editor", this.resource).get<number>("tabSize"); }
    public get filesAssociations(): any { return vscode.workspace.getConfiguration("files", null).get("associations"); }
    public set filesAssociations(value: any) {
        vscode.workspace.getConfiguration("files", null).update("associations", value, vscode.ConfigurationTarget.Workspace);
    }
    public get filesExclude(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration("files", this.resource).get("exclude"); }
    public get searchExclude(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration("search", this.resource).get("exclude"); }
    public get settingsEditor(): string { return vscode.workspace.getConfiguration("workbench.settings").get<string>("editor"); }

    public get colorTheme(): string { return vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"); }

    public getCustomColorToken(colorTokenName: string): string { return vscode.workspace.getConfiguration("editor.tokenColorCustomizations").get<string>(colorTokenName); }
    public getCustomThemeSpecificColorToken(themeName: string, colorTokenName: string): string { return vscode.workspace.getConfiguration(`editor.tokenColorCustomizations.[${themeName}]`, this.resource).get<string>(colorTokenName); }

    public get customTextMateRules(): TextMateRule[] { return vscode.workspace.getConfiguration("editor.tokenColorCustomizations").get<TextMateRule[]>("textMateRules"); }
    public getCustomThemeSpecificTextMateRules(themeName: string): TextMateRule[] { return vscode.workspace.getConfiguration(`editor.tokenColorCustomizations.[${themeName}]`, this.resource).get<TextMateRule[]>("textMateRules"); }
}


export interface TextMateRuleSettings {
    foreground: string | undefined;
    background: string | undefined;
    fontStyle: string | undefined;
}


export interface TextMateRule {
    scope: any;
    settings: TextMateRuleSettings;
}


public toggleSetting(name: string, value1: string, value2: string): void {
        let value: string = super.Section.get<string>(name);
        super.Section.update(name, value === value1 ? value2 : value1, getTarget());
    }


public update<T>(name: string, value: T): void {
        super.Section.update(name, value);
    }


public getCustomColorToken(colorTokenName: string): string { return vscode.workspace.getConfiguration("editor.tokenColorCustomizations").get<string>(colorTokenName); }


public getCustomThemeSpecificColorToken(themeName: string, colorTokenName: string): string { return vscode.workspace.getConfiguration(`editor.tokenColorCustomizations.[${themeName}]`, this.resource).get<string>(colorTokenName); }


public getCustomThemeSpecificTextMateRules(themeName: string): TextMateRule[] { return vscode.workspace.getConfiguration(`editor.tokenColorCustomizations.[${themeName}]`, this.resource).get<TextMateRule[]>("textMateRules"); }


({ message, date, category, messageType }) => {
        this.databaseService.insertLogs(date, message, messageType, category);
      }


() =>
      console.log(this.nsUrl2 + "fffffffff3333333f")


r => {
      console.log("Dialog closed!" + r.result + ", A TO TEKST:" + r.text);
      this.range = Number(r.text);
      if(this.range < 80 || this.range > 120){
 dialogs.alert({message: "BG VALUE OUT OF ACCEPTABLE RANGE: 80 - 120 mg/dl", okButtonText: "OK"});
      }
      else {
        appSettings.setNumber('range', this.range);
        this.rangeText = "AUTO STOP AT BG VALUE: " + this.range + " MG/DL";
      }

    }


r => {
      console.log("Dialog closed!" + r.result + ", A TO TEKST:" + r.text);
      if (r.text === '') {
        appSettings.setString('phoneN', 'ENTER PHONE NUMBER');
        this.phoneN = 'ENTER PHONE NUMBER';
      }
      else {
        Permissions.requestPermission(
          android.Manifest.permission.SEND_SMS, "zezwolic na czytanie SMS?"
        ).then(() => Permissions.requestPermission(android.Manifest.permission.READ_SMS));
        appSettings.setString('phoneN', r.text);
        this.phoneN = 'PHONE: ' + r.text;
      }
    }


() => Permissions.requestPermission(android.Manifest.permission.READ_SMS)


() => {
    if (a.isAlive() === false){
      clearInterval(u);
      console.log("CIOSs");
      Permissions.requestPermission(
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
      ).then(() =>
        compose({
          subject: "Debug med-link-ui",
          body: "aReduced2",
          to: ["jrkf@o2.pl"],
                    attachments:
                      [{
                        mimeType: 'text',
                        path: myFile.path,
                        fileName: 'my.txt'
                      }]
        })
      )
    }
    else {
      console.log("BAM BAM");
    }
    }


() =>
        compose({
          subject: "Debug med-link-ui",
          body: "aReduced2",
          to: ["jrkf@o2.pl"],
                    attachments:
                      [{
                        mimeType: 'text',
                        path: myFile.path,
                        fileName: 'my.txt'
                      }]
        })


() =>
      console.log(this.slowo + "aRRRRRRRRRR")


(resolve, reject) => {
      this.getNSData().subscribe(g => {
        g.map(bol => {
          console.log(bol.http.toString() + "JJJJJJJ" + bol.secret.toString());
          this.slowo =
            this.slowo2 +
            "  " +
            bol.http.toString() +
            " " +
            bol.secret.toString();
        });
        console.log("as" + this.slowo);
        resolve(), reject();
      });
    }


g => {
        g.map(bol => {
          console.log(bol.http.toString() + "JJJJJJJ" + bol.secret.toString());
          this.slowo =
            this.slowo2 +
            "  " +
            bol.http.toString() +
            " " +
            bol.secret.toString();
        });
        console.log("as" + this.slowo);
        resolve(), reject();
      }


bol => {
          console.log(bol.http.toString() + "JJJJJJJ" + bol.secret.toString());
          this.slowo =
            this.slowo2 +
            "  " +
            bol.http.toString() +
            " " +
            bol.secret.toString();
        }


(resolve, reject) => {
      this.getNSData().subscribe(g => {
        g.map(bol => {
          console.log(
            bol.http.toString() + "66666666666" + bol.secret.toString()
          );
          this.nsUrl2 = bol.http.toString();
          this.nsKey2 = bol.hash.toString();
        });
        console.log("as" + this.nsUrl2);
        resolve(), reject();
      });
    }


g => {
        g.map(bol => {
          console.log(
            bol.http.toString() + "66666666666" + bol.secret.toString()
          );
          this.nsUrl2 = bol.http.toString();
          this.nsKey2 = bol.hash.toString();
        });
        console.log("as" + this.nsUrl2);
        resolve(), reject();
      }


bol => {
          console.log(
            bol.http.toString() + "66666666666" + bol.secret.toString()
          );
          this.nsUrl2 = bol.http.toString();
          this.nsKey2 = bol.hash.toString();
        }


rows => {
        return rows.map(a => ({
          http: a[0],
          secret: a[1],
          hash: a[2]
        }));
      }


a => ({
          http: a[0],
          secret: a[1],
          hash: a[2]
        })


ngOnInit(): void {
    this.phoneN = 'PHONE: ' + appSettings.getString('phoneN', 'ENTER PHONE NUMBER');
    this.auto = appSettings.getBoolean('auto', false);
    this.bgSource = appSettings.getBoolean('bgsource', false);
    this.rangeText = "AUTO STOP AT BG VALUE: " + appSettings.getNumber('range', 80) + " MG/DL";
    this.traceWriterService.subscribe(
      ({ message, date, category, messageType }) => {
        this.databaseService.insertLogs(date, message, messageType, category);
      }
    );
    this.sendDatatoNightscout7().then(() =>
      console.log(this.nsUrl2 + "fffffffff3333333f")
    );
  }


getBGRange(){
    dialogs.prompt({
      title: "ENTER LIMIT BG VALUE TO SUSPEND PUMP",
      message: "LIMIT BG VALUE IS:",
      okButtonText: "OK",
      cancelButtonText: "CANCEL",
      inputType: dialogs.inputType.number
    }).then(r => {
      console.log("Dialog closed!" + r.result + ", A TO TEKST:" + r.text);
      this.range = Number(r.text);
      if(this.range < 80 || this.range > 120){
 dialogs.alert({message: "BG VALUE OUT OF ACCEPTABLE RANGE: 80 - 120 mg/dl", okButtonText: "OK"});
      }
      else {
        appSettings.setNumber('range', this.range);
        this.rangeText = "AUTO STOP AT BG VALUE: " + this.range + " MG/DL";
      }

    });
}


setPhoneNumber(){
    dialogs.prompt({
      title: "ENTER PHONE NUMBER",
      message: "Enter parent or guardian phone number for remote SMS commands: START, STOP, BOLUS",
      okButtonText: "OK",
      cancelButtonText: "CANCEL",
      inputType: dialogs.inputType.number
    }).then(r => {
      console.log("Dialog closed!" + r.result + ", A TO TEKST:" + r.text);
      if (r.text === '') {
        appSettings.setString('phoneN', 'ENTER PHONE NUMBER');
        this.phoneN = 'ENTER PHONE NUMBER';
      }
      else {
        Permissions.requestPermission(
          android.Manifest.permission.SEND_SMS, "zezwolic na czytanie SMS?"
        ).then(() => Permissions.requestPermission(android.Manifest.permission.READ_SMS));
        appSettings.setString('phoneN', r.text);
        this.phoneN = 'PHONE: ' + r.text;
      }
    });
  }


sendLogs() {
    const documents = fs.path.join(android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString());
    const myFolder = fs.Folder.fromPath(documents);
    const myFile = myFolder.getFile("my.txt");
    const a = Runtime.getRuntime().exec('logcat -v time -f /sdcard/my.txt -d');
    console.log("to ta wielkosc pliku: " + myFile.size);
    if (myFile.size > 2000000 )
    {
      myFile.remove();
    }

    const u = setInterval( () => {
    if (a.isAlive() === false){
      clearInterval(u);
      console.log("CIOSs");
      Permissions.requestPermission(
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
      ).then(() =>
        compose({
          subject: "Debug med-link-ui",
          body: "aReduced2",
          to: ["jrkf@o2.pl"],
                    attachments:
                      [{
                        mimeType: 'text',
                        path: myFile.path,
                        fileName: 'my.txt'
                      }]
        })
      )
    }
    else {
      console.log("BAM BAM");
    }
    }, 500);
  }


Zapisz() {
    console.log("aaaaaa" + this.nsUrl);
    const sha1 = require("sha1");
    this.databaseService.insertNS(this.nsUrl, sha1(this.nsKey), this.nsKey);
    console.log("NS URL: " + this.nsUrl + " ddddddddddd " + this.nsKey);
    this.sendDatatoNightscout6().then(() =>
      console.log(this.slowo + "aRRRRRRRRRR")
    );
    if (
      this.nsUrl.substring(0, 4).toUpperCase() !== "HTTP" ||
      this.nsUrl.substring(this.nsUrl.length - 1, this.nsUrl.length) === "/"
    ) {
      this.slowo2 = "INCORRECT URL!";
    } else {
      this.slowo2 = "OK! ";
    }
  }