() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-11-30T00:00:00.000Z")
  const endDate1 = undefined
  const startDate2 = new Date("2020-10-31T00:00:00.000Z")
  const endDate2 = new Date("2021-09-30T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = undefined
  const endDate2 = new Date("2020-09-30T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = undefined
  const endDate2 = new Date("2022-09-30T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = undefined
  const endDate2 = new Date("2019-09-30T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-11-30T00:00:00.000Z")
  const endDate2 = undefined
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = new Date("2020-12-01T00:00:00.000Z")
  const endDate2 = undefined
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = new Date("2018-12-01T00:00:00.000Z")
  const endDate2 = undefined
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2018-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-12-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2018-10-31T00:00:00.000Z")
  const endDate1 = new Date("2021-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-12-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2020-10-31T00:00:00.000Z")
  const endDate1 = new Date("2020-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-12-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2020-10-31T00:00:00.000Z")
  const endDate1 = new Date("2021-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-12-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2020-10-31T00:00:00.000Z")
  const endDate1 = new Date("2021-11-30T00:00:00.000Z")
  const startDate2 = new Date("2019-11-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-10-31T00:00:00.000Z")
  const startDate2 = new Date("2019-11-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2018-11-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2018-11-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2019-11-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2019-11-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2020-11-01T00:00:00.000Z")
  const endDate2 = new Date("2020-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2018-11-01T00:00:00.000Z")
  const endDate2 = new Date("2018-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2020-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2018-11-01T00:00:00.000Z")
  const endDate2 = new Date("2018-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2020-11-01T00:00:00.000Z")
  const endDate2 = new Date("2018-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(false)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-10-01T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2019-10-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-09-30T00:00:00.000Z")
  const endDate1 = new Date("2019-12-31T00:00:00.000Z")
  const startDate2 = new Date("2019-10-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-31T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-09-30T00:00:00.000Z")
  const endDate1 = new Date("2019-09-30T00:00:00.000Z")
  const startDate2 = new Date("2018-10-01T00:00:00.000Z")
  const endDate2 = new Date("2019-12-31T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const startDate1 = new Date("2019-09-30T00:00:00.000Z")
  const endDate1 = new Date("2019-10-30T00:00:00.000Z")
  const startDate2 = new Date("2019-10-01T00:00:00.000Z")
  const endDate2 = new Date("2019-10-01T00:00:00.000Z")
  expect(dateRangesOverlapping(startDate1, endDate1, startDate2, endDate2)).toEqual(true)
}


() => {
  expect.hasAssertions()
  const returnedDate: Date = getDateObject('2018-02-25')
  expect(returnedDate.getFullYear()).toEqual(2018)
  // month is returned in form of 0-11 so need to adjust accordingly
  expect(returnedDate.getMonth()).toEqual(1)
  expect(returnedDate.getDate()).toEqual(25)
}


() => {
  expect.hasAssertions()
  const returnedDate: Date = getDateObject('02/25/2018')
  expect(returnedDate.getFullYear()).toEqual(2018)
  // month is returned in form of 0-11 so need to adjust accordingly
  expect(returnedDate.getMonth()).toEqual(1)
  expect(returnedDate.getDate()).toEqual(25)
}


@Component({
  selector: 'app-followers',
  templateUrl: './followers.page.html',
  styleUrls: ['./followers.page.scss'],
})
export class FollowersPage implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


export default function Toggle() {
  const { action, state } = useStateMachine(updateSetting)
  const lightMode = state?.setting?.lightMode

  const onChange = (e) => {
    action({
      lightMode: e.target.checked,
    })

    if (e.target.checked) {
      document.querySelector("body").classList.add("light")
    } else {
      document.querySelector("body").classList.remove("light")
    }
  }

  return (
    <label htmlFor="toggle" className={styles.switch}>
      <input
        id="toggle"
        type="checkbox"
        onChange={onChange}
        defaultChecked={lightMode}
      />
      <span className={`${styles.slider} ${styles.round}`} />
    </label>
  )
}


(e) => {
    action({
      lightMode: e.target.checked,
    })

    if (e.target.checked) {
      document.querySelector("body").classList.add("light")
    } else {
      document.querySelector("body").classList.remove("light")
    }
  }


@Injectable()
export class ConfirmService {

  constructor(private matDialog: MatDialog) {
  }

  showDialog(message: string = ''): Observable<boolean> {
    const dialogRef = this.matDialog.open(ConfirmDialogComponent, {
      data: message
    });
    return dialogRef.afterClosed();
  }
}


showDialog(message: string = ''): Observable<boolean> {
    const dialogRef = this.matDialog.open(ConfirmDialogComponent, {
      data: message
    });
    return dialogRef.afterClosed();
  }


item => {
            this.case=item;
            console.log(this.case);
            console.log(item);
            this.Type=item.type;

         }


data =>{
      console.log(data);
    }


@Component({
  selector: 'app-plan-view',
  templateUrl: './plan-view.component.html',
  styleUrls: ['./plan-view.component.scss']
})
export class PlanViewComponent implements OnInit {
  Type='';
  RoleObject;
  BoundRole = '';
  ID: Number;
  case: CaseModel;
  nutriologistFlag = false;
  constructor(private AuthenticationService: AuthenticationService, private caseService: CaseService,private activatedRoute: ActivatedRoute,private router: Router) {

  }

  ngOnInit() {
    this.RoleObject = JSON.parse(localStorage.getItem('currentUser'));
    this.BoundRole = this.RoleObject.role;
    if(this.BoundRole == 'Nutriologist'){
      this.nutriologistFlag = true;
    }
    let itemID = this.activatedRoute.snapshot.queryParams["loadID"];
    this.ID = itemID;
    this.loadCaseToApprove(itemID);
    console.log(this.BoundRole);
  }
  loadCaseToApprove(itemID: number) {
    //let update
      this.caseService.getCaseById(itemID)
           .subscribe(item => {
            this.case=item;
            console.log(this.case);
            console.log(item);
            this.Type=item.type;

         })
  }
  approve(){
    this.caseService.approveCase(this.ID).subscribe(data =>{
      console.log(data);
    });
    this.router.navigate(['/nutriologistDashboard'])
  }
  logout(){
    this.AuthenticationService.logout();
    this.router.navigate(['/login']);
  }
}


ngOnInit() {
    this.RoleObject = JSON.parse(localStorage.getItem('currentUser'));
    this.BoundRole = this.RoleObject.role;
    if(this.BoundRole == 'Nutriologist'){
      this.nutriologistFlag = true;
    }
    let itemID = this.activatedRoute.snapshot.queryParams["loadID"];
    this.ID = itemID;
    this.loadCaseToApprove(itemID);
    console.log(this.BoundRole);
  }


loadCaseToApprove(itemID: number) {
    //let update
      this.caseService.getCaseById(itemID)
           .subscribe(item => {
            this.case=item;
            console.log(this.case);
            console.log(item);
            this.Type=item.type;

         })
  }


approve(){
    this.caseService.approveCase(this.ID).subscribe(data =>{
      console.log(data);
    });
    this.router.navigate(['/nutriologistDashboard'])
  }


logout(){
    this.AuthenticationService.logout();
    this.router.navigate(['/login']);
  }


export class UpdateTaskDTO extends Task {
  title: string;
  description?: string;
  completed: boolean;
}


function makeMP4Url(hlsUrl: string, profileName: string): string {
  const pp = hlsUrl.split("/");
  pp.pop();
  return pp.join("/") + "/" + profileName + ".mp4";
}


<D extends TableData>({
  cell,
}: CellComponentProps<D, RecordingUrlCellProps>) => {
  const id = cell.value.id;
  return (
    <Box id={`mp4-link-dropdown-${id}`}


({ title = "Sessions" }: { title?: string }) => {
  const { user, getStreamSessionsByUserId } = useApi();
  const tableProps = useTableState({
    tableId: "allSessionsTable",
  });
  const [openSnackbar] = useSnackbar();

  const columns: Column<SessionsTableData>[] = useMemo(
    () => [
      {
        Header: "Stream",
        accessor: "parentStream",
        Cell: TextCell,
        sortType: (...params: SortTypeArgs) =>
          stringSort("original.parentStream.name", ...params),
      },
      {
        Header: "Created at",
        accessor: "created",
        Cell: DateCell,
        sortType: (...params: SortTypeArgs) =>
          dateSort("original.created.date", ...params),
      },
      {
        Header: "Duration",
        accessor: "duration",
        Cell: DurationCell,
        sortType: (...params: SortTypeArgs) =>
          numberSort("original.duration.duration", ...params),
      },
      {
        Header: "Recording URL",
        accessor: "recordingUrl",
        Cell: RecordingUrlCell,
        disableSortBy: true,
      },
    ],
    []
  );

  const fetcher: Fetcher<SessionsTableData> = useCallback(
    async (state) => {
      const [streams, nextCursor, count] = await getStreamSessionsByUserId(
        user.id,
        state.cursor,
        state.pageSize,
        formatFiltersForApiRequest(state.filters, {
          parseNumber: (n) => n * 60,
        }),
        true
      );

      return {
        nextCursor,
        count,
        rows: streams.map((stream: any) => {
          return {
            id: stream.id,
            parentStream: {
              id: stream.parentId,
              name: stream.parentStream.name,
              children: (

                  {stream.parentStream.name}

              ),
              tooltipChildren: stream.createdByTokenName ? (
                <>
                  Created by stream {stream.parentStream.name}
                </>
              ) : null,
              href: `/dashboard/streams/${stream.parentId}`,
            }


() => [
      {
        Header: "Stream",
        accessor: "parentStream",
        Cell: TextCell,
        sortType: (...params: SortTypeArgs) =>
          stringSort("original.parentStream.name", ...params),
      },
      {
        Header: "Created at",
        accessor: "created",
        Cell: DateCell,
        sortType: (...params: SortTypeArgs) =>
          dateSort("original.created.date", ...params),
      },
      {
        Header: "Duration",
        accessor: "duration",
        Cell: DurationCell,
        sortType: (...params: SortTypeArgs) =>
          numberSort("original.duration.duration", ...params),
      },
      {
        Header: "Recording URL",
        accessor: "recordingUrl",
        Cell: RecordingUrlCell,
        disableSortBy: true,
      },
    ]


(...params: SortTypeArgs) =>
          stringSort("original.parentStream.name", ...params)


(...params: SortTypeArgs) =>
          dateSort("original.created.date", ...params)


(...params: SortTypeArgs) =>
          numberSort("original.duration.duration", ...params)


async (state) => {
      const [streams, nextCursor, count] = await getStreamSessionsByUserId(
        user.id,
        state.cursor,
        state.pageSize,
        formatFiltersForApiRequest(state.filters, {
          parseNumber: (n) => n * 60,
        }),
        true
      );

      return {
        nextCursor,
        count,
        rows: streams.map((stream: any) => {
          return {
            id: stream.id,
            parentStream: {
              id: stream.parentId,
              name: stream.parentStream.name,
              children: (

                  {stream.parentStream.name}

              ),
              tooltipChildren: stream.createdByTokenName ? (
                <>
                  Created by stream {stream.parentStream.name}
                </>


(n) => n * 60


(stream: any) => {
          return {
            id: stream.id,
            parentStream: {
              id: stream.parentId,
              name: stream.parentStream.name,
              children: (
                <A variant="violet" as={Box}>
                  {stream.parentStream.name}
                </A>


type Profile = { name: string; width: number; height: number };


export type RecordingUrlCellProps = {
  children?: React.ReactNode;
  tooltipChildren?: React.ReactNode;
  mp4Url?: string;
  id?: string;
  profiles?: Array<Profile>;
  showMP4: boolean;
};


type SessionsTableData = {
  id: string;
  parentStream: TextCellProps;
  recordingUrl: TextCellProps;
  created: DateCellProps;
  duration: DurationCellProps;
};


stream <b>{stream.parentStream.name}


truncate(stream


() => {
      console.log('Socket.IO connected');
      this.socket.emit('event', {test: 23})
    }


() => {
      console.log('Socket.IO disconnected');
    }


(...args) => {
      console.log('Received data', args);
    }


() => {
      alert('Login successful');
    }


() => {
      alert('Login failed');
    }


() => {
      alert('Someone else is the active controller. Please try again later');
    }


(base64Image: string, ts_drone_send: number, delta_rec: number, delta_proc: number, ts_cloud_send: number) => {
      const event = {
        buffer: base64Image,
        delta_proc: delta_proc,
        delta_rec: delta_rec,
        ts_cloud_send: ts_cloud_send,
        ts_drone_send: ts_drone_send
      };
      this.imageEmitter.emit('image', event);
    }


() => {
      window.open(downloadUrl, '_blank');
    }


@Injectable({
  providedIn: 'root'
})
export class CloudSocketService {

  private socket: io.Socket;
  imageEmitter: AngularImageEmitter;

  constructor() {
    console.log('Cloud socket constructor');
    this.imageEmitter = new AngularImageEmitter();

    // this.socket = io(environment.ioServer, {
    //   path: environment.ioPath
    // });
    this.socket = io(environment.ioServer);
    this.socket.on('connect', () => {
      console.log('Socket.IO connected');
      this.socket.emit('event', {test: 23})
    });

    this.socket.on('disconnect', () => {
      console.log('Socket.IO disconnected');
    });

    this.socket.on('response', (...args) => {
      console.log('Received data', args);
    });

    this.socket.on('controller-login', () => {
      alert('Login successful');
    });

    this.socket.on('login-error', () => {
      alert('Login failed');
    });

    this.socket.on('reject-controller', () => {
      alert('Someone else is the active controller. Please try again later');
    });

  }

  listen() {
    this.socket.on('image', (base64Image: string, ts_drone_send: number, delta_rec: number, delta_proc: number, ts_cloud_send: number) => {
      const event = {
        buffer: base64Image,
        delta_proc: delta_proc,
        delta_rec: delta_rec,
        ts_cloud_send: ts_cloud_send,
        ts_drone_send: ts_drone_send
      };
      this.imageEmitter.emit('image', event);
    });
  }

  login(secret: string) {
    this.socket.emit('login', secret);
  }

  sendCommand(acceleration: number, direction: number) {
    const now = Date.now();
    const message = {acceleration, direction, now};
    this.socket.emit('control-message', JSON.stringify(message));
  }

  startTracking() {
    this.socket.emit('start-track');
  }

  stopTracking() {
    this.socket.emit('stop-track');
  }

  startRec() {
    this.socket.emit('start-rec');
  }

  stopRec() {
    this.socket.emit('stop-rec');
    const downloadUrl = environment.ioServer + 'download-video';
    setTimeout(() => {
      window.open(downloadUrl, '_blank');
    }, 1000);
  }
}


listen() {
    this.socket.on('image', (base64Image: string, ts_drone_send: number, delta_rec: number, delta_proc: number, ts_cloud_send: number) => {
      const event = {
        buffer: base64Image,
        delta_proc: delta_proc,
        delta_rec: delta_rec,
        ts_cloud_send: ts_cloud_send,
        ts_drone_send: ts_drone_send
      };
      this.imageEmitter.emit('image', event);
    });
  }


login(secret: string) {
    this.socket.emit('login', secret);
  }


sendCommand(acceleration: number, direction: number) {
    const now = Date.now();
    const message = {acceleration, direction, now};
    this.socket.emit('control-message', JSON.stringify(message));
  }


startTracking() {
    this.socket.emit('start-track');
  }


stopTracking() {
    this.socket.emit('stop-track');
  }


startRec() {
    this.socket.emit('start-rec');
  }


stopRec() {
    this.socket.emit('stop-rec');
    const downloadUrl = environment.ioServer + 'download-video';
    setTimeout(() => {
      window.open(downloadUrl, '_blank');
    }, 1000);
  }


@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private router: Router) { }

  canActivate() {
    if (localStorage.getItem('currentUser')) {
      console.log(localStorage.getItem('currentUser'));
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }
}


canActivate() {
    if (localStorage.getItem('currentUser')) {
      console.log(localStorage.getItem('currentUser'));
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }


export default class SettingMock {
	public constructor(public readonly settingName?: string,
						public readonly settingValue?: string) {
		setting.name = this.settingName;
		setting.value = this.settingValue;
		saveStub.reset();
		removeStub.reset();
	}

	public get save(): SinonStub<unknown[], Promise<boolean>> {
		return saveStub;
	}

	public get remove(): SinonStub<unknown[], Promise<void>> {
		return removeStub;
	}

	public static get setting(): Setting {
		return setting;
	}

	public static get "get"(): SinonStub<string[], SettingMock> {
		return getStub;
	}
}


interface Setting {
	name?: string;
	value?: string;
}


() => {
                            uploadFace(j, i, face);
                        }


() => {
                return textureComplete();
            }


/**
 * A minimal WebGL cubemap descriptor
 */
export class TextureCube {

    /**
     * Returns the width of a face of the texture or 0 if not available
     */
    public get Width(): number {
        return (this.source && this.source[0] && this.source[0][0]) ? this.source[0][0].width : 0;
    }

    /**
     * Returns the height of a face of the texture or 0 if not available
     */
    public get Height(): number {
        return (this.source && this.source[0] && this.source[0][0]) ? this.source[0][0].height : 0;
    }

    /**
     * constructor
     * @param internalFormat WebGL pixel format for the texture on the GPU
     * @param type WebGL pixel type of the supplied data and texture on the GPU
     * @param source An array containing mipmap levels of faces, where each mipmap level is an array of faces and each face is a TextureSource object
     */
    constructor(public internalFormat: PixelFormat, public type: PixelType, public source: MipmapsCube = []) { }
}


/**
 * Raw texture data and descriptor sufficient for WebGL texture upload
 */
export interface TextureData {
    /**
     * Width of image
     */
    width: number;
    /**
     * Height of image
     */
    height: number;
    /**
     * Format of pixels in data
     */
    format: PixelFormat;
    /**
     * Row byte alignment of pixels in data
     */
    alignment: number;
    /**
     * Pixel data
     */
    data: ArrayBufferView;
}


/**
 * Wraps sampling parameters for a WebGL texture
 */
export interface SamplingParameters {
    /**
     * Magnification mode when upsampling from a WebGL texture
     */
    magFilter?: TextureMagFilter;
    /**
     * Minification mode when upsampling from a WebGL texture
     */
    minFilter?: TextureMinFilter;
    /**
     * X axis wrapping mode when sampling out of a WebGL texture bounds
     */
    wrapS?: TextureWrapMode;
    /**
     * Y axis wrapping mode when sampling out of a WebGL texture bounds
     */
    wrapT?: TextureWrapMode;
    /**
    * Anisotropic filtering samples
    */
    maxAnisotropy?: number;
}


/**
 * WebGL Pixel Formats
 */
export const enum PixelFormat {
    DEPTH_COMPONENT = 0x1902,
    ALPHA = 0x1906,
    RGB = 0x1907,
    RGBA = 0x1908,
    LUMINANCE = 0x1909,
    LUMINANCE_ALPHA = 0x190a,
}


/**
 * WebGL Pixel Types
 */
export const enum PixelType {
    UNSIGNED_BYTE = 0x1401,
    UNSIGNED_SHORT_4_4_4_4 = 0x8033,
    UNSIGNED_SHORT_5_5_5_1 = 0x8034,
    UNSIGNED_SHORT_5_6_5 = 0x8363,
}


/**
 * WebGL Texture Magnification Filter
 */
export const enum TextureMagFilter {
    NEAREST = 0x2600,
    LINEAR = 0x2601,
}


/**
 * WebGL Texture Minification Filter
 */
export const enum TextureMinFilter {
    NEAREST = 0x2600,
    LINEAR = 0x2601,
    NEAREST_MIPMAP_NEAREST = 0x2700,
    LINEAR_MIPMAP_NEAREST = 0x2701,
    NEAREST_MIPMAP_LINEAR = 0x2702,
    LINEAR_MIPMAP_LINEAR = 0x2703,
}


/**
 * WebGL Texture Wrap Modes
 */
export const enum TextureWrapMode {
    REPEAT = 0x2901,
    CLAMP_TO_EDGE = 0x812f,
    MIRRORED_REPEAT = 0x8370,
}


/**
 * Represents a valid WebGL texture source for use in texImage2D
 */
export type TextureSource = TextureData | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement;


/**
 * A generic set of texture mipmaps (where index 0 has the largest dimension)
 */
export type Mipmaps<T> = Array<T>;


/**
 * A set of 6 cubemap arranged in the order [+x, -x, +y, -y, +z, -z]
 */
export type Faces<T> = Array<T>;


/**
 * A set of texture mipmaps specifically for 2D textures in WebGL (where index 0 has the largest dimension)
 */
export type Mipmaps2D = Mipmaps<TextureSource>;


/**
 * A set of texture mipmaps specifically for cubemap textures in WebGL (where index 0 has the largest dimension)
 */
export type MipmapsCube = Mipmaps<Faces<TextureSource>>;


/**
     * Returns a BabylonCubeTexture instance from a Spectre texture cube, subject to sampling parameters.
     * If such a texture has already been requested in the past, this texture will be returned, otherwise a new one will be created.
     * The advantage of this is to enable working with texture objects without the need to initialize on the GPU until desired.
     * @param scene A Babylon Scene instance
     * @param textureCube A Spectre TextureCube object
     * @param parameters WebGL texture sampling parameters
     * @param automaticMipmaps Pass true to enable automatic mipmap generation where possible (requires power of images)
     * @param environment Specifies that the texture will be used as an environment
     * @param singleLod Specifies that the texture will be a singleLod (for environment)
     * @return Babylon cube texture
     */
public static GetBabylonCubeTexture(scene: Scene, textureCube: TextureCube, automaticMipmaps: boolean, environment = false, singleLod = false): CubeTexture {
        if (!textureCube) { throw new Error("no texture cube provided"); }

        var parameters: SamplingParameters;
        if (environment) {
            parameters = singleLod ? TextureUtils._EnvironmentSingleMipSampling : TextureUtils._EnvironmentSampling;
        }
        else {
            parameters = {
                magFilter: TextureMagFilter.NEAREST,
                minFilter: TextureMinFilter.NEAREST,
                wrapS: TextureWrapMode.CLAMP_TO_EDGE,
                wrapT: TextureWrapMode.CLAMP_TO_EDGE
            };
        }

        let key = TextureUtils.BabylonTextureKeyPrefix + parameters.magFilter + '' + parameters.minFilter + '' + parameters.wrapS + '' + parameters.wrapT;

        let babylonTexture: CubeTexture = (<any>textureCube)[key];

        if (!babylonTexture) {

            //initialize babylon texture
            babylonTexture = new CubeTexture('', scene);
            if (environment) {
                babylonTexture.lodGenerationOffset = TextureUtils.EnvironmentLODOffset;
                babylonTexture.lodGenerationScale = TextureUtils.EnvironmentLODScale;
            }

            babylonTexture.gammaSpace = false;

            let internalTexture = new InternalTexture(scene.getEngine(), InternalTexture.DATASOURCE_CUBERAW);
            let glTexture = internalTexture._webGLTexture;
            //babylon properties
            internalTexture.isCube = true;
            internalTexture.generateMipMaps = false;

            babylonTexture._texture = internalTexture;

            TextureUtils.ApplySamplingParameters(babylonTexture, parameters);

            let maxMipLevel = automaticMipmaps ? 0 : textureCube.source.length - 1;
            let texturesUploaded = 0;

            var textureComplete = function() {
                return texturesUploaded === ((maxMipLevel + 1) * 6);
            };

            var uploadFace = function(i: number, level: number, face: TextureSource) {
                if (!glTexture) { return; }

                if (i === 0 && level === 0) {
                    internalTexture.width = face.width;
                    internalTexture.height = face.height;
                }

                let gl = (<any>(scene.getEngine()))._gl;
                gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture);
                scene.getEngine()._unpackFlipY(false);
                if (face instanceof HTMLElement || face instanceof ImageData) {
                    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, textureCube.internalFormat, textureCube.internalFormat, textureCube.type, <any>face);
                } else {
                    let textureData = <TextureData>face;
                    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, textureCube.internalFormat, textureData.width, textureData.height, 0, textureData.format, textureCube.type, textureData.data);
                }

                texturesUploaded++;

                if (textureComplete()) {
                    //generate mipmaps
                    if (automaticMipmaps) {
                        let w = face.width;
                        let h = face.height;
                        let isPot = (((w !== 0) && (w & (w - 1))) === 0) && (((h !== 0) && (h & (h - 1))) === 0);
                        if (isPot) {
                            gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
                        }
                    }

                    // Upload Separate lods in case there is no support for texture lod.
                    if (environment && !scene.getEngine().getCaps().textureLOD && !singleLod) {
                        const mipSlices = 3;
                        for (let i = 0; i < mipSlices; i++) {
                            let lodKey = TextureUtils.BabylonTextureKeyPrefix + 'lod' + i;
                            let lod: CubeTexture = (<any>textureCube)[lodKey];

                            //initialize lod texture if it doesn't already exist
                            if (lod == null && textureCube.Width) {
                                //compute LOD from even spacing in smoothness (matching shader calculation)
                                let smoothness = i / (mipSlices - 1);
                                let roughness = 1 - smoothness;
                                const kMinimumVariance = 0.0005;
                                let alphaG = roughness * roughness + kMinimumVariance;
                                let microsurfaceAverageSlopeTexels = alphaG * textureCube.Width;

                                let environmentSpecularLOD = TextureUtils.EnvironmentLODScale * (Scalar.Log2(microsurfaceAverageSlopeTexels)) + TextureUtils.EnvironmentLODOffset;

                                let maxLODIndex = textureCube.source.length - 1;
                                let mipmapIndex = Math.min(Math.max(Math.round(environmentSpecularLOD), 0), maxLODIndex);

                                lod = TextureUtils.GetBabylonCubeTexture(scene, new TextureCube(PixelFormat.RGBA, PixelType.UNSIGNED_BYTE, [textureCube.source[mipmapIndex]]), false, true, true);

                                if (i === 0) {
                                    internalTexture._lodTextureLow = lod;
                                }
                                else if (i === 1) {
                                    internalTexture._lodTextureMid = lod;
                                }
                                else {
                                    internalTexture._lodTextureHigh = lod;
                                }

                                (<any>textureCube)[lodKey] = lod;
                            }
                        }
                    }

                    internalTexture.isReady = true;
                }

                gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
                scene.getEngine().resetTextureCache();
            };

            for (let i = 0; i <= maxMipLevel; i++) {
                let faces = textureCube.source[i];
                for (let j = 0; j < faces.length; j++) {
                    let face = faces[j];
                    if (face instanceof HTMLImageElement && !face.complete) {
                        face.addEventListener('load', () => {
                            uploadFace(j, i, face);
                        }, false);
                    } else {
                        uploadFace(j, i, face);
                    }
                }
            }

            scene.getEngine().resetTextureCache();

            babylonTexture.isReady = () => {
                return textureComplete();
            };

            (<any>textureCube)[key] = babylonTexture;
        }

        return babylonTexture;
    }


/**
     * Applies Spectre SamplingParameters to a Babylon texture by directly setting texture parameters on the internal WebGLTexture as well as setting Babylon fields
     * @param babylonTexture Babylon texture to apply texture to (requires the Babylon texture has an initialize _texture field)
     * @param parameters Spectre SamplingParameters to apply
     */
public static ApplySamplingParameters(babylonTexture: BaseTexture, parameters: SamplingParameters) {
        let scene = babylonTexture.getScene();
        if (!scene) { return; }
        let gl = (<any>(scene.getEngine()))._gl;

        let target = babylonTexture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;

        let internalTexture = babylonTexture._texture;
        if (!internalTexture) { return; }
        let glTexture = internalTexture._webGLTexture;
        gl.bindTexture(target, glTexture);

        if (parameters.magFilter != null) { gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, parameters.magFilter); }
        if (parameters.minFilter != null) { gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, parameters.minFilter); }
        if (parameters.wrapS != null) { gl.texParameteri(target, gl.TEXTURE_WRAP_S, parameters.wrapS); }
        if (parameters.wrapT != null) { gl.texParameteri(target, gl.TEXTURE_WRAP_T, parameters.wrapT); }

        //set babylon wrap modes from sampling parameter
        switch (parameters.wrapS) {
            case TextureWrapMode.REPEAT: babylonTexture.wrapU = Texture.WRAP_ADDRESSMODE; break;
            case TextureWrapMode.CLAMP_TO_EDGE: babylonTexture.wrapU = Texture.CLAMP_ADDRESSMODE; break;
            case TextureWrapMode.MIRRORED_REPEAT: babylonTexture.wrapU = Texture.MIRROR_ADDRESSMODE; break;
            default: babylonTexture.wrapU = Texture.CLAMP_ADDRESSMODE;
        }

        switch (parameters.wrapT) {
            case TextureWrapMode.REPEAT: babylonTexture.wrapV = Texture.WRAP_ADDRESSMODE; break;
            case TextureWrapMode.CLAMP_TO_EDGE: babylonTexture.wrapV = Texture.CLAMP_ADDRESSMODE; break;
            case TextureWrapMode.MIRRORED_REPEAT: babylonTexture.wrapV = Texture.MIRROR_ADDRESSMODE; break;
            default: babylonTexture.wrapV = Texture.CLAMP_ADDRESSMODE;
        }

        if (parameters.maxAnisotropy != null && parameters.maxAnisotropy > 1) {
            let anisotropicExt = gl.getExtension('EXT_texture_filter_anisotropic');
            if (anisotropicExt) {
                let maxAnisotropicSamples = gl.getParameter(anisotropicExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
                let maxAnisotropy = Math.min(parameters.maxAnisotropy, maxAnisotropicSamples);
                gl.texParameterf(target, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
                babylonTexture.anisotropicFilteringLevel = maxAnisotropy;
            }
        }

        gl.bindTexture(target, null);
        scene.getEngine().resetTextureCache();
    }


@NgModule({
    imports: [CommonModule, A11yModule, McCommonModule],
    exports: [McToggleComponent],
    declarations: [McToggleComponent]
})
export class McToggleModule {
}


@Injectable()
export class CreateProfileMapper {
  public request(request: CreateProfileRequest): Partial<Profile> {
    return {
      gender: request.gender,
      emailId: request.emailId,
      city: request.city,
    };
  }
}


public request(request: CreateProfileRequest): Partial<Profile> {
    return {
      gender: request.gender,
      emailId: request.emailId,
      city: request.city,
    };
  }


() => {
  const intl = useIntl()
  const {
    register,
    formState: {
      errors: { chassisNumber: chassisNumberError },
    },
  } = useFormContext<CreateVehicleRequest>()

  return (
    <Input
      label={intl.formatMessage({
        defaultMessage: 'Chassis number',
        description: 'Chassis number field',
      })}
      helperText={chassisNumberError?.message}
      helperColor={'error'}
      status={chassisNumberError ? 'error' : 'default'}
      width="100%"
      {...register('chassisNumber', {
        required: {
          value: true,
          message: intl.formatMessage({
            defaultMessage: 'Please enter a chassis number',
            description: 'Error message for chassis number field',
          }),
        },
      })}
    />


(evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      window.scrollTo(0, 0);
    }


@Component({
  // tslint:disable-next-line
  selector: 'body',
  template: '<router-outlet></router-outlet><app-alert></app-alert>'
})
export class AppComponent implements OnInit {
  constructor(private router: Router) { }

  ngOnInit() {
    this.router.events.subscribe((evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      window.scrollTo(0, 0);
    });
  }
}


ngOnInit() {
    this.router.events.subscribe((evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      window.scrollTo(0, 0);
    });
  }


/**
 * Tap configuration in a Network Interface.
 * API Version: 2020-08-01.
 */
export function getNetworkInterfaceTapConfiguration(args: GetNetworkInterfaceTapConfigurationArgs, opts?: pulumi.InvokeOptions): Promise<GetNetworkInterfaceTapConfigurationResult> {
    if (!opts) {
        opts = {}
    }

    if (!opts.version) {
        opts.version = utilities.getVersion();
    }
    return pulumi.runtime.invoke("azure-native:network:getNetworkInterfaceTapConfiguration", {
        "networkInterfaceName": args.networkInterfaceName,
        "resourceGroupName": args.resourceGroupName,
        "tapConfigurationName": args.tapConfigurationName,
    }, opts);
}


export interface GetNetworkInterfaceTapConfigurationArgs {
    /**
     * The name of the network interface.
     */
    readonly networkInterfaceName: string;
    /**
     * The name of the resource group.
     */
    readonly resourceGroupName: string;
    /**
     * The name of the tap configuration.
     */
    readonly tapConfigurationName: string;
}


/**
 * Tap configuration in a Network Interface.
 */
export interface GetNetworkInterfaceTapConfigurationResult {
    /**
     * A unique read-only string that changes whenever the resource is updated.
     */
    readonly etag: string;
    /**
     * Resource ID.
     */
    readonly id?: string;
    /**
     * The name of the resource that is unique within a resource group. This name can be used to access the resource.
     */
    readonly name?: string;
    /**
     * The provisioning state of the network interface tap configuration resource.
     */
    readonly provisioningState: string;
    /**
     * Sub Resource type.
     */
    readonly type: string;
    /**
     * The reference to the Virtual Network Tap resource.
     */
    readonly virtualNetworkTap?: outputs.network.VirtualNetworkTapResponse;
}


async (): Promise<string[]> => {
  const disciplines = await AsyncStorage.getItem('customDisciplines')
  return disciplines ? JSON.parse(disciplines) : null
}


async (customDisciplines: string[]): Promise<void> => {
  await AsyncStorage.setItem('customDisciplines', JSON.stringify(customDisciplines))
}


async (session: sessionData): Promise<void> => {
  await AsyncStorage.setItem(SESSION_KEY, JSON.stringify(session))
}


async (): Promise<sessionData | null> => {
  const sessionJson = await AsyncStorage.getItem(SESSION_KEY)
  return sessionJson === null ? null : JSON.parse(sessionJson)
}


async (): Promise<void> => {
  await AsyncStorage.removeItem(SESSION_KEY)
}


async (exerciseKey: ExerciseKeyType, exercise: ExerciseType): Promise<void> => {
  await AsyncStorage.setItem(exerciseKey.toString(), JSON.stringify(exercise))
}


async (exerciseKey: ExerciseKeyType): Promise<ExerciseType | null> => {
  const exerciseJson = await AsyncStorage.getItem(exerciseKey.toString())
  return exerciseJson === null ? null : JSON.parse(exerciseJson)
}


async (exerciseKey: ExerciseKeyType): Promise<void> => {
  await AsyncStorage.removeItem(exerciseKey.toString())
}


export interface ExerciseType {
  [disciplineId: number]: {
    [word: string]: DocumentResultType
  }
}


interface sessionData {
  id: number
  title: string
  numberOfWords: number
  exercise: number
  retryData?: { data: DocumentsType }
  results: []
}


(value: unknown): string => {
		const coercedValue = coerceType(value);

		return coercedValue.toLowerCase();
	}


() => <hr css


export class CreateScheduleRequest {
  readonly disciplineId: number;
  readonly grade: string;
}


export class CreateScheduleResponse extends CreateScheduleRequest {
  readonly id: number;
}


export function createSnapToN(n: number): Type;


export function createSnapToZero(opt_tolerance?: number): Type;


export function disable(rotation: number, delta: number): number;


export function none(rotation: number, delta: number): number;


export type Type = ((param0: number, param1: number) => number);


webview => {
			webview.showFind();
			this._findWidgetVisible.set(true);
		}


webview => webview.hideFind()


webview => {
			webview.runFindAction(previous);
		}


webview => webview.reload()


focused => {
				if (focused && this._editorService.activeControl === this) {
					this.focus();
				}
			}


webview => webview.focus()


() => this._onDidFocusWebview.fire()


export class WebviewEditor extends BaseEditor {

	public static readonly ID = 'WebviewEditor';

	private readonly _scopedContextKeyService = this._register(new MutableDisposable<IContextKeyService>());
	private _findWidgetVisible: IContextKey<boolean>;
	private _editorFrame?: HTMLElement;
	private _content?: HTMLElement;

	private readonly _webviewFocusTrackerDisposables = this._register(new DisposableStore());
	private readonly _onFocusWindowHandler = this._register(new MutableDisposable());

	private readonly _onDidFocusWebview = this._register(new Emitter<void>());
	public get onDidFocus(): Event<any> { return this._onDidFocusWebview.event; }

	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
		@IThemeService themeService: IThemeService,
		@IContextKeyService private readonly _contextKeyService: IContextKeyService,
		@IEditorService private readonly _editorService: IEditorService,
		@IWindowService private readonly _windowService: IWindowService,
		@IStorageService storageService: IStorageService
	) {
		super(WebviewEditor.ID, telemetryService, themeService, storageService);

		this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(_contextKeyService);
	}

	public get isWebviewEditor() {
		return true;
	}

	protected createEditor(parent: HTMLElement): void {
		this._editorFrame = parent;
		this._content = document.createElement('div');
		parent.appendChild(this._content);
	}

	public dispose(): void {
		if (this._content) {
			this._content.remove();
			this._content = undefined;
		}

		super.dispose();
	}

	public showFind() {
		this.withWebview(webview => {
			webview.showFind();
			this._findWidgetVisible.set(true);
		});
	}

	public hideFind() {
		this._findWidgetVisible.reset();
		this.withWebview(webview => webview.hideFind());
	}

	public find(previous: boolean) {
		this.withWebview(webview => {
			webview.runFindAction(previous);
		});
	}

	public reload() {
		this.withWebview(webview => webview.reload());
	}

	public layout(dimension: DOM.Dimension): void {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.synchronizeWebviewContainerDimensions(this.input.webview, dimension);
			this.input.webview.layout();
		}
	}

	public focus(): void {
		super.focus();
		if (!this._onFocusWindowHandler.value) {
			// Make sure we restore focus when switching back to a VS Code window
			this._onFocusWindowHandler.value = this._windowService.onDidChangeFocus(focused => {
				if (focused && this._editorService.activeControl === this) {
					this.focus();
				}
			});
		}
		this.withWebview(webview => webview.focus());
	}

	public withWebview(f: (element: Webview) => void): void {
		if (this.input && this.input instanceof WebviewEditorInput) {
			f(this.input.webview);
		}
	}

	protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
		const webview = this.input && (this.input as WebviewEditorInput).webview;
		if (webview) {
			if (visible) {
				webview.claim(this);
			} else {
				webview.release(this);
			}
			this.claimWebview(this.input as WebviewEditorInput);
		}

		super.setEditorVisible(visible, group);
	}

	public clearInput() {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.input.webview.release(this);
		}

		super.clearInput();
	}

	public async setInput(input: WebviewEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.input.webview.release(this);
		}

		await super.setInput(input, options, token);
		await input.resolve();
		if (token.isCancellationRequested) {
			return;
		}

		if (this.group) {
			input.updateGroup(this.group.id);
		}

		this.claimWebview(input);
	}

	private claimWebview(input: WebviewEditorInput): void {
		input.webview.claim(this);

		if (input.webview.options.enableFindWidget) {
			this._scopedContextKeyService.value = this._contextKeyService.createScoped(input.webview.container);
			this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._scopedContextKeyService.value);
		}

		if (this._content) {
			this._content.setAttribute('aria-flowto', input.webview.container.id);
		}

		this.synchronizeWebviewContainerDimensions(input.webview);
		this.trackFocus(input.webview);
	}

	private synchronizeWebviewContainerDimensions(webview: WebviewEditorOverlay, dimension?: DOM.Dimension) {
		const webviewContainer = webview.container;
		if (webviewContainer && webviewContainer.parentElement && this._editorFrame) {
			const frameRect = this._editorFrame.getBoundingClientRect();
			const containerRect = webviewContainer.parentElement.getBoundingClientRect();
			webviewContainer.style.position = 'absolute';
			webviewContainer.style.top = `${frameRect.top - containerRect.top}px`;
			webviewContainer.style.left = `${frameRect.left - containerRect.left}px`;
			webviewContainer.style.width = `${dimension ? dimension.width : frameRect.width}px`;
			webviewContainer.style.height = `${dimension ? dimension.height : frameRect.height}px`;
		}
	}

	private trackFocus(webview: WebviewEditorOverlay): void {
		this._webviewFocusTrackerDisposables.clear();

		// Track focus in webview content
		const webviewContentFocusTracker = DOM.trackFocus(webview.container);
		this._webviewFocusTrackerDisposables.add(webviewContentFocusTracker);
		this._webviewFocusTrackerDisposables.add(webviewContentFocusTracker.onDidFocus(() => this._onDidFocusWebview.fire()));

		// Track focus in webview element
		this._webviewFocusTrackerDisposables.add(webview.onDidFocus(() => this._onDidFocusWebview.fire()));
	}
}


protected createEditor(parent: HTMLElement): void {
		this._editorFrame = parent;
		this._content = document.createElement('div');
		parent.appendChild(this._content);
	}


public dispose(): void {
		if (this._content) {
			this._content.remove();
			this._content = undefined;
		}

		super.dispose();
	}


public showFind() {
		this.withWebview(webview => {
			webview.showFind();
			this._findWidgetVisible.set(true);
		});
	}


public hideFind() {
		this._findWidgetVisible.reset();
		this.withWebview(webview => webview.hideFind());
	}


public find(previous: boolean) {
		this.withWebview(webview => {
			webview.runFindAction(previous);
		});
	}


public reload() {
		this.withWebview(webview => webview.reload());
	}


public layout(dimension: DOM.Dimension): void {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.synchronizeWebviewContainerDimensions(this.input.webview, dimension);
			this.input.webview.layout();
		}
	}


public focus(): void {
		super.focus();
		if (!this._onFocusWindowHandler.value) {
			// Make sure we restore focus when switching back to a VS Code window
			this._onFocusWindowHandler.value = this._windowService.onDidChangeFocus(focused => {
				if (focused && this._editorService.activeControl === this) {
					this.focus();
				}
			});
		}
		this.withWebview(webview => webview.focus());
	}


public withWebview(f: (element: Webview) => void): void {
		if (this.input && this.input instanceof WebviewEditorInput) {
			f(this.input.webview);
		}
	}


protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
		const webview = this.input && (this.input as WebviewEditorInput).webview;
		if (webview) {
			if (visible) {
				webview.claim(this);
			} else {
				webview.release(this);
			}
			this.claimWebview(this.input as WebviewEditorInput);
		}

		super.setEditorVisible(visible, group);
	}


public clearInput() {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.input.webview.release(this);
		}

		super.clearInput();
	}


public async setInput(input: WebviewEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
		if (this.input && this.input instanceof WebviewEditorInput) {
			this.input.webview.release(this);
		}

		await super.setInput(input, options, token);
		await input.resolve();
		if (token.isCancellationRequested) {
			return;
		}

		if (this.group) {
			input.updateGroup(this.group.id);
		}

		this.claimWebview(input);
	}


private claimWebview(input: WebviewEditorInput): void {
		input.webview.claim(this);

		if (input.webview.options.enableFindWidget) {
			this._scopedContextKeyService.value = this._contextKeyService.createScoped(input.webview.container);
			this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._scopedContextKeyService.value);
		}

		if (this._content) {
			this._content.setAttribute('aria-flowto', input.webview.container.id);
		}

		this.synchronizeWebviewContainerDimensions(input.webview);
		this.trackFocus(input.webview);
	}


private synchronizeWebviewContainerDimensions(webview: WebviewEditorOverlay, dimension?: DOM.Dimension) {
		const webviewContainer = webview.container;
		if (webviewContainer && webviewContainer.parentElement && this._editorFrame) {
			const frameRect = this._editorFrame.getBoundingClientRect();
			const containerRect = webviewContainer.parentElement.getBoundingClientRect();
			webviewContainer.style.position = 'absolute';
			webviewContainer.style.top = `${frameRect.top - containerRect.top}px`;
			webviewContainer.style.left = `${frameRect.left - containerRect.left}px`;
			webviewContainer.style.width = `${dimension ? dimension.width : frameRect.width}px`;
			webviewContainer.style.height = `${dimension ? dimension.height : frameRect.height}px`;
		}
	}


private trackFocus(webview: WebviewEditorOverlay): void {
		this._webviewFocusTrackerDisposables.clear();

		// Track focus in webview content
		const webviewContentFocusTracker = DOM.trackFocus(webview.container);
		this._webviewFocusTrackerDisposables.add(webviewContentFocusTracker);
		this._webviewFocusTrackerDisposables.add(webviewContentFocusTracker.onDidFocus(() => this._onDidFocusWebview.fire()));

		// Track focus in webview element
		this._webviewFocusTrackerDisposables.add(webview.onDidFocus(() => this._onDidFocusWebview.fire()));
	}


() => {
  it('with missing remediation is not supported', async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      JSON.stringify({}),
    );
    // @ts-ignore: for test purpose only
    delete entity.testResult.remediation;
    const res = await isSupported(entity);
    expect(res.supported).toBeFalsy();
  });

  it('with empty Pins is not supported', async () => {
    const entity = generateEntityToFix(
      'poetry',
      'pyproject.toml',
      JSON.stringify({}),
    );
    // @ts-ignore: for test purpose only
    delete entity.testResult.remediation;
    // @ts-ignore: for test purpose only
    entity.testResult.remediation = {
      unresolved: [],
      upgrade: {
        'django@1.6.1': {
          upgradeTo: 'django@2.0.1',
          vulns: ['vuln-id'],
          isTransitive: false,
        },
      },
      patch: {},
      ignore: {},
      pin: {},
    };
    const res = await isSupported(entity);
    expect(res.supported).toBeFalsy();
  });
  it('with -r directive in the manifest is supported', async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      '-r prod.txt\nDjango==1.6.1',
    );
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  });
  it('with -c directive in the manifest is supported', async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      '-c constraints.txt',
    );
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  });
  it('with -e directive in the manifest is supported', async () => {
    const entity = generateEntityToFix('pip', 'requirements.txt', '-e .');
    entity.testResult.remediation!.pin = {
      'django@1.6.1': {
        upgradeTo: 'django@2.0.1',
        vulns: [],
        isTransitive: false,
      },
    };
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  });
}


async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      JSON.stringify({}),
    );
    // @ts-ignore: for test purpose only
    delete entity.testResult.remediation;
    const res = await isSupported(entity);
    expect(res.supported).toBeFalsy();
  }


async () => {
    const entity = generateEntityToFix(
      'poetry',
      'pyproject.toml',
      JSON.stringify({}),
    );
    // @ts-ignore: for test purpose only
    delete entity.testResult.remediation;
    // @ts-ignore: for test purpose only
    entity.testResult.remediation = {
      unresolved: [],
      upgrade: {
        'django@1.6.1': {
          upgradeTo: 'django@2.0.1',
          vulns: ['vuln-id'],
          isTransitive: false,
        },
      },
      patch: {},
      ignore: {},
      pin: {},
    };
    const res = await isSupported(entity);
    expect(res.supported).toBeFalsy();
  }


async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      '-r prod.txt\nDjango==1.6.1',
    );
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  }


async () => {
    const entity = generateEntityToFix(
      'pip',
      'requirements.txt',
      '-c constraints.txt',
    );
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  }


async () => {
    const entity = generateEntityToFix('pip', 'requirements.txt', '-e .');
    entity.testResult.remediation!.pin = {
      'django@1.6.1': {
        upgradeTo: 'django@2.0.1',
        vulns: [],
        isTransitive: false,
      },
    };
    const res = await isSupported(entity);
    expect(res.supported).toBeTruthy();
  }


({ onDismiss }: Props) => (
  <Modal onDismiss={onDismiss}>
    <div className


interface Props {
  onDismiss()
}


// -----------------------------------------------------------------------------
export async function getProfile(identityId: string, profileId: string) {
  const sql = {
    text: `
      SELECT id, name, email, is_default, created_at, updated_at
      FROM profile
      WHERE id = $2
        AND identity_id = $1`,
    args: [
      identityId,
      profileId,
    ],
  };

  return await fetch(sql) as profileRows;
}


// -----------------------------------------------------------------------------
export async function getDefaultProfile(identityId: string) {
  const sql = {
    text: `
      SELECT id, name, email, is_default, created_at, updated_at
      FROM profile
      WHERE identity_id = $1
        AND is_default = true
      LIMIT 1`,
    args: [
      identityId,
    ],
  };

  return await fetch(sql) as profileRows;
}


// -----------------------------------------------------------------------------
export async function listProfile(
  identityId: string,
  limit: number,
  offset: number,
) {
  const sql = {
    text: `
      SELECT id, name, email, is_default, created_at, updated_at
      FROM profile
      WHERE identity_id = $1
      ORDER BY name
      LIMIT $2 OFFSET $3`,
    args: [
      identityId,
      limit,
      offset,
    ],
  };

  return await fetch(sql) as profileRows;
}


// -----------------------------------------------------------------------------
export async function addProfile(
  identityId: string,
  name: string,
  email: string,
  isDefault = false,
) {
  const sql = {
    text: `
      INSERT INTO profile (identity_id, name, email, is_default)
      VALUES ($1, $2, $3, $4)
      RETURNING id, created_at as at`,
    args: [
      identityId,
      name,
      email,
      isDefault,
    ],
  };

  return await fetch(sql) as idRows;
}


// -----------------------------------------------------------------------------
export async function delProfile(identityId: string, profileId: string) {
  const sql = {
    text: `
      DELETE FROM profile
      WHERE id = $2
        AND identity_id = $1
        AND is_default = false
      RETURNING id, now() as at`,
    args: [
      identityId,
      profileId,
    ],
  };

  return await fetch(sql) as idRows;
}


// -----------------------------------------------------------------------------
export async function updateProfile(
  identityId: string,
  profileId: string,
  name: string,
  email: string,
) {
  const sql = {
    text: `
      UPDATE profile
      SET
        name = $3,
        email = $4,
        updated_at = now()
      WHERE id = $2
        AND identity_id = $1
      RETURNING id, updated_at as at`,
    args: [
      identityId,
      profileId,
      name,
      email,
    ],
  };

  return await fetch(sql) as idRows;
}


// -----------------------------------------------------------------------------
export async function setDefaultProfile(identityId: string, profileId: string) {
  // note: don't add an is_default checking into WHERE. user should set a
  // profile as default although it's already default to solve the duplicated
  // defaults issue. Also UI should support this.
  const sql = {
    text: `
      UPDATE profile
      SET
        is_default = true,
        updated_at = now()
      WHERE id = $2
        AND identity_id = $1
      RETURNING id, updated_at as at`,
    args: [
      identityId,
      profileId,
    ],
  };
  const rows = await fetch(sql) as idRows;

  // reset the old default if the set action is successful
  const sql1 = {
    text: `
      UPDATE profile
      SET
        is_default = false,
        updated_at = now()
      WHERE identity_id = $1
        AND id != $2
        AND is_default = true`,
    args: [
      identityId,
      profileId,
    ],
  };
  if (rows[0] !== undefined) await query(sql1);

  return rows;
}


// -----------------------------------------------------------------------------
interface profileRows {
  [index: number]: {
    id: string;
    name: string;
    email: string;
    is_default: boolean;
    created_at: string;
    updated_at: string;
  };
}


@Pipe({
  name: 'duration',
})
export class DurationPipe implements PipeTransform {
  transform(value: any): string {
    if (value) {
      return dayjs.duration(value).humanize();
    }
    return '';
  }
}


transform(value: any): string {
    if (value) {
      return dayjs.duration(value).humanize();
    }
    return '';
  }


export function WaitTracker(): WaitTrackerClass {
	if (waitTrackerInstance === undefined) {
		waitTrackerInstance = new WaitTrackerClass();
	}

	return waitTrackerInstance;
}


() => {
			this.getwaitingExecutions();
		}


(execution) => execution.id.toString()


() => {
						this.startExecution(executionId);
					}


async () => {
			// Get the data to execute
			const fullExecutionDataFlatted = await Db.collections.Execution!.findOne(executionId);

			if (fullExecutionDataFlatted === undefined) {
				throw new Error(`The execution with the id "${executionId}" does not exist.`);
			}

			const fullExecutionData = ResponseHelper.unflattenExecutionData(fullExecutionDataFlatted);

			if (fullExecutionData.finished) {
				throw new Error('The execution did succeed and can so not be started again.');
			}

			const data: IWorkflowExecutionDataProcess = {
				executionMode: fullExecutionData.mode,
				executionData: fullExecutionData.data,
				workflowData: fullExecutionData.workflowData,
			};

			// Start the execution again
			const workflowRunner = new WorkflowRunner();
			await workflowRunner.run(data, false, false, executionId);
		}


(error) => {
			Logger.error(
				`There was a problem starting the waiting execution with id "${executionId}": "${error.message}"`,
				{ executionId },
			);
		}


export class WaitTrackerClass {
	activeExecutionsInstance: ActiveExecutions.ActiveExecutions;

	private waitingExecutions: {
		[key: string]: {
			executionId: string;
			timer: NodeJS.Timeout;
		};
	} = {};

	mainTimer: NodeJS.Timeout;

	constructor() {
		this.activeExecutionsInstance = ActiveExecutions.getInstance();

		// Poll every 60 seconds a list of upcoming executions
		this.mainTimer = setInterval(() => {
			this.getwaitingExecutions();
		}, 60000);

		this.getwaitingExecutions();
	}

	// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
	async getwaitingExecutions() {
		Logger.debug('Wait tracker querying database for waiting executions');
		// Find all the executions which should be triggered in the next 70 seconds
		const findQuery: FindManyOptions<IExecutionFlattedDb> = {
			select: ['id', 'waitTill'],
			where: {
				waitTill: LessThanOrEqual(new Date(Date.now() + 70000)),
			},
			order: {
				waitTill: 'ASC',
			},
		};
		const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType;
		if (dbType === 'sqlite') {
			// This is needed because of issue in TypeORM <> SQLite:
			// https://github.com/typeorm/typeorm/issues/2286
			(findQuery.where! as ObjectLiteral).waitTill = LessThanOrEqual(
				DateUtils.mixedDateToUtcDatetimeString(new Date(Date.now() + 70000)),
			);
		}

		const executions = await Db.collections.Execution!.find(findQuery);

		if (executions.length === 0) {
			return;
		}

		const executionIds = executions.map((execution) => execution.id.toString()).join(', ');
		Logger.debug(
			`Wait tracker found ${executions.length} executions. Setting timer for IDs: ${executionIds}`,
		);

		// Add timers for each waiting execution that they get started at the correct time
		// eslint-disable-next-line no-restricted-syntax
		for (const execution of executions) {
			const executionId = execution.id.toString();
			if (this.waitingExecutions[executionId] === undefined) {
				const triggerTime = execution.waitTill!.getTime() - new Date().getTime();
				this.waitingExecutions[executionId] = {
					executionId,
					timer: setTimeout(() => {
						this.startExecution(executionId);
					}, triggerTime),
				};
			}
		}
	}

	async stopExecution(executionId: string): Promise<IExecutionsStopData> {
		if (this.waitingExecutions[executionId] !== undefined) {
			// The waiting execution was already sheduled to execute.
			// So stop timer and remove.
			clearTimeout(this.waitingExecutions[executionId].timer);
			delete this.waitingExecutions[executionId];
		}

		// Also check in database
		const execution = await Db.collections.Execution!.findOne(executionId);

		if (execution === undefined || !execution.waitTill) {
			throw new Error(`The execution ID "${executionId}" could not be found.`);
		}

		const fullExecutionData = ResponseHelper.unflattenExecutionData(execution);

		// Set in execution in DB as failed and remove waitTill time
		const error = new WorkflowOperationError('Workflow-Execution has been canceled!');

		fullExecutionData.data.resultData.error = {
			...error,
			message: error.message,
			stack: error.stack,
		};

		fullExecutionData.stoppedAt = new Date();
		fullExecutionData.waitTill = undefined;

		await Db.collections.Execution!.update(
			executionId,
			ResponseHelper.flattenExecutionData(fullExecutionData),
		);

		return {
			mode: fullExecutionData.mode,
			startedAt: new Date(fullExecutionData.startedAt),
			stoppedAt: fullExecutionData.stoppedAt ? new Date(fullExecutionData.stoppedAt) : undefined,
			finished: fullExecutionData.finished,
		};
	}

	startExecution(executionId: string) {
		Logger.debug(`Wait tracker resuming execution ${executionId}`, { executionId });
		delete this.waitingExecutions[executionId];

		(async () => {
			// Get the data to execute
			const fullExecutionDataFlatted = await Db.collections.Execution!.findOne(executionId);

			if (fullExecutionDataFlatted === undefined) {
				throw new Error(`The execution with the id "${executionId}" does not exist.`);
			}

			const fullExecutionData = ResponseHelper.unflattenExecutionData(fullExecutionDataFlatted);

			if (fullExecutionData.finished) {
				throw new Error('The execution did succeed and can so not be started again.');
			}

			const data: IWorkflowExecutionDataProcess = {
				executionMode: fullExecutionData.mode,
				executionData: fullExecutionData.data,
				workflowData: fullExecutionData.workflowData,
			};

			// Start the execution again
			const workflowRunner = new WorkflowRunner();
			await workflowRunner.run(data, false, false, executionId);
		})().catch((error) => {
			Logger.error(
				`There was a problem starting the waiting execution with id "${executionId}": "${error.message}"`,
				{ executionId },
			);
		});
	}
}


// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
async getwaitingExecutions() {
		Logger.debug('Wait tracker querying database for waiting executions');
		// Find all the executions which should be triggered in the next 70 seconds
		const findQuery: FindManyOptions<IExecutionFlattedDb> = {
			select: ['id', 'waitTill'],
			where: {
				waitTill: LessThanOrEqual(new Date(Date.now() + 70000)),
			},
			order: {
				waitTill: 'ASC',
			},
		};
		const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType;
		if (dbType === 'sqlite') {
			// This is needed because of issue in TypeORM <> SQLite:
			// https://github.com/typeorm/typeorm/issues/2286
			(findQuery.where! as ObjectLiteral).waitTill = LessThanOrEqual(
				DateUtils.mixedDateToUtcDatetimeString(new Date(Date.now() + 70000)),
			);
		}

		const executions = await Db.collections.Execution!.find(findQuery);

		if (executions.length === 0) {
			return;
		}

		const executionIds = executions.map((execution) => execution.id.toString()).join(', ');
		Logger.debug(
			`Wait tracker found ${executions.length} executions. Setting timer for IDs: ${executionIds}`,
		);

		// Add timers for each waiting execution that they get started at the correct time
		// eslint-disable-next-line no-restricted-syntax
		for (const execution of executions) {
			const executionId = execution.id.toString();
			if (this.waitingExecutions[executionId] === undefined) {
				const triggerTime = execution.waitTill!.getTime() - new Date().getTime();
				this.waitingExecutions[executionId] = {
					executionId,
					timer: setTimeout(() => {
						this.startExecution(executionId);
					}, triggerTime),
				};
			}
		}
	}


async stopExecution(executionId: string): Promise<IExecutionsStopData> {
		if (this.waitingExecutions[executionId] !== undefined) {
			// The waiting execution was already sheduled to execute.
			// So stop timer and remove.
			clearTimeout(this.waitingExecutions[executionId].timer);
			delete this.waitingExecutions[executionId];
		}

		// Also check in database
		const execution = await Db.collections.Execution!.findOne(executionId);

		if (execution === undefined || !execution.waitTill) {
			throw new Error(`The execution ID "${executionId}" could not be found.`);
		}

		const fullExecutionData = ResponseHelper.unflattenExecutionData(execution);

		// Set in execution in DB as failed and remove waitTill time
		const error = new WorkflowOperationError('Workflow-Execution has been canceled!');

		fullExecutionData.data.resultData.error = {
			...error,
			message: error.message,
			stack: error.stack,
		};

		fullExecutionData.stoppedAt = new Date();
		fullExecutionData.waitTill = undefined;

		await Db.collections.Execution!.update(
			executionId,
			ResponseHelper.flattenExecutionData(fullExecutionData),
		);

		return {
			mode: fullExecutionData.mode,
			startedAt: new Date(fullExecutionData.startedAt),
			stoppedAt: fullExecutionData.stoppedAt ? new Date(fullExecutionData.stoppedAt) : undefined,
			finished: fullExecutionData.finished,
		};
	}


startExecution(executionId: string) {
		Logger.debug(`Wait tracker resuming execution ${executionId}`, { executionId });
		delete this.waitingExecutions[executionId];

		(async () => {
			// Get the data to execute
			const fullExecutionDataFlatted = await Db.collections.Execution!.findOne(executionId);

			if (fullExecutionDataFlatted === undefined) {
				throw new Error(`The execution with the id "${executionId}" does not exist.`);
			}

			const fullExecutionData = ResponseHelper.unflattenExecutionData(fullExecutionDataFlatted);

			if (fullExecutionData.finished) {
				throw new Error('The execution did succeed and can so not be started again.');
			}

			const data: IWorkflowExecutionDataProcess = {
				executionMode: fullExecutionData.mode,
				executionData: fullExecutionData.data,
				workflowData: fullExecutionData.workflowData,
			};

			// Start the execution again
			const workflowRunner = new WorkflowRunner();
			await workflowRunner.run(data, false, false, executionId);
		})().catch((error) => {
			Logger.error(
				`There was a problem starting the waiting execution with id "${executionId}": "${error.message}"`,
				{ executionId },
			);
		});
	}


export default function UseBoolean(initial = false) {
	const [isOn, setIsOn] = useState(initial)
	const turnOn = () => setIsOn(true)
	const turnOff = () => setIsOn(false)
	return [isOn, turnOn, turnOff] as const
}


() => setIsOn(true)


() => setIsOn(false)


export default function MyProductVideo() {
  const {data} = useShopQuery({query: QUERY});

  const firstMediaElement = data.products.edges[0].node.media.edges[0].node;
  if (firstMediaElement.mediaContentType === 'EXTERNAL_VIDEO') {
    return <ExternalVideo data={firstMediaElement} />;
  }
}


props =>  {

  const tablehead = props.columns.map(c => {
    return th(c, `${props.modelName}.${c}`);
  });

  return (

        <Card>

            <DynamicGuiComponent authorized={ props.authorizeAdd }>
              <Link to={ props.addNewRoute } className='btn btn-default pull-right'>

                { T.translate(props.modelName + '.addNew') }
              </Link>
            </DynamicGuiComponent>
            <InfoTable head={ tablehead } data={ props.response.data } onClick={ props.onSelect } />
            <Pagination onClick={ props.fetchModels } response={ props.response }/>

        </Card>


c => {
    return th(c, `${props.modelName}.${c}`);
  }


interface Props {
  onSelect: any;
  addNewRoute: string;
  fetchModels: any;
  modelName: string;
  columns: string[];
  response: ListResponse;
  authorizeAdd: boolean;
}


export function StartupServiceFactory(startupService: StartupService): Function {
  return () => startupService.load();
}


() => startupService.load()


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    DelonModule.forRoot(),
    CoreModule,
    SharedModule,
    LayoutModule,
    RoutesModule,
    ...FORM_MODULES,
    ...GLOBAL_THIRD_MDOULES
  ],
  providers: [
    ...LANG_PROVIDES,
    ...INTERCEPTOR_PROVIDES,
    ...APPINIT_PROVIDES,
    // ...MY_PROVIDES
    {
      provide: RouteReuseStrategy,
      useClass: ReuseTabStrategy,
      deps: [ReuseTabService],
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }


/**
 * Create a reader that can return blocks in base64url format.
 * @param stream {Readable} a stream to read blocks
 * @param blockSize {number} the aproximate size of the block (will be converted for the closest multiple of 3).
 */
export async function createBase64BlockReader(stream: Readable, blockSize: number): Promise<Base64BlockReader> {
  return new Promise((resolve, reject) => {
    stream.on('readable', () => {
      resolve(new Base64BlockReader(stream, Math.round(blockSize / 3) * 3));
    });

    stream.on('error', err => {
      reject(err);
    });
  });
}


(resolve, reject) => {
    stream.on('readable', () => {
      resolve(new Base64BlockReader(stream, Math.round(blockSize / 3) * 3));
    });

    stream.on('error', err => {
      reject(err);
    });
  }


() => {
      resolve(new Base64BlockReader(stream, Math.round(blockSize / 3) * 3));
    }


err => {
      reject(err);
    }


class Base64BlockReader {
  constructor(
    private stream: Readable,
    private blockSize: number) {

    if (!stream.readable) throw new Error('stream need to be readable.');
    if (blockSize % 3 !== 0) throw new Error('blockSize need to be multiple of 3.');
  }

  private _formatBase64Url(block: Buffer) {
    return block.toString('base64')
      .replace(/=/g, "")
      .replace(/\+/g, "-")
      .replace(/\//g, "_");
  }

  read() {
    let block = this.stream.read(this.blockSize);

    if (!block) {
      block = this.stream.read();

      if (!block) return null;
    }

    if (Buffer.isBuffer(block)) {
      return this._formatBase64Url(block);
    }

    return this._formatBase64Url(Buffer.from(block, 'utf-8'));
  }

  readAll() {
    const blocks = <Blocks>[];
    blocks.totalLength = 0;

    let block;
    while (block = this.read()) {
      blocks.push(block);
      blocks.totalLength += block.length;
    }

    return blocks;
  }

  get readableLength() {
    return this.stream.readableLength;
  }
}


export interface Blocks extends Array<string> {
  totalLength: number;
}


private _formatBase64Url(block: Buffer) {
    return block.toString('base64')
      .replace(/=/g, "")
      .replace(/\+/g, "-")
      .replace(/\//g, "_");
  }


read() {
    let block = this.stream.read(this.blockSize);

    if (!block) {
      block = this.stream.read();

      if (!block) return null;
    }

    if (Buffer.isBuffer(block)) {
      return this._formatBase64Url(block);
    }

    return this._formatBase64Url(Buffer.from(block, 'utf-8'));
  }


readAll() {
    const blocks = <Blocks>[];
    blocks.totalLength = 0;

    let block;
    while (block = this.read()) {
      blocks.push(block);
      blocks.totalLength += block.length;
    }

    return blocks;
  }


export interface EbbinghausItem {
    id?: number;
    name: string;
    link?: string;
    desc?: string;
    createTime: number | Date;
    updateTime: number | Date;
    stage: Stage;
}


export type Stage = 1 | 2 | 4 | 7 | 15 | 1_000_000_000;


apiResponse => {
          // Save user data
          this.ObservablesService.setObservableData('users', apiResponse.data);

          // Navigation to protected route
          this.Router.navigateByUrl('/');
        }


error => {
          console.log("Auto connection fail", error);
          // Navigation to protected route
          this.Router.navigateByUrl('/connexion');
        }


//
/*
Componant configuration
*/
@Component({
    selector: 'app-root',
    template: `
      <app-sidebar></app-sidebar>
      <app-header></app-header>
      <router-outlet></router-outlet>
    `
  })
//

/*
Componant class definition
*/
  export class AppComponent {
    title = 'MySponsport';

    constructor( private ObservablesService: ObservablesService, private AuthService: AuthService, private Router: Router ) {}

    async ngOnInit() {
      console.log(localStorage.getItem('userId'));

      if(localStorage.getItem('userId') != null) {
        this.AuthService.identity(localStorage.getItem('userId'))
        .then( apiResponse => {
          // Save user data
          this.ObservablesService.setObservableData('users', apiResponse.data);

          // Navigation to protected route
          this.Router.navigateByUrl('/');
        })
        .catch( error => {
          console.log("Auto connection fail", error);
          // Navigation to protected route
          this.Router.navigateByUrl('/connexion');
        });
      }
    }
  }


async ngOnInit() {
      console.log(localStorage.getItem('userId'));

      if(localStorage.getItem('userId') != null) {
        this.AuthService.identity(localStorage.getItem('userId'))
        .then( apiResponse => {
          // Save user data
          this.ObservablesService.setObservableData('users', apiResponse.data);

          // Navigation to protected route
          this.Router.navigateByUrl('/');
        })
        .catch( error => {
          console.log("Auto connection fail", error);
          // Navigation to protected route
          this.Router.navigateByUrl('/connexion');
        });
      }
    }


(name: string): pino.Logger => {
  return pino({
    name: name,
    level: process.env.LOG_LEVEL || "info",
    mixin() {
      return {
        version: pjson.version,
        node_env: process.env.NODE_ENV,
      };
    },
  });
}


mixin() {
      return {
        version: pjson.version,
        node_env: process.env.NODE_ENV,
      };
    }


() => {

    let connections: Connection[];
    before(async () => connections = await createTestingConnections({
        enabledDrivers: ["postgres", "mariadb", "mysql"],
        entities: [Men, Person, Women],
        schema: "custom",
        schemaCreate: true
    }));
    beforeEach(() => reloadTestingDatabases(connections));
    after(() => closeTestingConnections(connections));

    it("Child classes should have same schema as parent", () => Promise.all(connections.map(async connection => {
        const personMetadata = connection.getMetadata(Person);
        const menMetadata = connection.getMetadata(Men);
        const womenMetadata = connection.getMetadata(Women);
        // @ts-ignore
        personMetadata.schema.should.be.eq("custom");
        // @ts-ignore
        menMetadata.schema.should.be.eq(personMetadata.schema);
        // @ts-ignore
        womenMetadata.schema.should.be.eq(personMetadata.schema);
    })));

}


async () => connections = await createTestingConnections({
        enabledDrivers: ["postgres", "mariadb", "mysql"],
        entities: [Men, Person, Women],
        schema: "custom",
        schemaCreate: true
    })


() => Promise.all(connections.map(async connection => {
        const personMetadata = connection.getMetadata(Person);
        const menMetadata = connection.getMetadata(Men);
        const womenMetadata = connection.getMetadata(Women);
        // @ts-ignore
        personMetadata.schema.should.be.eq("custom");
        // @ts-ignore
        menMetadata.schema.should.be.eq(personMetadata.schema);
        // @ts-ignore
        womenMetadata.schema.should.be.eq(personMetadata.schema);
    }))


async connection => {
        const personMetadata = connection.getMetadata(Person);
        const menMetadata = connection.getMetadata(Men);
        const womenMetadata = connection.getMetadata(Women);
        // @ts-ignore
        personMetadata.schema.should.be.eq("custom");
        // @ts-ignore
        menMetadata.schema.should.be.eq(personMetadata.schema);
        // @ts-ignore
        womenMetadata.schema.should.be.eq(personMetadata.schema);
    }


(mardown: MarkdownIt) => {
		if (this.options.markdown !== false) mardown.enable('emphasis');
	}


export default class<
	T extends BoldOptions = BoldOptions,
> extends MarkPlugin<T> {
	static get pluginName() {
		return 'bold';
	}

	tagName = 'strong';

	init(): void {
		super.init();
		const editor = this.editor;
		if (isEngine(editor)) {
			editor.on(MARKDOWN_IT, this.markdownIt);
		}
	}

	markdownIt = (mardown: MarkdownIt) => {
		if (this.options.markdown !== false) mardown.enable('emphasis');
	};

	hotkey() {
		return this.options.hotkey || 'mod+b';
	}

	conversion() {
		return [
			{
				from: {
					span: {
						style: {
							'font-weight': ['bold', '700'],
						},
					},
				},
				to: this.tagName,
			},
			{
				from: 'b',
				to: this.tagName,
			},
		];
	}

	destroy(): void {
		this.editor.off(MARKDOWN_IT, this.markdownIt);
	}
}


export interface BoldOptions extends PluginOptions {
	hotkey?: string | Array<string>;
	markdown?: boolean;
}


init(): void {
		super.init();
		const editor = this.editor;
		if (isEngine(editor)) {
			editor.on(MARKDOWN_IT, this.markdownIt);
		}
	}


hotkey() {
		return this.options.hotkey || 'mod+b';
	}


conversion() {
		return [
			{
				from: {
					span: {
						style: {
							'font-weight': ['bold', '700'],
						},
					},
				},
				to: this.tagName,
			},
			{
				from: 'b',
				to: this.tagName,
			},
		];
	}


destroy(): void {
		this.editor.off(MARKDOWN_IT, this.markdownIt);
	}


(basePath, cb) => {
      fs.readdir(basePath, (err, files) => {
        if (err) return cb(err);
        async.filter(
          files,
          (file, next: (err: boolean) => void) => {
            fs.stat(path.join(basePath, file), (err, stats) => {
              return next(!err && stats.isDirectory());
            });
          },
          (dirs) => {
            return cb(null, dirs);
          }
        );
      });
    }


(err, files) => {
        if (err) return cb(err);
        async.filter(
          files,
          (file, next: (err: boolean) => void) => {
            fs.stat(path.join(basePath, file), (err, stats) => {
              return next(!err && stats.isDirectory());
            });
          },
          (dirs) => {
            return cb(null, dirs);
          }
        );
      }


(file, next: (err: boolean) => void) => {
            fs.stat(path.join(basePath, file), (err, stats) => {
              return next(!err && stats.isDirectory());
            });
          }


(err, stats) => {
              return next(!err && stats.isDirectory());
            }


(dirs) => {
            return cb(null, dirs);
          }


(done) => {
          _readDirectories(this.templatePath, (err, res) => {
            this.availableLanguages = res;
            done(err);
          });
        }


(err, res) => {
            this.availableLanguages = res;
            done(err);
          }


(done) => {
          if (opts.storage) {
            this.storage = opts.storage;
            done();
          } else {
            this.storage = new Storage();
            this.storage.connect(
              opts.storageOpts,
              done
            );
          }
        }


(done) => {
          this.messageBroker =
            opts.messageBroker || new MessageBroker(opts.messageBrokerOpts);
          this.messageBroker.onMessage(
            _.bind(this._sendPushNotifications, this)
          );
          done();
        }


(err) => {
        if (err) {
          log.error(err);
        }
        return cb(err);
      }


(err, should) => {
      if (err) return cb(err);

      log.debug('Should send notification: ', should);
      if (!should) return cb();

      this._getRecipientsList(notification, notifType, (
        err,
        recipientsList
      ) => {
        if (err) return cb(err);

        async.waterfall(
          [
            (next) => {
              this._readAndApplyTemplates(
                notification,
                notifType,
                recipientsList,
                next
              );
            },
            (contents, next) => {
              async.map(
                recipientsList,
                (recipient: IPreferences, next) => {
                  const content = contents[recipient.language];

                  this.storage.fetchPushNotificationSubs(
                    recipient.copayerId,
                    (err, subs) => {
                      if (err) return next(err);

                      const notifications = _.map(subs, (sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      });
                      return next(err, notifications);
                    }
                  );
                },
                (err, allNotifications) => {
                  if (err) return next(err);
                  return next(null, _.flatten(allNotifications));
                }
              );
            },
            (notifications, next) => {
              async.each(
                notifications,
                (notification, next) => {
                  this._makeRequest(notification, (err, response) => {
                    if (err) log.error(err);
                    if (response) {
                      log.debug('Request status: ', response.statusCode);
                      log.debug('Request message: ', response.statusMessage);
                      log.debug('Request body: ', response.request.body);
                    }
                    next();
                  });
                },
                (err) => {
                  return next(err);
                }
              );
            }
          ],
          (err) => {
            if (err) {
              log.error('An error ocurred generating notification', err);
            }
            return cb(err);
          }
        );
      });
    }


(
        err,
        recipientsList
      ) => {
        if (err) return cb(err);

        async.waterfall(
          [
            (next) => {
              this._readAndApplyTemplates(
                notification,
                notifType,
                recipientsList,
                next
              );
            },
            (contents, next) => {
              async.map(
                recipientsList,
                (recipient: IPreferences, next) => {
                  const content = contents[recipient.language];

                  this.storage.fetchPushNotificationSubs(
                    recipient.copayerId,
                    (err, subs) => {
                      if (err) return next(err);

                      const notifications = _.map(subs, (sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      });
                      return next(err, notifications);
                    }
                  );
                },
                (err, allNotifications) => {
                  if (err) return next(err);
                  return next(null, _.flatten(allNotifications));
                }
              );
            },
            (notifications, next) => {
              async.each(
                notifications,
                (notification, next) => {
                  this._makeRequest(notification, (err, response) => {
                    if (err) log.error(err);
                    if (response) {
                      log.debug('Request status: ', response.statusCode);
                      log.debug('Request message: ', response.statusMessage);
                      log.debug('Request body: ', response.request.body);
                    }
                    next();
                  });
                },
                (err) => {
                  return next(err);
                }
              );
            }
          ],
          (err) => {
            if (err) {
              log.error('An error ocurred generating notification', err);
            }
            return cb(err);
          }
        );
      }


(next) => {
              this._readAndApplyTemplates(
                notification,
                notifType,
                recipientsList,
                next
              );
            }


(contents, next) => {
              async.map(
                recipientsList,
                (recipient: IPreferences, next) => {
                  const content = contents[recipient.language];

                  this.storage.fetchPushNotificationSubs(
                    recipient.copayerId,
                    (err, subs) => {
                      if (err) return next(err);

                      const notifications = _.map(subs, (sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      });
                      return next(err, notifications);
                    }
                  );
                },
                (err, allNotifications) => {
                  if (err) return next(err);
                  return next(null, _.flatten(allNotifications));
                }
              );
            }


(recipient: IPreferences, next) => {
                  const content = contents[recipient.language];

                  this.storage.fetchPushNotificationSubs(
                    recipient.copayerId,
                    (err, subs) => {
                      if (err) return next(err);

                      const notifications = _.map(subs, (sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      });
                      return next(err, notifications);
                    }
                  );
                }


(err, subs) => {
                      if (err) return next(err);

                      const notifications = _.map(subs, (sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      });
                      return next(err, notifications);
                    }


(sub) => {
                        return {
                          to: sub.token,
                          priority: 'high',
                          restricted_package_name: sub.packageName,
                          notification: {
                            title: content.plain.subject,
                            body: content.plain.body,
                            sound: 'default',
                            click_action: 'FCM_PLUGIN_ACTIVITY',
                            icon: 'fcm_push_icon'
                          },
                          data: {
                            walletId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(notification.walletId)
                            ),
                            copayerId: sjcl.codec.hex.fromBits(
                              sjcl.hash.sha256.hash(recipient.copayerId)
                            ),
                            title: content.plain.subject,
                            body: content.plain.body,
                            notification_type: notification.type
                          }
                        };
                      }


(err, allNotifications) => {
                  if (err) return next(err);
                  return next(null, _.flatten(allNotifications));
                }