<commit_before>import * as nls from "vscode-nls";
import * as path from "path";
import * as util from "util";
import * as dedent from "dedent";
import { BoardConstructor, Board, BoardCandidate, BoardInformation } from "../boards/board";
import { CacheStorage } from "../util/cacheStorage";
import {
    CancellationToken, Disposable,
    EventEmitter, ExtensionContext,
    MessageItem, ProviderResult, QuickPickItem,
    StatusBarAlignment, StatusBarItem,
    TextDocumentContentProvider, Uri, ViewColumn,
    commands, window, workspace
} from "vscode";
import { CatalogData, toLocalizedString } from "./catalogData";
import { FSWatcher, readFileSync, watch } from "fs";
import { SketchLoadResult } from "../sketch";
import * as MarkdownIt from "markdown-it";
import { GitHubRepository } from "../util/githubFetcher";
import { RubicProcess, RubicMessageItem } from "../processes/rubicProcess";
import { Runtime } from "../runtimes/runtime";
require("promise.prototype.finally").shim();

const Handlebars = require("./handlebars");
require("./template");

const localize = nls.loadMessageBundle(__filename);

export const CMD_SHOW_CATALOG = "extension.rubic.showCatalog";
export const CMD_SELECT_PORT  = "extension.rubic.selectPort";

const URI_CATALOG = Uri.parse("rubic://catalog");
const CMD_UPDATE_CATALOG = "extension.rubic.updateCatalog";
const CMD_TEST_CONNECTION  = "extension.rubic.testConnection";
const CMD_WRITE_FIRMWARE  = "extension.rubic.writeFirmware";

const CFG_SHOW_PREVIEW = "catalog.showPreview";

interface CatalogSelection {
    boardClass: string;
    repositoryUuid: string;
    releaseTag: string;
    variationPath: string;
}

function makeGithubURL(owner: string, repo: string, branch?: string): string {
    let suffix = branch ? `/tree/${branch}` : "";
    return `https://github.com/${owner}/${repo}${suffix}`;
}

export class CatalogViewer implements TextDocumentContentProvider, Disposable {
    private _currentSelection: CatalogSelection;
    private _currentPanel: "board" | "repository" | "release" | "variation" | "details";
    private _pendingSave: boolean;
    private _pendingCache: boolean;
    private _onDidChange = new EventEmitter<Uri>();
    get onDidChange() { return this._onDidChange.event; }

    /**
     * Constructor of CatalogViewer
     */
    public constructor(context: ExtensionContext) {
        // Register commands
        if (RubicProcess.self.workspaceRoot == null) {
            context.subscriptions.push(
                commands.registerCommand(CMD_SHOW_CATALOG, () => {
                    return RubicProcess.self.showInformationMessage(localize(
                        "open-folder-before",
                        "Open a folder to place your files before opening Rubic board catalog"
                    ));
                })
            );
            return;
        }
        context.subscriptions.push(
            commands.registerCommand(CMD_SHOW_CATALOG, (params) => {
                if (params) {
                    this._updateCatalogView(params);
                } else {
                    this._showCatalogView();
                }
            }),
            commands.registerCommand(CMD_UPDATE_CATALOG, () => {
                this._fetchCatalog();
            }),
            commands.registerCommand(CMD_SELECT_PORT, () => {
                this.selectPort();
            }),
            commands.registerCommand(CMD_TEST_CONNECTION, () => {
                this._testConnection();
            }),
            commands.registerCommand(CMD_WRITE_FIRMWARE, () => {
                this._writeFirmware();
            })
        );

        // Register scheme
        context.subscriptions.push(
            workspace.registerTextDocumentContentProvider("rubic", this)
        );

        RubicProcess.self.catalogData.fetch()
        .catch((reason) => {
            RubicProcess.self.showErrorMessage(
                localize("failed-load-catalog-x", "Failed to load catalog: {0}", reason)
            );
        });

        let { sketch } = RubicProcess.self;
        sketch.on("load", () => {
            this._currentSelection = {
                boardClass: sketch.boardClass,
                repositoryUuid: sketch.repositoryUuid,
                releaseTag: sketch.releaseTag,<commit_msg>Fix errors with empty sketch<commit_after>import * as nls from "vscode-nls";
import * as path from "path";
import * as util from "util";
import * as dedent from "dedent";
import { BoardConstructor, Board, BoardCandidate, BoardInformation } from "../boards/board";
import { CacheStorage } from "../util/cacheStorage";
import {
    CancellationToken, Disposable,
    EventEmitter, ExtensionContext,
    MessageItem, ProviderResult, QuickPickItem,
    StatusBarAlignment, StatusBarItem,
    TextDocumentContentProvider, Uri, ViewColumn,
    commands, window, workspace
} from "vscode";
import { CatalogData, toLocalizedString } from "./catalogData";
import { FSWatcher, readFileSync, watch } from "fs";
import { SketchLoadResult } from "../sketch";
import * as MarkdownIt from "markdown-it";
import { GitHubRepository } from "../util/githubFetcher";
import { RubicProcess, RubicMessageItem } from "../processes/rubicProcess";
import { Runtime } from "../runtimes/runtime";
require("promise.prototype.finally").shim();

const Handlebars = require("./handlebars");
require("./template");

const localize = nls.loadMessageBundle(__filename);

export const CMD_SHOW_CATALOG = "extension.rubic.showCatalog";
export const CMD_SELECT_PORT  = "extension.rubic.selectPort";

const URI_CATALOG = Uri.parse("rubic://catalog");
const CMD_UPDATE_CATALOG = "extension.rubic.updateCatalog";
const CMD_TEST_CONNECTION  = "extension.rubic.testConnection";
const CMD_WRITE_FIRMWARE  = "extension.rubic.writeFirmware";

const CFG_SHOW_PREVIEW = "catalog.showPreview";

interface CatalogSelection {
    boardClass: string;
    repositoryUuid: string;
    releaseTag: string;
    variationPath: string;
}

function makeGithubURL(owner: string, repo: string, branch?: string): string {
    let suffix = branch ? `/tree/${branch}` : "";
    return `https://github.com/${owner}/${repo}${suffix}`;
}

export class CatalogViewer implements TextDocumentContentProvider, Disposable {
    private _currentSelection: CatalogSelection;
    private _currentPanel: "board" | "repository" | "release" | "variation" | "details";
    private _pendingSave: boolean;
    private _pendingCache: boolean;
    private _onDidChange = new EventEmitter<Uri>();
    get onDidChange() { return this._onDidChange.event; }

    /**
     * Constructor of CatalogViewer
     */
    public constructor(context: ExtensionContext) {
        // Register commands
        if (RubicProcess.self.workspaceRoot == null) {
            context.subscriptions.push(
                commands.registerCommand(CMD_SHOW_CATALOG, () => {
                    return RubicProcess.self.showInformationMessage(localize(
                        "open-folder-before",
                        "Open a folder to place your files before opening Rubic board catalog"
                    ));
                })
            );
            return;
        }
        context.subscriptions.push(
            commands.registerCommand(CMD_SHOW_CATALOG, (params) => {
                if (params) {
                    this._updateCatalogView(params);
                } else {
                    this._showCatalogView();
                }
            }),
            commands.registerCommand(CMD_UPDATE_CATALOG, () => {
                this._fetchCatalog();
            }),
            commands.registerCommand(CMD_SELECT_PORT, () => {
                this.selectPort();
            }),
            commands.registerCommand(CMD_TEST_CONNECTION, () => {
                this._testConnection();
            }),
            commands.registerCommand(CMD_WRITE_FIRMWARE, () => {
                this._writeFirmware();
            })
        );

        // Register scheme
        context.subscriptions.push(
            workspace.registerTextDocumentContentProvider("rubic", this)
        );

        RubicProcess.self.catalogData.fetch()
        .catch((reason) => {
            RubicProcess.self.showErrorMessage(
                localize("failed-load-catalog-x", "Failed to load catalog: {0}", reason)
            );
        });

        let { sketch } = RubicProcess.self;
        this._currentSelection = {
            boardClass: null,
            repositoryUuid: null,
            releaseTag: null,
            variationPath: null
        };
        sketch.on("load", () => {
            this._currentSelection = {
                boardClass: sketch.boardClass,
                repositoryUuid: sketch.repositoryUuid,
                releaseTag: sketch.releaseTag,
{'fraction_non_alphanumeric': 0.11383597581840994, 'fraction_numerical': 0.00022812820805292574, 'mean_word_length': 2.561332250203087, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3194053', 'n_tokens_mistral': 2376, 'n_tokens_neox': 2316, 'n_words': 488}