/**
     * Should take in a string value and return a FdDatetime model object.
     * @param value String to concert to a FdDatetime model object.
     */
abstract parse(value: string): FdDatetime;


/**
     * Should take in a FdDatetime model object and return a string representation.
     * @param date FdDatetime object to concert to a date string.
     * Return null, to keep default angular DatePipe as a formatter.
     */
abstract format(date: FdDatetime): string;


/**
     * Takes in a string representation of a date and returns a FdDatetime object.
     * @param value String to convert to a FdDatetime model object.
     */
public parse(value: string): FdDatetime {
        if (!value) {
            return FdDatetime.getToday();
        } else {
            const date: Date = new Date(value);
            return new FdDatetime(new FdDate(date.getFullYear(), date.getMonth() + 1, date.getDate()), {
                hour: date.getHours(),
                minute: date.getMinutes(),
                second: date.getSeconds()
            });
        }
    }


/**
     * Takes in a FdDatetime object and returns the string representation.
     * @param date FdDatetime model object to convert to a string.
     * Return null, to keep default angular DatePipe as a formatter.
     */
public format(date: FdDatetime): string {
        return null;
    }


export function toLowerCase(value: string) {
  return value.replace(/\B([A-Z])/g, "-$1").toLowerCase()
}


(style: CSSProperties) =>
  Object.entries(style).reduce(
    (receiver, [k, v]) => receiver.concat(`${toLowerCase(k)}:${v};`),
    ""
  )


(receiver, [k, v]) => receiver.concat(`${toLowerCase(k)}:${v};`)


({ size, fill, style, className }) => {
  return <svg className={className} style={style} fill={fill} xmlns="http://www.w3.org/2000/svg"  height={size ?? "1em"}


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'project2Angular';
  constructor() {
  }
}


() => {
  let component: PhenoToolMeasureComponent;
  let fixture: ComponentFixture<PhenoToolMeasureComponent>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        PhenoToolMeasureComponent,
      ],
      providers: [
        MeasuresService,
        HttpClient,
        HttpHandler,
        ConfigService,
        DatasetsService,
        UsersService
      ],
      imports: [RouterTestingModule, NgxsModule.forRoot([], {developmentMode: true})],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PhenoToolMeasureComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
}


() => {
    TestBed.configureTestingModule({
      declarations: [
        PhenoToolMeasureComponent,
      ],
      providers: [
        MeasuresService,
        HttpClient,
        HttpHandler,
        ConfigService,
        DatasetsService,
        UsersService
      ],
      imports: [RouterTestingModule, NgxsModule.forRoot([], {developmentMode: true})],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }


() => {
    fixture = TestBed.createComponent(PhenoToolMeasureComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }


/**
     * Create a function that reports error by writing to the system and handles the formating of the diagnostic
     */
export function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter {
        const host: FormatDiagnosticsHost = system === sys ? sysFormatDiagnosticsHost : {
            getCurrentDirectory: () => system.getCurrentDirectory(),
            getNewLine: () => system.newLine,
            getCanonicalFileName: createGetCanonicalFileName(system.useCaseSensitiveFileNames),
        };
        if (!pretty) {
            return diagnostic => system.write(ts.formatDiagnostic(diagnostic, host));
        }

        const diagnostics: Diagnostic[] = new Array(1);
        return diagnostic => {
            diagnostics[0] = diagnostic;
            system.write(formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
            diagnostics[0] = undefined;
        };
    }


function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic) {
        if (system.clearScreen && diagnostic.code !== Diagnostics.Compilation_complete_Watching_for_file_changes.code) {
            system.clearScreen();
        }
    }


/**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
export function createWatchStatusReporter(system: System, pretty?: boolean): WatchStatusReporter {
        return pretty ?
        (diagnostic: Diagnostic, newLine: string) => {
            clearScreenIfNotWatchingForFileChanges(system, diagnostic);
            let output = `[${ formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey) }] `;
            output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
            system.write(output);
        } :
        (diagnostic: Diagnostic, newLine: string) => {
            clearScreenIfNotWatchingForFileChanges(system, diagnostic);
            let output = new Date().toLocaleTimeString() + " - ";
            output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
            system.write(output);
        };
    }


/** Parses config file using System interface */
export function parseConfigFileWithSystem(configFileName: string, optionsToExtend: CompilerOptions, system: System, reportDiagnostic: DiagnosticReporter) {
        const host: ParseConfigFileHost = <any>system;
        host.onConfigFileDiagnostic = reportDiagnostic;
        host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(sys, reportDiagnostic, diagnostic);
        const result = getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host);
        host.onConfigFileDiagnostic = undefined;
        host.onUnRecoverableConfigFileDiagnostic = undefined;
        return result;
    }


/**
     * Reads the config file, reports errors if any and exits if the config file cannot be found
     */
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
        let configFileText: string;
        try {
            configFileText = host.readFile(configFileName);
        }
        catch (e) {
            const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
            host.onUnRecoverableConfigFileDiagnostic(error);
            return undefined;
        }
        if (!configFileText) {
            const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
            host.onUnRecoverableConfigFileDiagnostic(error);
            return undefined;
        }

        const result = parseJsonText(configFileName, configFileText);
        result.parseDiagnostics.forEach(diagnostic => host.onConfigFileDiagnostic(diagnostic));

        const cwd = host.getCurrentDirectory();
        const configParseResult = parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
        configParseResult.errors.forEach(diagnostic => host.onConfigFileDiagnostic(diagnostic));

        return configParseResult;
    }


/**
     * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
     */
export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void) {
        // First get and report any syntactic errors.
        const diagnostics = program.getSyntacticDiagnostics().slice();
        let reportSemanticDiagnostics = false;

        // If we didn't have any syntactic errors, then also try getting the global and
        // semantic errors.
        if (diagnostics.length === 0) {
            addRange(diagnostics, program.getOptionsDiagnostics());
            addRange(diagnostics, program.getGlobalDiagnostics());

            if (diagnostics.length === 0) {
                reportSemanticDiagnostics = true;
            }
        }

        // Emit and report any errors we ran into.
        const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit();
        addRange(diagnostics, emitDiagnostics);

        if (reportSemanticDiagnostics) {
            addRange(diagnostics, program.getSemanticDiagnostics());
        }

        sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
        if (writeFileName) {
            const currentDir = program.getCurrentDirectory();
            forEach(emittedFiles, file => {
                const filepath = getNormalizedAbsolutePath(file, currentDir);
                writeFileName(`TSFILE: ${filepath}`);
            });

            if (program.getCompilerOptions().listFiles) {
                forEach(program.getSourceFiles(), file => {
                    writeFileName(file.fileName);
                });
            }
        }

        if (emitSkipped && diagnostics.length > 0) {
            // If the emitter didn't emit anything, then pass that value along.
            return ExitStatus.DiagnosticsPresent_OutputsSkipped;
        }
        else if (diagnostics.length > 0) {
            // The emitter emitted something, inform the caller if that happened in the presence
            // of diagnostics or not.
            return ExitStatus.DiagnosticsPresent_OutputsGenerated;
        }
        return ExitStatus.Success;
    }


/**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
function createWatchCompilerHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system = sys, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHost<T> {
        if (!createProgram) {
            createProgram = createEmitAndSemanticDiagnosticsBuilderProgram as any;
        }

        let host: DirectoryStructureHost = system;
        const useCaseSensitiveFileNames = () => system.useCaseSensitiveFileNames;
        const writeFileName = (s: string) => system.write(s + system.newLine);
        return {
            useCaseSensitiveFileNames,
            getNewLine: () => system.newLine,
            getCurrentDirectory: () => system.getCurrentDirectory(),
            getDefaultLibLocation,
            getDefaultLibFileName: options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)),
            fileExists: path => system.fileExists(path),
            readFile: (path, encoding) => system.readFile(path, encoding),
            directoryExists: path => system.directoryExists(path),
            getDirectories: path => system.getDirectories(path),
            readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth),
            realpath: system.realpath && (path => system.realpath(path)),
            getEnvironmentVariable: system.getEnvironmentVariable && (name => system.getEnvironmentVariable(name)),
            watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile(path, callback, pollingInterval)) : () => noopFileWatcher,
            watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory(path, callback, recursive)) : () => noopFileWatcher,
            setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout.call(system, callback, ms, ...args)) : noop,
            clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout(timeoutId)) : noop,
            trace: s => system.write(s),
            onWatchStatusChange: reportWatchStatus || createWatchStatusReporter(system),
            createDirectory: path => system.createDirectory(path),
            writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
            onCachedDirectoryStructureHostCreate: cacheHost => host = cacheHost || system,
            createHash: system.createHash && (s => system.createHash(s)),
            createProgram,
            afterProgramCreate: emitFilesAndReportErrorUsingBuilder
        };

        function getDefaultLibLocation() {
            return getDirectoryPath(normalizePath(system.getExecutingFilePath()));
        }

        function emitFilesAndReportErrorUsingBuilder(builderProgram: BuilderProgram) {
            emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName);
        }
    }


function getDefaultLibLocation() {
            return getDirectoryPath(normalizePath(system.getExecutingFilePath()));
        }


function emitFilesAndReportErrorUsingBuilder(builderProgram: BuilderProgram) {
            emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName);
        }


/**
     * Report error and exit
     */
function reportUnrecoverableDiagnostic(system: System, reportDiagnostic: DiagnosticReporter, diagnostic: Diagnostic) {
        reportDiagnostic(diagnostic);
        system.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
    }


/**
     * Creates the watch compiler host from system for config file in watch mode
     */
export function createWatchCompilerHostOfConfigFile<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T> {
        reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
        const host = createWatchCompilerHost(system, createProgram, reportDiagnostic, reportWatchStatus) as WatchCompilerHostOfConfigFile<T>;
        host.onConfigFileDiagnostic = reportDiagnostic;
        host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic);
        host.configFileName = configFileName;
        host.optionsToExtend = optionsToExtend;
        return host;
    }


/**
     * Creates the watch compiler host from system for compiling root files and options in watch mode
     */
export function createWatchCompilerHostOfFilesAndCompilerOptions<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T> {
        const host = createWatchCompilerHost(system, createProgram, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus) as WatchCompilerHostOfFilesAndCompilerOptions<T>;
        host.rootFiles = rootFiles;
        host.options = options;
        return host;
    }


/**
     * Create the watch compiler host for either configFile or fileNames and its options
     */
export function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;


export function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;


export function createWatchCompilerHost<T extends BuilderProgram>(rootFilesOrConfigFileName: string | string[], options: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T> | WatchCompilerHostOfConfigFile<T> {
        if (isArray(rootFilesOrConfigFileName)) {
            return createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
        }
        else {
            return createWatchCompilerHostOfConfigFile(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
        }
    }


/**
     * Creates the watch from the host for root files and compiler options
     */
export function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfFilesAndCompilerOptions<T>): WatchOfFilesAndCompilerOptions<T>;


/**
     * Creates the watch from the host for config file
     */
export function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;


function getCurrentBuilderProgram() {
            return builderProgram;
        }


function getCurrentProgram() {
            return builderProgram && builderProgram.getProgram();
        }


function synchronizeProgram() {
            writeLog(`Synchronizing program`);

            const program = getCurrentProgram();
            if (hasChangedCompilerOptions) {
                newLine = updateNewLine();
                if (program && changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
                    resolutionCache.clear();
                }
            }

            // All resolutions are invalid if user provided resolutions
            const hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution);
            if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames)) {
                return builderProgram;
            }

            // Compile the program
            const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !program;
            hasChangedCompilerOptions = false;
            resolutionCache.startCachingPerDirectoryResolution();
            compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
            compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
            builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram);
            resolutionCache.finishCachingPerDirectoryResolution();

            // Update watches
            updateMissingFilePathsWatch(builderProgram.getProgram(), missingFilesMap || (missingFilesMap = createMap()), watchMissingFilePath);
            if (needsUpdateInTypeRootWatch) {
                resolutionCache.updateTypeRootsWatch();
            }

            if (missingFilePathsRequestedForRelease) {
                // These are the paths that program creater told us as not in use any more but were missing on the disk.
                // We didnt remove the entry for them from sourceFiles cache so that we dont have to do File IO,
                // if there is already watcher for it (for missing files)
                // At this point our watches were updated, hence now we know that these paths are not tracked and need to be removed
                // so that at later time we have correct result of their presence
                for (const missingFilePath of missingFilePathsRequestedForRelease) {
                    if (!missingFilesMap.has(missingFilePath)) {
                        sourceFilesCache.delete(missingFilePath);
                    }
                }
                missingFilePathsRequestedForRelease = undefined;
            }

            if (host.afterProgramCreate) {
                host.afterProgramCreate(builderProgram);
            }
            reportWatchDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes);
            return builderProgram;
        }


function updateRootFileNames(files: string[]) {
            Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
            rootFileNames = files;
            scheduleProgramUpdate();
        }


function updateNewLine() {
            return getNewLineCharacter(compilerOptions, () => host.getNewLine());
        }


function toPath(fileName: string) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }


function fileExists(fileName: string) {
            const path = toPath(fileName);
            const hostSourceFileInfo = sourceFilesCache.get(path);
            if (hostSourceFileInfo !== undefined) {
                return !isString(hostSourceFileInfo);
            }

            return directoryStructureHost.fileExists(fileName);
        }


function getVersionedSourceFileByPath(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile {
            const hostSourceFile = sourceFilesCache.get(path);
            // No source file on the host
            if (isString(hostSourceFile)) {
                return undefined;
            }

            // Create new source file if requested or the versions dont match
            if (!hostSourceFile || shouldCreateNewSourceFile || hostSourceFile.version.toString() !== hostSourceFile.sourceFile.version) {
                const sourceFile = getNewSourceFile();
                if (hostSourceFile) {
                    if (shouldCreateNewSourceFile) {
                        hostSourceFile.version++;
                    }
                    if (sourceFile) {
                        hostSourceFile.sourceFile = sourceFile;
                        sourceFile.version = hostSourceFile.version.toString();
                        if (!hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher = watchFilePath(host, fileName, onSourceFileChange, path, writeLog);
                        }
                    }
                    else {
                        // There is no source file on host any more, close the watch, missing file paths will track it
                        hostSourceFile.fileWatcher.close();
                        sourceFilesCache.set(path, hostSourceFile.version.toString());
                    }
                }
                else {
                    let fileWatcher: FileWatcher;
                    if (sourceFile) {
                        sourceFile.version = "1";
                        fileWatcher = watchFilePath(host, fileName, onSourceFileChange, path, writeLog);
                        sourceFilesCache.set(path, { sourceFile, version: 1, fileWatcher });
                    }
                    else {
                        sourceFilesCache.set(path, "0");
                    }
                }
                return sourceFile;
            }
            return hostSourceFile.sourceFile;

            function getNewSourceFile() {
                let text: string;
                try {
                    performance.mark("beforeIORead");
                    text = host.readFile(fileName, compilerOptions.charset);
                    performance.mark("afterIORead");
                    performance.measure("I/O Read", "beforeIORead", "afterIORead");
                }
                catch (e) {
                    if (onError) {
                        onError(e.message);
                    }
                }

                return text !== undefined ? createSourceFile(fileName, text, languageVersion) : undefined;
            }
        }


function getNewSourceFile() {
                let text: string;
                try {
                    performance.mark("beforeIORead");
                    text = host.readFile(fileName, compilerOptions.charset);
                    performance.mark("afterIORead");
                    performance.measure("I/O Read", "beforeIORead", "afterIORead");
                }
                catch (e) {
                    if (onError) {
                        onError(e.message);
                    }
                }

                return text !== undefined ? createSourceFile(fileName, text, languageVersion) : undefined;
            }


function removeSourceFile(path: Path) {
            const hostSourceFile = sourceFilesCache.get(path);
            if (hostSourceFile !== undefined) {
                if (!isString(hostSourceFile)) {
                    hostSourceFile.fileWatcher.close();
                    resolutionCache.invalidateResolutionOfFile(path);
                }
                sourceFilesCache.delete(path);
            }
        }


function getSourceVersion(path: Path): string {
            const hostSourceFile = sourceFilesCache.get(path);
            return !hostSourceFile || isString(hostSourceFile) ? undefined : hostSourceFile.version.toString();
        }


function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions) {
            const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.path);
            // If this is the source file thats in the cache and new program doesnt need it,
            // remove the cached entry.
            // Note we arent deleting entry if file became missing in new program or
            // there was version update and new source file was created.
            if (hostSourceFileInfo) {
                // record the missing file paths so they can be removed later if watchers arent tracking them
                if (isString(hostSourceFileInfo)) {
                    (missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
                }
                else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
                    sourceFilesCache.delete(oldSourceFile.path);
                    resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
                }
            }
        }


function reportWatchDiagnostic(message: DiagnosticMessage) {
            if (host.onWatchStatusChange) {
                host.onWatchStatusChange(createCompilerDiagnostic(message), newLine);
            }
        }


// Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
// operations (such as saving all modified files in an editor) a chance to complete before we kick
// off a new compilation.
function scheduleProgramUpdate() {
            if (!host.setTimeout || !host.clearTimeout) {
                return;
            }

            if (timerToUpdateProgram) {
                host.clearTimeout(timerToUpdateProgram);
            }
            timerToUpdateProgram = host.setTimeout(updateProgram, 250);
        }


function scheduleProgramReload() {
            Debug.assert(!!configFileName);
            reloadLevel = ConfigFileProgramReloadLevel.Full;
            scheduleProgramUpdate();
        }


function updateProgram() {
            timerToUpdateProgram = undefined;
            reportWatchDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation);

            switch (reloadLevel) {
                case ConfigFileProgramReloadLevel.Partial:
                    return reloadFileNamesFromConfigFile();
                case ConfigFileProgramReloadLevel.Full:
                    return reloadConfigFile();
                default:
                    synchronizeProgram();
                    return;
            }
        }


function reloadFileNamesFromConfigFile() {
            const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, parseConfigFileHost);
            if (!configFileSpecs.filesSpecs && result.fileNames.length === 0) {
                host.onConfigFileDiagnostic(getErrorForNoInputFiles(configFileSpecs, configFileName));
            }
            rootFileNames = result.fileNames;

            // Update the program
            synchronizeProgram();
        }


function reloadConfigFile() {
            writeLog(`Reloading config file: ${configFileName}`);
            reloadLevel = ConfigFileProgramReloadLevel.None;

            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.clearCache();
            }
            parseConfigFile();
            hasChangedCompilerOptions = true;
            synchronizeProgram();

            // Update the wild card directory watch
            watchConfigFileWildCardDirectories();
        }


function parseConfigFile() {
            const configParseResult = ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost);
            rootFileNames = configParseResult.fileNames;
            compilerOptions = configParseResult.options;
            configFileSpecs = configParseResult.configFileSpecs;
            configFileWildCardDirectories = configParseResult.wildcardDirectories;
        }


function onSourceFileChange(fileName: string, eventKind: FileWatcherEventKind, path: Path) {
            updateCachedSystemWithFile(fileName, path, eventKind);
            const hostSourceFile = sourceFilesCache.get(path);
            if (hostSourceFile) {
                // Update the cache
                if (eventKind === FileWatcherEventKind.Deleted) {
                    resolutionCache.invalidateResolutionOfFile(path);
                    if (!isString(hostSourceFile)) {
                        hostSourceFile.fileWatcher.close();
                        sourceFilesCache.set(path, (++hostSourceFile.version).toString());
                    }
                }
                else {
                    // Deleted file created
                    if (isString(hostSourceFile)) {
                        sourceFilesCache.delete(path);
                    }
                    else {
                        // file changed - just update the version
                        hostSourceFile.version++;
                    }
                }
            }

            // Update the program
            scheduleProgramUpdate();
        }


function updateCachedSystemWithFile(fileName: string, path: Path, eventKind: FileWatcherEventKind) {
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.addOrDeleteFile(fileName, path, eventKind);
            }
        }


function watchDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags) {
            return watchDirectoryWorker(host, directory, cb, flags, writeLog);
        }


function watchMissingFilePath(missingFilePath: Path) {
            return watchFilePath(host, missingFilePath, onMissingFileChange, missingFilePath, writeLog);
        }


function onMissingFileChange(fileName: string, eventKind: FileWatcherEventKind, missingFilePath: Path) {
            updateCachedSystemWithFile(fileName, missingFilePath, eventKind);

            if (eventKind === FileWatcherEventKind.Created && missingFilesMap.has(missingFilePath)) {
                missingFilesMap.get(missingFilePath).close();
                missingFilesMap.delete(missingFilePath);

                // Delete the entry in the source files cache so that new source file is created
                removeSourceFile(missingFilePath);

                // When a missing file is created, we should update the graph.
                scheduleProgramUpdate();
            }
        }


function watchConfigFileWildCardDirectories() {
            if (configFileWildCardDirectories) {
                updateWatchingWildcardDirectories(
                    watchedWildcardDirectories || (watchedWildcardDirectories = createMap()),
                    createMapFromTemplate(configFileWildCardDirectories),
                    watchWildcardDirectory
                );
            }
            else if (watchedWildcardDirectories) {
                clearMap(watchedWildcardDirectories, closeFileWatcherOf);
            }
        }


function watchWildcardDirectory(directory: string, flags: WatchDirectoryFlags) {
            return watchDirectory(
                directory,
                fileOrDirectory => {
                    Debug.assert(!!configFileName);

                    const fileOrDirectoryPath = toPath(fileOrDirectory);

                    // Since the file existance changed, update the sourceFiles cache
                    const result = cachedDirectoryStructureHost && cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);

                    // Instead of deleting the file, mark it as changed instead
                    // Many times node calls add/remove/file when watching directories recursively
                    const hostSourceFile = sourceFilesCache.get(fileOrDirectoryPath);
                    if (hostSourceFile && !isString(hostSourceFile) && (result ? result.fileExists : directoryStructureHost.fileExists(fileOrDirectory))) {
                        hostSourceFile.version++;
                    }
                    else {
                        removeSourceFile(fileOrDirectoryPath);
                    }

                    // If the the added or created file or directory is not supported file name, ignore the file
                    // But when watched directory is added/removed, we need to reload the file list
                    if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
                        writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
                        return;
                    }

                    // Reload is pending, do the reload
                    if (reloadLevel !== ConfigFileProgramReloadLevel.Full) {
                        reloadLevel = ConfigFileProgramReloadLevel.Partial;

                        // Schedule Update the program
                        scheduleProgramUpdate();
                    }
                },
                flags
            );
        }


function ensureDirectoriesExist(directoryPath: string) {
            if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists(directoryPath)) {
                const parentDirectory = getDirectoryPath(directoryPath);
                ensureDirectoriesExist(parentDirectory);
                host.createDirectory(directoryPath);
            }
        }


function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
            try {
                performance.mark("beforeIOWrite");
                ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));

                host.writeFile(fileName, text, writeByteOrderMark);

                performance.mark("afterIOWrite");
                performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }


() => sys.getCurrentDirectory()


() => sys.newLine


() => system.getCurrentDirectory()


() => system.newLine


diagnostic => system.write(ts.formatDiagnostic(diagnostic, host))


diagnostic => {
            diagnostics[0] = diagnostic;
            system.write(formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
            diagnostics[0] = undefined;
        }


(diagnostic: Diagnostic, newLine: string) => {
            clearScreenIfNotWatchingForFileChanges(system, diagnostic);
            let output = `[${ formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey) }] `;
            output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
            system.write(output);
        }


(diagnostic: Diagnostic, newLine: string) => {
            clearScreenIfNotWatchingForFileChanges(system, diagnostic);
            let output = new Date().toLocaleTimeString() + " - ";
            output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
            system.write(output);
        }


diagnostic => reportUnrecoverableDiagnostic(sys, reportDiagnostic, diagnostic)


diagnostic => host.onConfigFileDiagnostic(diagnostic)


file => {
                const filepath = getNormalizedAbsolutePath(file, currentDir);
                writeFileName(`TSFILE: ${filepath}`);
            }


file => {
                    writeFileName(file.fileName);
                }


() => system.useCaseSensitiveFileNames


(s: string) => system.write(s + system.newLine)


options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options))


path => system.fileExists(path)


(path, encoding) => system.readFile(path, encoding)


path => system.directoryExists(path)


path => system.getDirectories(path)


(path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth)


path => system.realpath(path)


name => system.getEnvironmentVariable(name)


(path, callback, pollingInterval) => system.watchFile(path, callback, pollingInterval)


() => noopFileWatcher


(path, callback, recursive) => system.watchDirectory(path, callback, recursive)


(callback, ms, ...args: any[]) => system.setTimeout.call(system, callback, ms, ...args)


timeoutId => system.clearTimeout(timeoutId)


s => system.write(s)


path => system.createDirectory(path)


(path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark)


cacheHost => host = cacheHost || system


s => system.createHash(s)


diagnostic => reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic)


() => currentDirectory


(path, encoding) => host.readFile(path, encoding)


(path, extensions, exclude, include, depth) => directoryStructureHost.readDirectory(path, extensions, exclude, include, depth)


path => host.fileExists(path)


(s: string) => { host.trace(s + newLine); }


(fileName, languageVersion, onError?, shouldCreateNewSourceFile?) => getVersionedSourceFileByPath(fileName, toPath(fileName), languageVersion, onError, shouldCreateNewSourceFile)


() => host.getDefaultLibLocation()


options => host.getDefaultLibFileName(options)


() => useCaseSensitiveFileNames


() => newLine


path => directoryStructureHost.directoryExists(path)


path => directoryStructureHost.getDirectories(path)


s => host.realpath(s)


name => host.getEnvironmentVariable(name)


data => host.createHash(data)


() => compilerOptions


() => cachedDirectoryStructureHost


() => {
                hasChangedAutomaticTypeDirectiveNames = true;
                scheduleProgramUpdate();
            }


(moduleNames, containingFile, reusedNames) => host.resolveModuleNames(moduleNames, containingFile, reusedNames)


(moduleNames, containingFile, reusedNames) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames)


(typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile)


(typeDirectiveNames, containingFile) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile)


() => host.getNewLine()


fileOrDirectory => {
                    Debug.assert(!!configFileName);

                    const fileOrDirectoryPath = toPath(fileOrDirectory);

                    // Since the file existance changed, update the sourceFiles cache
                    const result = cachedDirectoryStructureHost && cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);

                    // Instead of deleting the file, mark it as changed instead
                    // Many times node calls add/remove/file when watching directories recursively
                    const hostSourceFile = sourceFilesCache.get(fileOrDirectoryPath);
                    if (hostSourceFile && !isString(hostSourceFile) && (result ? result.fileExists : directoryStructureHost.fileExists(fileOrDirectory))) {
                        hostSourceFile.version++;
                    }
                    else {
                        removeSourceFile(fileOrDirectoryPath);
                    }

                    // If the the added or created file or directory is not supported file name, ignore the file
                    // But when watched directory is added/removed, we need to reload the file list
                    if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
                        writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
                        return;
                    }

                    // Reload is pending, do the reload
                    if (reloadLevel !== ConfigFileProgramReloadLevel.Full) {
                        reloadLevel = ConfigFileProgramReloadLevel.Partial;

                        // Schedule Update the program
                        scheduleProgramUpdate();
                    }
                }


/**
     * Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
     */
export interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
        getCurrentDirectory(): string;
    }


/**
     * Program structure needed to emit the files and report diagnostics
     */
export interface ProgramToEmitFilesAndReportErrors {
        getCurrentDirectory(): string;
        getCompilerOptions(): CompilerOptions;
        getSourceFiles(): ReadonlyArray<SourceFile>;
        getSyntacticDiagnostics(): ReadonlyArray<Diagnostic>;
        getOptionsDiagnostics(): ReadonlyArray<Diagnostic>;
        getGlobalDiagnostics(): ReadonlyArray<Diagnostic>;
        getSemanticDiagnostics(): ReadonlyArray<Diagnostic>;
        emit(): EmitResult;
    }


export interface WatchCompilerHost<T extends BuilderProgram> {
        /**
         * Used to create the program when need for program creation or recreation detected
         */
        createProgram: CreateProgram<T>;
        /** If provided, callback to invoke after every new program creation */
        afterProgramCreate?(program: T): void;
        /** If provided, called with Diagnostic message that informs about change in watch status */
        onWatchStatusChange?(diagnostic: Diagnostic, newLine: string): void;

        // Only for testing
        /*@internal*/
        maxNumberOfFilesToIterateForInvalidation?: number;

        // Sub set of compiler host methods to read and generate new program
        useCaseSensitiveFileNames(): boolean;
        getNewLine(): string;
        getCurrentDirectory(): string;
        getDefaultLibFileName(options: CompilerOptions): string;
        getDefaultLibLocation?(): string;
        createHash?(data: string): string;

        /**
         * Use to check file presence for source files and
         * if resolveModuleNames is not provided (complier is in charge of module resolution) then module files as well
         */
        fileExists(path: string): boolean;
        /**
         * Use to read file text for source files and
         * if resolveModuleNames is not provided (complier is in charge of module resolution) then module files as well
         */
        readFile(path: string, encoding?: string): string | undefined;

        /** If provided, used for module resolution as well as to handle directory structure */
        directoryExists?(path: string): boolean;
        /** If provided, used in resolutions as well as handling directory structure */
        getDirectories?(path: string): string[];
        /** If provided, used to cache and handle directory structure modifications */
        readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];

        /** Symbol links resolution */
        realpath?(path: string): string;
        /** If provided would be used to write log about compilation */
        trace?(s: string): void;
        /** If provided is used to get the environment variable */
        getEnvironmentVariable?(name: string): string;

        /** If provided, used to resolve the module names, otherwise typescript's default module resolution */
        resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
        /** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
        resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];

        /** Used to watch changes in source files, missing files needed to update the program or config file */
        watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
        /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
        watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
        /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
        setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
        /** If provided, will be used to reset existing delayed compilation */
        clearTimeout?(timeoutId: any): void;
    }


/** Internal interface used to wire emit through same host */
/*@internal*/
export interface WatchCompilerHost<T extends BuilderProgram> {
        createDirectory?(path: string): void;
        writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
        onCachedDirectoryStructureHostCreate?(host: CachedDirectoryStructureHost): void;
    }


/**
     * Host to create watch with root files and options
     */
export interface WatchCompilerHostOfFilesAndCompilerOptions<T extends BuilderProgram> extends WatchCompilerHost<T> {
        /** root files to use to generate program */
        rootFiles: string[];

        /** Compiler options */
        options: CompilerOptions;
    }


/**
     * Reports config file diagnostics
     */
export interface ConfigFileDiagnosticsReporter {
        /**
         * Reports the diagnostics in reading/writing or parsing of the config file
         */
        onConfigFileDiagnostic: DiagnosticReporter;

        /**
         * Reports unrecoverable error when parsing config file
         */
        onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
    }


/**
     * Host to create watch with config file
     */
export interface WatchCompilerHostOfConfigFile<T extends BuilderProgram> extends WatchCompilerHost<T>, ConfigFileDiagnosticsReporter {
        /** Name of the config file to compile */
        configFileName: string;

        /** Options to extend */
        optionsToExtend?: CompilerOptions;

        /**
         * Used to generate source file names from the config file and its include, exclude, files rules
         * and also to cache the directory stucture
         */
        readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
    }


/**
     * Host to create watch with config file that is already parsed (from tsc)
     */
/*@internal*/
export interface WatchCompilerHostOfConfigFile<T extends BuilderProgram> extends WatchCompilerHost<T> {
        rootFiles?: string[];
        options?: CompilerOptions;
        optionsToExtend?: CompilerOptions;
        configFileSpecs?: ConfigFileSpecs;
        configFileWildCardDirectories?: MapLike<WatchDirectoryFlags>;
    }


export interface Watch<T> {
        /** Synchronize with host and get updated program */
        getProgram(): T;
        /** Gets the existing program without synchronizing with changes on host */
        /*@internal*/
        getCurrentProgram(): T;
    }


/**
     * Creates the watch what generates program using the config file
     */
export interface WatchOfConfigFile<T> extends Watch<T> {
    }


/**
     * Creates the watch that generates program using the root files and compiler options
     */
export interface WatchOfFilesAndCompilerOptions<T> extends Watch<T> {
        /** Updates the root files in the program, only if this is not config file compilation */
        updateRootFileNames(fileNames: string[]): void;
    }


interface HostFileInfo {
            version: number;
            sourceFile: SourceFile;
            fileWatcher: FileWatcher;
        }


export type DiagnosticReporter = (diagnostic: Diagnostic) => void;


export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string) => void;


export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: T) => T;


export interface MessageEvent {
    data: string;
}


// T => Promise<T> and Promise<T> => Promise<T>
type Promisify<T> = T extends Promise<unknown>
    ? T
    : T extends boolean
    ? Promise<boolean>
    : Promise<T>;


export type JavascriptInterface<T> = {
    [P in keyof T]: T[P] extends (...args: infer Arguments) => infer R
        ? (...args: Arguments) => Promisify<R>
        : never;
};


/**
 * Extend to add more terminal context menu items
 * @deprecated
 */
export abstract class TerminalContextMenuItemProvider {
    weight: number

    abstract getItems (tab: BaseTerminalTabComponent): Promise<MenuItemOptions[]>
}


abstract getItems (tab: BaseTerminalTabComponent): Promise<MenuItemOptions[]>


({ shapeAtom }) => {
    const [shape] = useAtom(shapeAtom)
    const [selected, select] = useAtom(selectAtom)

    return (
      <g
        transform={`translate(${shape.x} ${shape.y})`}


export function astFromType(type: GraphQLType): TypeNode {
  if (isNonNullType(type)) {
    const innerType = astFromType(type.ofType);
    if (innerType.kind === Kind.NON_NULL_TYPE) {
      throw new Error(
        `Invalid type node ${JSON.stringify(type)}. Inner type of non-null type cannot be a non-null type.`
      );
    }
    return {
      kind: Kind.NON_NULL_TYPE,
      type: innerType,
    };
  } else if (isListType(type)) {
    return {
      kind: Kind.LIST_TYPE,
      type: astFromType(type.ofType),
    };
  }

  return {
    kind: Kind.NAMED_TYPE,
    name: {
      kind: Kind.NAME,
      value: type.name,
    },
  };
}


@Injectable({
  providedIn: 'root'
})
export class TokenStorageService {
  private roles: Array<string> = [];
  constructor() { }

  signOut() {
    window.localStorage.clear();
  }

  public saveToken(token: string) {
    window.localStorage.removeItem(TOKEN_KEY);
    window.localStorage.setItem(TOKEN_KEY, token);
  }

  public getToken(): string {
    return localStorage.getItem(TOKEN_KEY);
  }

  public saveUsername(username: string) {
    window.localStorage.removeItem(USERNAME_KEY);
    window.localStorage.setItem(USERNAME_KEY, username);
  }

  public getUsername(): string {
    return localStorage.getItem(USERNAME_KEY);
  }

  public saveName(name: string) {
    window.localStorage.removeItem(NAME_KEY);
    window.localStorage.setItem(NAME_KEY, name);
  }

  public getName(): string {
    return localStorage.getItem(NAME_KEY);
  }

  public saveUserId(userid: number) {
    window.localStorage.removeItem(USERID_KEY);
    window.localStorage.setItem(USERID_KEY, userid.toString());
  }

  public getUserId(): number {
    return +localStorage.getItem(USERID_KEY);
  }

  public saveAuthorities(authorities: string[]) {
    window.localStorage.removeItem(AUTHORITIES_KEY);
    window.localStorage.setItem(AUTHORITIES_KEY, JSON.stringify(authorities));
  }

  public getAuthorities(): string[] {
    this.roles = [];

    if (localStorage.getItem(TOKEN_KEY)) {
      // 27-11-19
      // JSON.parse(localStorage.getItem(AUTHORITIES_KEY)).forEach(authority => {
      //   this.roles.push(authority.authority);
      // });
    }

    return this.roles;
  }
}


signOut() {
    window.localStorage.clear();
  }


public saveToken(token: string) {
    window.localStorage.removeItem(TOKEN_KEY);
    window.localStorage.setItem(TOKEN_KEY, token);
  }


public getToken(): string {
    return localStorage.getItem(TOKEN_KEY);
  }


public saveUsername(username: string) {
    window.localStorage.removeItem(USERNAME_KEY);
    window.localStorage.setItem(USERNAME_KEY, username);
  }


public getUsername(): string {
    return localStorage.getItem(USERNAME_KEY);
  }


public saveName(name: string) {
    window.localStorage.removeItem(NAME_KEY);
    window.localStorage.setItem(NAME_KEY, name);
  }


public getName(): string {
    return localStorage.getItem(NAME_KEY);
  }


public saveUserId(userid: number) {
    window.localStorage.removeItem(USERID_KEY);
    window.localStorage.setItem(USERID_KEY, userid.toString());
  }


public getUserId(): number {
    return +localStorage.getItem(USERID_KEY);
  }


public saveAuthorities(authorities: string[]) {
    window.localStorage.removeItem(AUTHORITIES_KEY);
    window.localStorage.setItem(AUTHORITIES_KEY, JSON.stringify(authorities));
  }


public getAuthorities(): string[] {
    this.roles = [];

    if (localStorage.getItem(TOKEN_KEY)) {
      // 27-11-19
      // JSON.parse(localStorage.getItem(AUTHORITIES_KEY)).forEach(authority => {
      //   this.roles.push(authority.authority);
      // });
    }

    return this.roles;
  }


export default class GuildLevelItemCriterion extends ItemCriterion {

}


(params: VertoParams) => {
  if (params.hasOwnProperty('dialogParams')) {
    // prettier-ignore
    const {
      remoteSdp,
      localStream,
      remoteStream,
      ...dialogParams
    } = params.dialogParams
    for (const key in tmpMap) {
      if (key && dialogParams.hasOwnProperty(key)) {
        // @ts-ignore
        dialogParams[tmpMap[key]] = dialogParams[key]
        delete dialogParams[key]
      }
    }
    params.dialogParams = dialogParams
  }

  return params
}


(method: VertoMethod) => {
  return (params: VertoParams = {}) => {
    return makeRPCRequest({
      method,
      params: filterVertoParams(params),
    })
  }
}


(params: VertoParams = {}) => {
    return makeRPCRequest({
      method,
      params: filterVertoParams(params),
    })
  }


(id: string, method: VertoMethod) => {
  return makeRPCResponse({
    id,
    result: {
      method,
    },
  })
}


type VertoParams = { [key: string]: any }


// Canonical URL for ValueSet: http://hl7.org/fhir/ValueSet/subject-type
type Subjecttype = "Patient" | "Practitioner" | "Organization" | "Location" | "Device";


({ didMount$, didUnmount$ }) => {
  const cancel = cs();
  const reset = cs();
  const state$ = Atom.create<IState>({
    stage: 0,
    fig: createFig<IParseFileState>({
      value: {
        progress: 0,
        result: {
          created: 0,
          ignored: 0,
        },
        lastRows: [],
      },
    }),
  });

  didMount$
    .pipe(
      switchMap(() =>
        concat(
          parseFile$((records) => tachka.recordValidate(records)).pipe(
            tap({
              complete: () => {
                state$.lens('stage').set(1);
              },
            })
          ),
          parseFile$((records) => tachka.recordAdd(records)).pipe(
            tap({
              complete: () => {
                state$.lens('stage').set(2);
                stateCsvImporter$.lens('completed').set(5);
              },
            })
          )
        ).pipe(
          tap({
            error: () => {
              stateCsvImporter$.lens('completed').set(4);
            },
          }),
          figProjection(state$.lens('fig'), { skipProgress: true })
        )
      ),
      takeUntil(didUnmount$)
    )
    .subscribe();

  cancel.$.pipe(takeUntil(didUnmount$)).subscribe(() => {
    const {
      stage,
      fig: {
        error,
        value: { lastRows },
      },
    } = state$.get();

    if (stage === 0 && isDefined(error) && error.message.startsWith('400: Validation error')) {
      const potentialIndex = error.message.match(/at (\d+)\./);
      if (isNotNull(potentialIndex)) {
        const index = Number(potentialIndex[1]);
        const item = lastRows[index];
        if (isDefined(item)) {
          return stateCsvImporter$.modify((state) =>
            produce(state, (draft) => {
              draft.step = 2;
              draft.completed = 4;
              draft.mapOptions.row = { item, index };
            })
          );
        }
      }
    }

    stateCsvImporter$.modify((state) => ({ ...state, step: 2, completed: 4 }));
  });

  reset.$.pipe(takeUntil(didUnmount$)).subscribe(() => {
    stateCsvImporter$.lens('step').set(0);
  });

  return { cancel, reset, state$ };
}


() =>
        concat(
          parseFile$((records) => tachka.recordValidate(records)).pipe(
            tap({
              complete: () => {
                state$.lens('stage').set(1);
              },
            })
          ),
          parseFile$((records) => tachka.recordAdd(records)).pipe(
            tap({
              complete: () => {
                state$.lens('stage').set(2);
                stateCsvImporter$.lens('completed').set(5);
              },
            })
          )
        ).pipe(
          tap({
            error: () => {
              stateCsvImporter$.lens('completed').set(4);
            },
          }),
          figProjection(state$.lens('fig'), { skipProgress: true })
        )


(records) => tachka.recordValidate(records)


() => {
                state$.lens('stage').set(1);
              }


(records) => tachka.recordAdd(records)


() => {
                state$.lens('stage').set(2);
                stateCsvImporter$.lens('completed').set(5);
              }


() => {
              stateCsvImporter$.lens('completed').set(4);
            }


() => {
    const {
      stage,
      fig: {
        error,
        value: { lastRows },
      },
    } = state$.get();

    if (stage === 0 && isDefined(error) && error.message.startsWith('400: Validation error')) {
      const potentialIndex = error.message.match(/at (\d+)\./);
      if (isNotNull(potentialIndex)) {
        const index = Number(potentialIndex[1]);
        const item = lastRows[index];
        if (isDefined(item)) {
          return stateCsvImporter$.modify((state) =>
            produce(state, (draft) => {
              draft.step = 2;
              draft.completed = 4;
              draft.mapOptions.row = { item, index };
            })
          );
        }
      }
    }

    stateCsvImporter$.modify((state) => ({ ...state, step: 2, completed: 4 }));
  }


(state) =>
            produce(state, (draft) => {
              draft.step = 2;
              draft.completed = 4;
              draft.mapOptions.row = { item, index };
            })


(draft) => {
              draft.step = 2;
              draft.completed = 4;
              draft.mapOptions.row = { item, index };
            }


(state) => ({ ...state, step: 2, completed: 4 })


() => {
    stateCsvImporter$.lens('step').set(0);
  }


(work: (records: IRecordCreate[]) => Promise<unknown>) =>
  new Observable<IParseFileState>((subscriber) => {
    let nChunks = 0;
    let estimated = 63;
    let processed = 0;
    const { file, parserOptions, mapOptions } = stateCsvImporter$.get();

    if (!isDefined(file)) {
      return subscriber.error(new Error('Please select file'));
    }

    const result: IParseFileState = {
      progress: 0,
      result: {
        created: 0,
        ignored: 0,
      },
      lastRows: [],
    };

    Papa.parse(file, {
      skipEmptyLines: parserOptions.skipEmpty ? 'greedy' : false,
      quoteChar: parserOptions.quoteChar,
      escapeChar: parserOptions.escapeChar,
      comments: parserOptions.commentStr,

      chunkSize: 2000,

      error: (error) => {
        subscriber.error(error);
      },

      chunk: ({ data }, parser) => {
        try {
          if (subscriber.closed) {
            return parser.abort();
          }

          parser.pause();

          const rows = data.map((item) => (item as unknown[]).map((i) => (isText(i) ? i : '')));

          // for first chunk
          if (++nChunks === 1) {
            if (parserOptions.hasHeader) {
              rows.shift();
            }

            if (rows.length === 0) {
              throw new Error('File has no data');
            }

            result.progress = 2;

            // estimate amount of records in file
            const totalRowBytes = rows.reduce((prevCount, row) => {
              const rowBytes = row.reduce((prev, item) => {
                return prev + countUTF8Bytes(item) + 1; // add a byte for separator or newline
              }, 0);
              return prevCount + rowBytes;
            }, 0);

            const averageRowSize = totalRowBytes / rows.length;

            if (averageRowSize > 1) {
              estimated = file.size / averageRowSize;
            }
          }

          const records: IRecordCreate[] = [];
          const lastRows: string[][] = [];

          mapRowsToRecords({ code: mapOptions.code, rows }).forEach((record, index) => {
            if (isDefined(record)) {
              records.push(record);
              lastRows.push(rows[index]);
            }
          });

          subscriber.next({ ...result, lastRows });

          const afterWork = records.length > 0 ? work(records) : Promise.resolve();

          afterWork
            .then((res) => {
              // inputs hand-picked so that correctly estimated total is about 75% of the bar
              const progressPower = 2.5 * ((processed += rows.length) / estimated);
              const progressLeft = 0.5 ** progressPower;

              // convert to .1 percent precision for smoother bar display
              result.progress = Math.floor(1000 - 1000 * progressLeft) / 10;

              if (isResCreated(res)) {
                result.result.created += res.created;
                result.result.ignored += res.ignored;
              }

              subscriber.next({ ...result });
              parser.resume();
            })
            .catch((error) => {
              subscriber.error(error);
            });
        } catch (error) {
          subscriber.error(error);
        }
      },

      complete() {
        subscriber.next({ ...result, progress: 100 });
        subscriber.complete();
      },
    });
  })


(subscriber) => {
    let nChunks = 0;
    let estimated = 63;
    let processed = 0;
    const { file, parserOptions, mapOptions } = stateCsvImporter$.get();

    if (!isDefined(file)) {
      return subscriber.error(new Error('Please select file'));
    }

    const result: IParseFileState = {
      progress: 0,
      result: {
        created: 0,
        ignored: 0,
      },
      lastRows: [],
    };

    Papa.parse(file, {
      skipEmptyLines: parserOptions.skipEmpty ? 'greedy' : false,
      quoteChar: parserOptions.quoteChar,
      escapeChar: parserOptions.escapeChar,
      comments: parserOptions.commentStr,

      chunkSize: 2000,

      error: (error) => {
        subscriber.error(error);
      },

      chunk: ({ data }, parser) => {
        try {
          if (subscriber.closed) {
            return parser.abort();
          }

          parser.pause();

          const rows = data.map((item) => (item as unknown[]).map((i) => (isText(i) ? i : '')));

          // for first chunk
          if (++nChunks === 1) {
            if (parserOptions.hasHeader) {
              rows.shift();
            }

            if (rows.length === 0) {
              throw new Error('File has no data');
            }

            result.progress = 2;

            // estimate amount of records in file
            const totalRowBytes = rows.reduce((prevCount, row) => {
              const rowBytes = row.reduce((prev, item) => {
                return prev + countUTF8Bytes(item) + 1; // add a byte for separator or newline
              }, 0);
              return prevCount + rowBytes;
            }, 0);

            const averageRowSize = totalRowBytes / rows.length;

            if (averageRowSize > 1) {
              estimated = file.size / averageRowSize;
            }
          }

          const records: IRecordCreate[] = [];
          const lastRows: string[][] = [];

          mapRowsToRecords({ code: mapOptions.code, rows }).forEach((record, index) => {
            if (isDefined(record)) {
              records.push(record);
              lastRows.push(rows[index]);
            }
          });

          subscriber.next({ ...result, lastRows });

          const afterWork = records.length > 0 ? work(records) : Promise.resolve();

          afterWork
            .then((res) => {
              // inputs hand-picked so that correctly estimated total is about 75% of the bar
              const progressPower = 2.5 * ((processed += rows.length) / estimated);
              const progressLeft = 0.5 ** progressPower;

              // convert to .1 percent precision for smoother bar display
              result.progress = Math.floor(1000 - 1000 * progressLeft) / 10;

              if (isResCreated(res)) {
                result.result.created += res.created;
                result.result.ignored += res.ignored;
              }

              subscriber.next({ ...result });
              parser.resume();
            })
            .catch((error) => {
              subscriber.error(error);
            });
        } catch (error) {
          subscriber.error(error);
        }
      },

      complete() {
        subscriber.next({ ...result, progress: 100 });
        subscriber.complete();
      },
    });
  }


(error) => {
        subscriber.error(error);
      }


({ data }, parser) => {
        try {
          if (subscriber.closed) {
            return parser.abort();
          }

          parser.pause();

          const rows = data.map((item) => (item as unknown[]).map((i) => (isText(i) ? i : '')));

          // for first chunk
          if (++nChunks === 1) {
            if (parserOptions.hasHeader) {
              rows.shift();
            }

            if (rows.length === 0) {
              throw new Error('File has no data');
            }

            result.progress = 2;

            // estimate amount of records in file
            const totalRowBytes = rows.reduce((prevCount, row) => {
              const rowBytes = row.reduce((prev, item) => {
                return prev + countUTF8Bytes(item) + 1; // add a byte for separator or newline
              }, 0);
              return prevCount + rowBytes;
            }, 0);

            const averageRowSize = totalRowBytes / rows.length;

            if (averageRowSize > 1) {
              estimated = file.size / averageRowSize;
            }
          }

          const records: IRecordCreate[] = [];
          const lastRows: string[][] = [];

          mapRowsToRecords({ code: mapOptions.code, rows }).forEach((record, index) => {
            if (isDefined(record)) {
              records.push(record);
              lastRows.push(rows[index]);
            }
          });

          subscriber.next({ ...result, lastRows });

          const afterWork = records.length > 0 ? work(records) : Promise.resolve();

          afterWork
            .then((res) => {
              // inputs hand-picked so that correctly estimated total is about 75% of the bar
              const progressPower = 2.5 * ((processed += rows.length) / estimated);
              const progressLeft = 0.5 ** progressPower;

              // convert to .1 percent precision for smoother bar display
              result.progress = Math.floor(1000 - 1000 * progressLeft) / 10;

              if (isResCreated(res)) {
                result.result.created += res.created;
                result.result.ignored += res.ignored;
              }

              subscriber.next({ ...result });
              parser.resume();
            })
            .catch((error) => {
              subscriber.error(error);
            });
        } catch (error) {
          subscriber.error(error);
        }
      }


(item) => (item as unknown[]).map((i) => (isText(i) ? i : ''))


(i) => (isText(i) ? i : '')


(prevCount, row) => {
              const rowBytes = row.reduce((prev, item) => {
                return prev + countUTF8Bytes(item) + 1; // add a byte for separator or newline
              }, 0);
              return prevCount + rowBytes;
            }


(prev, item) => {
                return prev + countUTF8Bytes(item) + 1; // add a byte for separator or newline
              }


(record, index) => {
            if (isDefined(record)) {
              records.push(record);
              lastRows.push(rows[index]);
            }
          }


(res) => {
              // inputs hand-picked so that correctly estimated total is about 75% of the bar
              const progressPower = 2.5 * ((processed += rows.length) / estimated);
              const progressLeft = 0.5 ** progressPower;

              // convert to .1 percent precision for smoother bar display
              result.progress = Math.floor(1000 - 1000 * progressLeft) / 10;

              if (isResCreated(res)) {
                result.result.created += res.created;
                result.result.ignored += res.ignored;
              }

              subscriber.next({ ...result });
              parser.resume();
            }


(error) => {
              subscriber.error(error);
            }


(item: string) => {
  // re-encode into UTF-8
  const escaped = encodeURIComponent(item);
  // convert byte escape sequences into single character
  const normalized = escaped.replace(/%\d\d/g, '_');
  return normalized.length;
}


(res: unknown): res is IResCreated =>
  isObject(res) && isNumber(res.created) && isNumber(res.ignored)


interface IState {
  stage: number;
  fig: IFig<IParseFileState>;
}


interface IParseFileState {
  progress: number;
  result: IResCreated;
  lastRows: string[][];
}


isDefined(error)


created <strong>{result.created}


complete() {
        subscriber.next({ ...result, progress: 100 });
        subscriber.complete();
      }


function deleteSocketFile(socketPath) {
  if (process.platform === 'win32') {
    return;
  }

  if (fs.existsSync(socketPath)) {
    try {
      fs.unlinkSync(socketPath);
    } catch (error) {
      // Ignore ENOENT errors in case the file was deleted between the exists
      // check and the call to unlink sync. This occurred occasionally on CI
      // which is why this check is here.
      if (error.code !== 'ENOENT') {
        throw error;
      }
    }
  }
}


/**
 * Creates server to listen for additional atom application launches.
 *
 * You can run the command multiple times, but after the first launch
 * the other launches will just pass their information to this server and then
 * close immediately.
 */
function listenForArgumentsFromNewProcess(socketPath, callback) {
  deleteSocketFile(socketPath);

  const server = net.createServer(connection => {
    connection.on('data', data => {
      const args = JSON.parse(data.toString());
      callback(args);
    });
  });
  server.listen(socketPath);
  server.on('error', error => console.error('Application server failed', error));
  return server;
}


function tryStart(socketPath, callback, otherAppFound) {
  // FIXME: Sometimes when socketPath doesn't exist, net.connect would strangely
  // take a few seconds to trigger 'error' event, it could be a bug of node
  // or atom-shell, before it's fixed we check the existence of socketPath to
  // speedup startup.
  if (process.platform !== 'win32' && !fs.existsSync(socketPath)) {
    callback();
    return;
  }

  const client = net.connect({ path: socketPath }, () => {
    client.write(JSON.stringify(process.argv.slice(1)), () => {
      client.end();
      otherAppFound();
    });
  });
  client.on('error', callback);
}


function makeSocketPath() {
  let name = electron.app.name ? electron.app.name : electron.app.getName();
  if (buildinfo.releaseChannel !== 'stable') {
    name += buildinfo.releaseChannel;
  }

  if (process.platform === 'win32') {
    return '\\\\.\\pipe\\' + name + '-sock';
  } else {
    return path.join(os.tmpdir(), name + '.sock');
  }
}


export function create(startCallback, newProcessCallback) {
  const socketPath = makeSocketPath();

  tryStart(socketPath, () => {
    const server = listenForArgumentsFromNewProcess(socketPath, newProcessCallback);

    electron.app.on('will-quit', () => {
      server.close();
      deleteSocketFile(socketPath);
    });

    //@ts-ignore
    electron.app.on('will-exit', () => {
      server.close();
      deleteSocketFile(socketPath);
    });

    startCallback();
  }, () => {
    console.log('Another instance exists. Quitting.');
    electron.app.exit(0);
  });
}


export function pipeCommandLineArgs(noOtherAppFoundCallback, otherAppFound) {
  tryStart(makeSocketPath(), noOtherAppFoundCallback, otherAppFound);
}


connection => {
    connection.on('data', data => {
      const args = JSON.parse(data.toString());
      callback(args);
    });
  }


data => {
      const args = JSON.parse(data.toString());
      callback(args);
    }


error => console.error('Application server failed', error)


() => {
    client.write(JSON.stringify(process.argv.slice(1)), () => {
      client.end();
      otherAppFound();
    });
  }


() => {
      client.end();
      otherAppFound();
    }


() => {
    const server = listenForArgumentsFromNewProcess(socketPath, newProcessCallback);

    electron.app.on('will-quit', () => {
      server.close();
      deleteSocketFile(socketPath);
    });

    //@ts-ignore
    electron.app.on('will-exit', () => {
      server.close();
      deleteSocketFile(socketPath);
    });

    startCallback();
  }


() => {
      server.close();
      deleteSocketFile(socketPath);
    }


() => {
    console.log('Another instance exists. Quitting.');
    electron.app.exit(0);
  }


() => {
    domApi = mockDomApi();
    patch = createRendererPatch(<any>plt, domApi);
  }


() => {

    it('should get text from deep nested default slot', () => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="1">
          <cmp-b data-ssrc="1.0" data-ssrv="4">
            <cmp-c data-ssrc="4.0">
              <cmp-d data-ssrc="4.0.">
                <!--s.1.0-->News<!--/-->
              </cmp-d>
            </cmp-c>
          </cmp-b>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[0].vchildren).toHaveLength(1);
    });

    it('should create a vnode from complex html', () => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="1">
          <cmp-b data-ssrc="1.0" data-ssrv="2">
            <!--s.2.0-->TEXT 1<!--/-->
            <cmp-c data-ssrc="2.1." data-ssrv="4">
              <!--s.1.0-->TEXT 2<!--/-->
              <!--s.1.1-->TEXT 3<!--/-->
              <!--s.4.0-->TEXT 7<!--/-->
              <cmp-d data-ssrc="1.2." data-ssrv="3">
                <cmp-f data-ssrc="3.0.">
                  <!--s.3.0-->TEXT 6<!--/-->
                </cmp-f>
              </cmp-d>
              <cmp-e data-ssrc="1.3." data-ssrv="5">
                <!--s.1.0-->TEXT 5<!--/-->
              </cmp-e>
              <!--s.1.4-->TEXT 4<!--/-->
            </cmp-c>
          </cmp-b>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[0].vchildren[0].vtext).toBe('TEXT 2');
      expect(cmpA.vchildren[0].vchildren[1].vtext).toBe('TEXT 3');
      expect(cmpA.vchildren[0].vchildren[2].vtag).toBe('cmp-d');
      expect(cmpA.vchildren[0].vchildren[3].vtag).toBe('cmp-e');
      expect(cmpA.vchildren[0].vchildren[3].vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vchildren[3].vchildren[0].vtext).toBe('TEXT 5');
      expect(cmpA.vchildren[0].vchildren[4].vtext).toBe('TEXT 4');
      expect(cmpA.vchildren[0].vchildren).toHaveLength(5);

      const cmpB = plt.vnodeMap.get(rootElm.querySelector('cmp-b'));
      expect(cmpB.vchildren).toHaveLength(2);
      expect(cmpB.vchildren[0].vtext).toBe('TEXT 1');
      expect(cmpB.vchildren[1].vtag).toBe('cmp-c');

      const cmpC = plt.vnodeMap.get(rootElm.querySelector('cmp-c'));
      expect(cmpC.vchildren).toHaveLength(1);
      expect(cmpC.vchildren[0].vtext).toBe('TEXT 7');

      const cmpD = plt.vnodeMap.get(rootElm.querySelector('cmp-d'));
      expect(cmpD.vchildren).toHaveLength(1);
      expect(cmpD.vchildren[0].vtag).toBe('cmp-f');
      expect(cmpD.vchildren[0].vchildren[0].vtext).toBe('TEXT 6');

      const cmpE = plt.vnodeMap.get(rootElm.querySelector('cmp-e'));
      expect(cmpE.vchildren).toBeUndefined();
    });

    it('should create a vnode from nested default slots html', () => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="0">
          <cmp-b data-ssrv="1" data-ssrc="0.0">
            <!--s.1.0-->
            88
          </cmp-b>
          <cmp-c data-ssrv="2" data-ssrc="0.1">
            <!--s.2.0-->
            mph
          </cmp-c>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(2);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[1].vtag).toBe('cmp-c');

      const cmpB = plt.vnodeMap.get(rootElm.querySelector('cmp-b'));
      expect(cmpB.vchildren).toHaveLength(1);
      expect(cmpB.vchildren[0].vtext).toBe('88');

      const cmpC = plt.vnodeMap.get(rootElm.querySelector('cmp-c'));
      expect(cmpC.vchildren).toHaveLength(1);
      expect(cmpC.vchildren[0].vtext).toBe('mph');
    });

  }


() => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="1">
          <cmp-b data-ssrc="1.0" data-ssrv="4">
            <cmp-c data-ssrc="4.0">
              <cmp-d data-ssrc="4.0.">
                <!--s.1.0-->News<!--/-->
              </cmp-d>
            </cmp-c>
          </cmp-b>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[0].vchildren).toHaveLength(1);
    }


() => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="1">
          <cmp-b data-ssrc="1.0" data-ssrv="2">
            <!--s.2.0-->TEXT 1<!--/-->
            <cmp-c data-ssrc="2.1." data-ssrv="4">
              <!--s.1.0-->TEXT 2<!--/-->
              <!--s.1.1-->TEXT 3<!--/-->
              <!--s.4.0-->TEXT 7<!--/-->
              <cmp-d data-ssrc="1.2." data-ssrv="3">
                <cmp-f data-ssrc="3.0.">
                  <!--s.3.0-->TEXT 6<!--/-->
                </cmp-f>
              </cmp-d>
              <cmp-e data-ssrc="1.3." data-ssrv="5">
                <!--s.1.0-->TEXT 5<!--/-->
              </cmp-e>
              <!--s.1.4-->TEXT 4<!--/-->
            </cmp-c>
          </cmp-b>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[0].vchildren[0].vtext).toBe('TEXT 2');
      expect(cmpA.vchildren[0].vchildren[1].vtext).toBe('TEXT 3');
      expect(cmpA.vchildren[0].vchildren[2].vtag).toBe('cmp-d');
      expect(cmpA.vchildren[0].vchildren[3].vtag).toBe('cmp-e');
      expect(cmpA.vchildren[0].vchildren[3].vchildren).toHaveLength(1);
      expect(cmpA.vchildren[0].vchildren[3].vchildren[0].vtext).toBe('TEXT 5');
      expect(cmpA.vchildren[0].vchildren[4].vtext).toBe('TEXT 4');
      expect(cmpA.vchildren[0].vchildren).toHaveLength(5);

      const cmpB = plt.vnodeMap.get(rootElm.querySelector('cmp-b'));
      expect(cmpB.vchildren).toHaveLength(2);
      expect(cmpB.vchildren[0].vtext).toBe('TEXT 1');
      expect(cmpB.vchildren[1].vtag).toBe('cmp-c');

      const cmpC = plt.vnodeMap.get(rootElm.querySelector('cmp-c'));
      expect(cmpC.vchildren).toHaveLength(1);
      expect(cmpC.vchildren[0].vtext).toBe('TEXT 7');

      const cmpD = plt.vnodeMap.get(rootElm.querySelector('cmp-d'));
      expect(cmpD.vchildren).toHaveLength(1);
      expect(cmpD.vchildren[0].vtag).toBe('cmp-f');
      expect(cmpD.vchildren[0].vchildren[0].vtext).toBe('TEXT 6');

      const cmpE = plt.vnodeMap.get(rootElm.querySelector('cmp-e'));
      expect(cmpE.vchildren).toBeUndefined();
    }


() => {
      const rootElm = domApi.$createElement('div');
      rootElm.innerHTML = `
        <cmp-a data-ssrv="0">
          <cmp-b data-ssrv="1" data-ssrc="0.0">
            <!--s.1.0-->
            88
          </cmp-b>
          <cmp-c data-ssrv="2" data-ssrc="0.1">
            <!--s.2.0-->
            mph
          </cmp-c>
        </cmp-a>
      `;
      removeWhitespaceFromNodes(rootElm);

      createVNodesFromSsr(plt, domApi, rootElm);

      const cmpA = plt.vnodeMap.get(rootElm.querySelector('cmp-a'));
      expect(cmpA.vchildren).toHaveLength(2);
      expect(cmpA.vchildren[0].vtag).toBe('cmp-b');
      expect(cmpA.vchildren[1].vtag).toBe('cmp-c');

      const cmpB = plt.vnodeMap.get(rootElm.querySelector('cmp-b'));
      expect(cmpB.vchildren).toHaveLength(1);
      expect(cmpB.vchildren[0].vtext).toBe('88');

      const cmpC = plt.vnodeMap.get(rootElm.querySelector('cmp-c'));
      expect(cmpC.vchildren).toHaveLength(1);
      expect(cmpC.vchildren[0].vtext).toBe('mph');
    }


() => {
    var oldVnode: d.VNode;
    var newVnode: d.VNode;
    var ssrVNode: d.VNode;
    var hostElm: d.RenderNode;

    beforeEach(() => {
      oldVnode = {};
      hostElm = domApi.$createElement('ion-test');
      oldVnode.elm = hostElm;
    });

    it('should add default slot comments', () => {
      newVnode = h('ion-test', null,
        h('div', null,
          h('slot', null)
        )
      );

      initHostSnapshot(domApi, {}, hostElm as d.HostElement);

      const defaultContentNode = domApi.$createElement('child-a');
      hostElm.appendChild(defaultContentNode);

      ssrVNode = patch(hostElm, oldVnode, newVnode, false, 'none', 1);
      hostElm = removeWhitespaceFromNodes(ssrVNode.elm);

      expect(hostElm.getAttribute(SSR_VNODE_ID)).toBe('1');
      expect(hostElm.firstElementChild.getAttribute(SSR_CHILD_ID)).toBe('1.0.');
      expect(hostElm.firstElementChild.innerHTML).toBe('<child-a></child-a>');
    });

    it('should add same ssr to all elements', () => {
      newVnode = h('ion-test', null,
        h('div', null,
          h('button', null, 'Text 1'),
          h('span', null, 'Text 2')
        )
      );

      ssrVNode = patch(hostElm, oldVnode, newVnode, false, 'none', 1);
      hostElm = <any>ssrVNode.elm;

      expect(hostElm.getAttribute(SSR_VNODE_ID)).toBe('1');
      expect(hostElm.querySelector('div').getAttribute(SSR_CHILD_ID)).toBe('1.0');
      expect(hostElm.querySelector('button').getAttribute(SSR_CHILD_ID)).toBe('1.0');
      expect(hostElm.querySelector('button').innerHTML).toBe('<!--s.1.0-->Text 1<!--/--> ');
      expect(hostElm.querySelector('span').getAttribute(SSR_CHILD_ID)).toBe('1.1');
      expect(hostElm.querySelector('span').innerHTML).toBe('<!--s.1.0-->Text 2<!--/--> ');
    });

  }


() => {
      oldVnode = {};
      hostElm = domApi.$createElement('ion-test');
      oldVnode.elm = hostElm;
    }


() => {
      newVnode = h('ion-test', null,
        h('div', null,
          h('slot', null)
        )
      );

      initHostSnapshot(domApi, {}, hostElm as d.HostElement);

      const defaultContentNode = domApi.$createElement('child-a');
      hostElm.appendChild(defaultContentNode);

      ssrVNode = patch(hostElm, oldVnode, newVnode, false, 'none', 1);
      hostElm = removeWhitespaceFromNodes(ssrVNode.elm);

      expect(hostElm.getAttribute(SSR_VNODE_ID)).toBe('1');
      expect(hostElm.firstElementChild.getAttribute(SSR_CHILD_ID)).toBe('1.0.');
      expect(hostElm.firstElementChild.innerHTML).toBe('<child-a></child-a>');
    }


() => {
      newVnode = h('ion-test', null,
        h('div', null,
          h('button', null, 'Text 1'),
          h('span', null, 'Text 2')
        )
      );

      ssrVNode = patch(hostElm, oldVnode, newVnode, false, 'none', 1);
      hostElm = <any>ssrVNode.elm;

      expect(hostElm.getAttribute(SSR_VNODE_ID)).toBe('1');
      expect(hostElm.querySelector('div').getAttribute(SSR_CHILD_ID)).toBe('1.0');
      expect(hostElm.querySelector('button').getAttribute(SSR_CHILD_ID)).toBe('1.0');
      expect(hostElm.querySelector('button').innerHTML).toBe('<!--s.1.0-->Text 1<!--/--> ');
      expect(hostElm.querySelector('span').getAttribute(SSR_CHILD_ID)).toBe('1.1');
      expect(hostElm.querySelector('span').innerHTML).toBe('<!--s.1.0-->Text 2<!--/--> ');
    }


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  constructor(private loginService: LoginService, private authService: AuthenticationService) {}

  ngOnInit() {
    if (this.authService.isLoggedIn()) {
      this.loginService.redirectAfterLogin();
    }
  }

  handleLogin(): void {
    this.loginService.redirectToAuth();
  }
}


ngOnInit() {
    if (this.authService.isLoggedIn()) {
      this.loginService.redirectAfterLogin();
    }
  }


handleLogin(): void {
    this.loginService.redirectToAuth();
  }


export function httpMock({ success, randomFailure }: Options) {
  return new Promise<void>((resolve, reject) => {
    // resolves randomly between 500ms to 2000ms
    setTimeout(() => {
      if ((randomFailure && Math.random() < 0.9) || success) {
        resolve()
      } else {
        reject({ message: "Failed" })
      }
    }, getRandomInt(5, 20) * 100)
  })
}


(resolve, reject) => {
    // resolves randomly between 500ms to 2000ms
    setTimeout(() => {
      if ((randomFailure && Math.random() < 0.9) || success) {
        resolve()
      } else {
        reject({ message: "Failed" })
      }
    }, getRandomInt(5, 20) * 100)
  }


() => {
      if ((randomFailure && Math.random() < 0.9) || success) {
        resolve()
      } else {
        reject({ message: "Failed" })
      }
    }


interface Options {
  success?: boolean
  randomFailure?: boolean
}


(m) => {
      this.message = m;
    }


export class SuccessHandler extends EventDispatcher<{ message: string }> {
  message: { message: string };

  constructor() {
    super();

    this.message = null;

    this.subscribe("_internal", (m) => {
      this.message = m;
    });
  }
}


@Injectable({
  providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
  canDeactivate(component: CanComponentDeactivate) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}


export interface CanComponentDeactivate {
  canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}


canDeactivate(component: CanComponentDeactivate) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }


type SvgrComponent = React.StatelessComponent<React.SVGAttributes<SVGElement>>


user => user.pets


@Entity()
export class Pet {

    @PrimaryColumn('uuid')
    public id: string;

    @IsNotEmpty()
    @Column()
    public name: string;

    @IsNotEmpty()
    @Column()
    public age: number;

    @Column({
        name: 'user_id',
        nullable: true,
    })
    public userId: string;

    @ManyToOne(type => User, user => user.pets)
    @JoinColumn({ name: 'user_id' })
    public user: User;

    public toString(): string {
        return `${this.name}`;
    }

}


public toString(): string {
        return `${this.name}`;
    }


@Controller('notes')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('list')
  getlist() {
    return this.appService.getlist();
  }

  @Delete('del/:id')
  delete(@Param('id') id1: number) {
    const data = this.appService.delete(id1);
    return data;
  }

  @Post('create')
  createdb(@Body() insert) {
    return this.appService.createdb1(insert);
  }

  @Post('update/:id')
  updateExpression(@Param('id') id1: number, @Body() update) {
    return this.appService.updateExpression1(update, id1);
  }
}


@Get('list')
  getlist() {
    return this.appService.getlist();
  }


@Delete('del/:id')
  delete(@Param('id') id1: number) {
    const data = this.appService.delete(id1);
    return data;
  }


@Post('create')
  createdb(@Body() insert) {
    return this.appService.createdb1(insert);
  }


@Post('update/:id')
  updateExpression(@Param('id') id1: number, @Body() update) {
    return this.appService.updateExpression1(update, id1);
  }


(resolve, reject) => {
            // Get the Cake configuration.
            var config = vscode.workspace.getConfiguration('cake');
            if (!config) {
                reject('Could not resolve bootstrapper configuration.');
                return;
            }

            // Get the bootstrapper URI from the configuration.
            var uri = config['bootstrappers'][this._info.id];
            if (!uri) {
                reject(
                    'Could not resolve bootstrapper URI from configuration.'
                );
                return;
            }

            // Download the bootstrapper.
            request
                .get(uri, { timeout: 4000 })
                .on('response', function(response: any) {
                    if (response.statusCode === 200) {
                        resolve(true);
                    } else {
                        reject(
                            `Failed to download bootstrapper: ${
                                response.statusMessage
                            }`
                        );
                    }
                })
                .on('error', function(e: any) {
                    reject(`Failed to download bootstrapper: ${e}`);
                })
                .pipe(stream);
        }


export class CakeBootstrapper {
    private _info: CakeBootstrapperInfo;

    private static bootstrappers = [
        new CakeBootstrapperInfo(
            'powershell',
            'PowerShell',
            'Bootstrapper for Windows',
            'build.ps1',
            false
        ),
        new CakeBootstrapperInfo(
            'bash',
            'Bash',
            'Bootstrapper for Linux and OSX',
            'build.sh',
            true
        )
    ];

    constructor(info: CakeBootstrapperInfo) {
        this._info = info;
    }

    public getTargetPath(): string {
        if (vscode.workspace.rootPath) {
            return path.join(vscode.workspace.rootPath, this._info.fileName);
        }

        return '';
    }

    public static getBootstrappers(): CakeBootstrapperInfo[] {
        return CakeBootstrapper.bootstrappers;
    }

    public download(stream: NodeJS.WritableStream): Thenable<boolean> {
        return new Promise((resolve, reject) => {
            // Get the Cake configuration.
            var config = vscode.workspace.getConfiguration('cake');
            if (!config) {
                reject('Could not resolve bootstrapper configuration.');
                return;
            }

            // Get the bootstrapper URI from the configuration.
            var uri = config['bootstrappers'][this._info.id];
            if (!uri) {
                reject(
                    'Could not resolve bootstrapper URI from configuration.'
                );
                return;
            }

            // Download the bootstrapper.
            request
                .get(uri, { timeout: 4000 })
                .on('response', function(response: any) {
                    if (response.statusCode === 200) {
                        resolve(true);
                    } else {
                        reject(
                            `Failed to download bootstrapper: ${
                                response.statusMessage
                            }`
                        );
                    }
                })
                .on('error', function(e: any) {
                    reject(`Failed to download bootstrapper: ${e}`);
                })
                .pipe(stream);
        });
    }
}


public getTargetPath(): string {
        if (vscode.workspace.rootPath) {
            return path.join(vscode.workspace.rootPath, this._info.fileName);
        }

        return '';
    }


public static getBootstrappers(): CakeBootstrapperInfo[] {
        return CakeBootstrapper.bootstrappers;
    }


public download(stream: NodeJS.WritableStream): Thenable<boolean> {
        return new Promise((resolve, reject) => {
            // Get the Cake configuration.
            var config = vscode.workspace.getConfiguration('cake');
            if (!config) {
                reject('Could not resolve bootstrapper configuration.');
                return;
            }

            // Get the bootstrapper URI from the configuration.
            var uri = config['bootstrappers'][this._info.id];
            if (!uri) {
                reject(
                    'Could not resolve bootstrapper URI from configuration.'
                );
                return;
            }

            // Download the bootstrapper.
            request
                .get(uri, { timeout: 4000 })
                .on('response', function(response: any) {
                    if (response.statusCode === 200) {
                        resolve(true);
                    } else {
                        reject(
                            `Failed to download bootstrapper: ${
                                response.statusMessage
                            }`
                        );
                    }
                })
                .on('error', function(e: any) {
                    reject(`Failed to download bootstrapper: ${e}`);
                })
                .pipe(stream);
        });
    }


export type SubredditModerators = RelationList<Moderator>;


() => {
  beforeEach(() => TestBed.configureTestingModule({}));

  it('should be created', () => {
    const service: ActivitiesService = TestBed.get(ActivitiesService);
    expect(service).toBeTruthy();
  });
}


() => {
    const service: ActivitiesService = TestBed.get(ActivitiesService);
    expect(service).toBeTruthy();
  }


export function add(map: ol.Map) {

    Measurement.create({
        map: map,
        draw: Draw.create({ map: map, geometryType: "MultiLineString", position: "bottom right-1", label: "📏", title: "Measure"  }),
        edit: Modify.create({ map: map, position: "bottom right-3", label: "✍", title: "Modify" }),
        uom: ["mi", "ft", "in"]
    });

}


@Component({
  selector: 'ngx-profesionales',
  template: `
  <router-outlet></router-outlet>
`,
})
export class ProfesionalesComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}


(i) => i.productId


(p) => {
      product2Price[p.id] = p.price;
    }


(item) => {
      return { ...item, price: product2Price[item.productId.toString()] };
    }


@Injectable()
export class OrdersService {
  constructor(
    @InjectModel(Order.name) private orderModel: Model<OrderDocument>,
    @InjectModel(Product.name) private productModel: Model<ProductDocument>,
  ) {}

  async create(createOrderDto: CreateOrderDto) {
    const { items } = createOrderDto;
    const pids = items.map((i) => i.productId);
    const products = await this.productModel.find({ _id: { $in: pids } });
    if (products.length != new Set(pids).size) {
      throw new BadRequestException('Invalid productId exists in order');
    }

    const product2Price = {};
    products.forEach((p) => {
      product2Price[p.id] = p.price;
    });
    const pricedItems = items.map((item) => {
      return { ...item, price: product2Price[item.productId.toString()] };
    });
    const createdOrder = new this.orderModel({
      items: pricedItems,
      status: 'success',
    });
    return createdOrder.save();
  }

  async findOne(id: mongoose.ObjectId) {
    const o = await this.orderModel.findById(id);
    if (o == null) throw new NotFoundException('Not valid order id');
    return o;
  }
}


async create(createOrderDto: CreateOrderDto) {
    const { items } = createOrderDto;
    const pids = items.map((i) => i.productId);
    const products = await this.productModel.find({ _id: { $in: pids } });
    if (products.length != new Set(pids).size) {
      throw new BadRequestException('Invalid productId exists in order');
    }

    const product2Price = {};
    products.forEach((p) => {
      product2Price[p.id] = p.price;
    });
    const pricedItems = items.map((item) => {
      return { ...item, price: product2Price[item.productId.toString()] };
    });
    const createdOrder = new this.orderModel({
      items: pricedItems,
      status: 'success',
    });
    return createdOrder.save();
  }


async findOne(id: mongoose.ObjectId) {
    const o = await this.orderModel.findById(id);
    if (o == null) throw new NotFoundException('Not valid order id');
    return o;
  }


({ isDisabled, ...props }) => (
  <button {...props} />
)


({ isDisabled }) => (isDisabled ? 'none' : 'initial')


({ isDisabled, ...props }) => <li {...props} />


({ isDisabled }) => (isDisabled ? 'not-allowed' : 'pointer')


(
  { state }: { state?: OrderStateEnum } = {},
  formatMessage: FormatMessage
) => [
  {
    link: '',
    title: formatMessage(ordersMessages.orderDetails)
  },
  {
    link: '/approval',
    title: formatMessage(ordersMessages.menuApproval)
  },
  {
    link: '/provision',
    title: formatMessage(ordersMessages.menuProvision)
  },
  {
    link: '/lifecycle',
    title: formatMessage(ordersMessages.menuLifecycle),
    isDisabled: stateToDisplay(state)
  }
]