
import { registerCss } from '../../../../../../../css.js';
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import * as extensionsWidgets from './media/extensionsWidgets.css';
import { semverExports } from '../../../../../../../_virtual/semver.js';
import { Disposable, DisposableStore, MutableDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
import { ExtensionState, ExtensionEditorTab } from '../common/extensions.js';
import { IExtensionsWorkbenchService } from '../common/extensions.service.js';
import { addDisposableListener, EventType, finalHandler, append, $, reset } from '../../../../base/browser/dom.js';
import { language } from '../../../../base/common/platform.js';
import { localize } from '../../../../nls.js';
import { IExtensionManagementServerService } from '../../../services/extensionManagement/common/extensionManagement.service.js';
import { IExtensionRecommendationsService, IExtensionIgnoredRecommendationsService } from '../../../services/extensionRecommendations/common/extensionRecommendations.service.js';
import { ILabelService } from '../../../../platform/label/common/label.service.js';
import { extensionButtonProminentBackground } from './extensionsActions.js';
import { registerThemingParticipant } from '../../../../platform/theme/common/themeService.js';
import { IThemeService } from '../../../../platform/theme/common/themeService.service.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { EXTENSION_BADGE_BACKGROUND, EXTENSION_BADGE_FOREGROUND } from '../../../common/theme.js';
import { Event, Emitter } from '../../../../base/common/event.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { CountBadge } from '../../../../base/browser/ui/countBadge/countBadge.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { IUserDataSyncEnablementService } from '../../../../platform/userDataSync/common/userDataSync.service.js';
import { installCountIcon, starFullIcon, starHalfIcon, starEmptyIcon, sponsorIcon, ratingIcon, preReleaseIcon, remoteIcon, privateExtensionIcon, syncIgnoredIcon, restartRequiredIcon, activationTimeIcon, errorIcon, warningIcon, infoIcon } from './extensionsIcons.js';
import { registerColor } from '../../../../platform/theme/common/colorUtils.js';
import { textLinkForeground } from '../../../../platform/theme/common/colors/baseColors.js';
import '../../../../platform/theme/common/colors/chartsColors.js';
import '../../../../platform/theme/common/colors/editorColors.js';
import '../../../../platform/theme/common/colors/inputColors.js';
import '../../../../platform/theme/common/colors/listColors.js';
import '../../../../platform/theme/common/colors/menuColors.js';
import '../../../../platform/theme/common/colors/minimapColors.js';
import '../../../../platform/theme/common/colors/miscColors.js';
import '../../../../platform/theme/common/colors/quickpickColors.js';
import '../../../../platform/theme/common/colors/searchColors.js';
import { IHoverService } from '../../../../platform/hover/browser/hover.service.js';
import { MarkdownString, createCommandUri } from '../../../../base/common/htmlContent.js';
import { URI } from '../../../../base/common/uri.js';
import { IExtensionService } from '../../../services/extensions/common/extensions.service.js';
import { areSameExtensions } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js';
import Severity$1 from '../../../../base/common/severity.js';
import { Color } from '../../../../base/common/color.js';
import { IOpenerService } from '../../../../platform/opener/common/opener.service.js';
import { renderIcon } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
import { KeyCode } from '../../../../base/common/keyCodes.js';
import { defaultCountBadgeStyles } from '../../../../platform/theme/browser/defaultStyles.js';
import { getDefaultHoverDelegate } from '../../../../base/browser/ui/hover/hoverDelegateFactory.js';
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.service.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { Extensions } from '../../../services/extensionManagement/common/extensionFeatures.js';
import { IExtensionFeaturesManagementService } from '../../../services/extensionManagement/common/extensionFeatures.service.js';
import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
import { extensionDefaultIcon, verifiedPublisherIcon, extensionVerifiedPublisherIconColor } from '../../../services/extensionManagement/common/extensionsIcons.js';
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.service.js';
import { IExplorerService } from '../../files/browser/files.service.js';
import { IViewsService } from '../../../services/views/common/viewsService.service.js';
import { VIEW_ID } from '../../files/common/files.js';
import { IExtensionGalleryManifestService } from '../../../../platform/extensionManagement/common/extensionGalleryManifest.service.js';
import { IMarkdownRendererService } from '../../../../platform/markdown/browser/markdownRenderer.service.js';

var InstallCountWidget_1, ExtensionHoverWidget_1;
registerCss(extensionsWidgets);
class ExtensionWidget extends Disposable {
    constructor() {
        super(...arguments);
        this._extension = null;
    }
    get extension() {
        return this._extension;
    }
    set extension(extension) {
        this._extension = extension;
        this.update();
    }
    update() {
        this.render();
    }
}
function onClick(element, callback) {
    const disposables = ( new DisposableStore());
    disposables.add(addDisposableListener(element, EventType.CLICK, finalHandler(callback)));
    disposables.add(addDisposableListener(element, EventType.KEY_UP, e => {
        const keyboardEvent = ( new StandardKeyboardEvent(e));
        if (keyboardEvent.equals(KeyCode.Space) || keyboardEvent.equals(KeyCode.Enter)) {
            e.preventDefault();
            e.stopPropagation();
            callback();
        }
    }));
    return disposables;
}
class ExtensionIconWidget extends ExtensionWidget {
    constructor(container) {
        super();
        this.iconLoadingDisposable = this._register(( new MutableDisposable()));
        this.iconErrorDisposable = this._register(( new MutableDisposable()));
        this.element = append(container, $(".extension-icon"));
        this.iconElement = append(this.element, $("img.icon", {
            alt: ""
        }));
        this.iconElement.style.display = "none";
        this.defaultIconElement = append(this.element, $(ThemeIcon.asCSSSelector(extensionDefaultIcon)));
        this.defaultIconElement.style.display = "none";
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.iconUrl = undefined;
        this.iconElement.src = "";
        this.iconElement.style.display = "none";
        this.defaultIconElement.style.display = "none";
        this.iconErrorDisposable.clear();
        this.iconLoadingDisposable.clear();
    }
    render() {
        if (!this.extension) {
            this.clear();
            return;
        }
        if (this.extension.iconUrl) {
            if (this.iconUrl !== this.extension.iconUrl) {
                this.iconElement.style.display = "inherit";
                this.defaultIconElement.style.display = "none";
                this.iconUrl = this.extension.iconUrl;
                this.iconErrorDisposable.value = addDisposableListener(this.iconElement, "error", () => {
                    if (this.extension?.iconUrlFallback) {
                        this.iconElement.src = this.extension.iconUrlFallback;
                    } else {
                        this.iconElement.style.display = "none";
                        this.defaultIconElement.style.display = "inherit";
                    }
                }, {
                    once: true
                });
                this.iconElement.src = this.iconUrl;
                if (!this.iconElement.complete) {
                    this.iconElement.style.visibility = "hidden";
                    this.iconLoadingDisposable.value = addDisposableListener(this.iconElement, "load", () => {
                        this.iconElement.style.visibility = "inherit";
                    });
                } else {
                    this.iconElement.style.visibility = "inherit";
                }
            }
        } else {
            this.iconUrl = undefined;
            this.iconElement.style.display = "none";
            this.iconElement.src = "";
            this.defaultIconElement.style.display = "inherit";
            this.iconErrorDisposable.clear();
            this.iconLoadingDisposable.clear();
        }
    }
}
let InstallCountWidget = InstallCountWidget_1 = class InstallCountWidget extends ExtensionWidget {
    constructor(container, small, hoverService) {
        super();
        this.container = container;
        this.small = small;
        this.hoverService = hoverService;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.container.innerText = "";
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (!this.extension) {
            return;
        }
        if (this.small && this.extension.state !== ExtensionState.Uninstalled) {
            return;
        }
        const installLabel = InstallCountWidget_1.getInstallLabel(this.extension, this.small);
        if (!installLabel) {
            return;
        }
        const parent = this.small ? this.container : append(this.container, $("span.install", {
            tabIndex: 0
        }));
        append(parent, $("span" + ThemeIcon.asCSSSelector(installCountIcon)));
        const count = append(parent, $("span.count"));
        count.textContent = installLabel;
        if (!this.small) {
            this.disposables.add(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), this.container, ( localize(9308, "Install count")))
            );
        }
    }
    static getInstallLabel(extension, small) {
        const installCount = extension.installCount;
        if (!installCount) {
            return undefined;
        }
        let installLabel;
        if (small) {
            if (installCount > 1000000) {
                installLabel = `${Math.floor(installCount / 100000) / 10}M`;
            } else if (installCount > 1000) {
                installLabel = `${Math.floor(installCount / 1000)}K`;
            } else {
                installLabel = String(installCount);
            }
        } else {
            installLabel = installCount.toLocaleString(language);
        }
        return installLabel;
    }
};
InstallCountWidget = InstallCountWidget_1 = ( __decorate([( __param(2, IHoverService))], InstallCountWidget));
let RatingsWidget = class RatingsWidget extends ExtensionWidget {
    constructor(container, small, hoverService, openerService) {
        super();
        this.container = container;
        this.small = small;
        this.hoverService = hoverService;
        this.openerService = openerService;
        this.disposables = this._register(( new DisposableStore()));
        container.classList.add("extension-ratings");
        if (this.small) {
            container.classList.add("small");
        }
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.container.innerText = "";
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (!this.extension) {
            return;
        }
        if (this.small && this.extension.state !== ExtensionState.Uninstalled) {
            return;
        }
        if (this.extension.rating === undefined) {
            return;
        }
        if (this.small && !this.extension.ratingCount) {
            return;
        }
        if (!this.extension.url) {
            return;
        }
        const rating = Math.round(this.extension.rating * 2) / 2;
        if (this.small) {
            append(this.container, $("span" + ThemeIcon.asCSSSelector(starFullIcon)));
            const count = append(this.container, $("span.count"));
            count.textContent = String(rating);
        } else {
            const element = append(this.container, $("span.rating.clickable", {
                tabIndex: 0
            }));
            for (let i = 1; i <= 5; i++) {
                if (rating >= i) {
                    append(element, $("span" + ThemeIcon.asCSSSelector(starFullIcon)));
                } else if (rating >= i - 0.5) {
                    append(element, $("span" + ThemeIcon.asCSSSelector(starHalfIcon)));
                } else {
                    append(element, $("span" + ThemeIcon.asCSSSelector(starEmptyIcon)));
                }
            }
            if (this.extension.ratingCount) {
                const ratingCountElemet = append(element, $("span", undefined, ` (${this.extension.ratingCount})`));
                ratingCountElemet.style.paddingLeft = "1px";
            }
            this.containerHover = this._register(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), element, "")
            );
            this.containerHover.update(( localize(9309, "Average rating: {0} out of 5", rating)));
            element.setAttribute("role", "link");
            if (this.extension.ratingUrl) {
                this.disposables.add(onClick(element, () => this.openerService.open(( URI.parse(this.extension.ratingUrl)))));
            }
        }
    }
};
RatingsWidget = ( __decorate([( __param(2, IHoverService)), ( __param(3, IOpenerService))], RatingsWidget));
let PublisherWidget = class PublisherWidget extends ExtensionWidget {
    constructor(container, small, extensionsWorkbenchService, hoverService, openerService) {
        super();
        this.container = container;
        this.small = small;
        this.extensionsWorkbenchService = extensionsWorkbenchService;
        this.hoverService = hoverService;
        this.openerService = openerService;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.element?.remove();
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (!this.extension) {
            return;
        }
        if (this.extension.resourceExtension) {
            return;
        }
        if (this.extension.local?.source === "resource") {
            return;
        }
        this.element = append(this.container, $(".publisher"));
        const publisherDisplayName = $(".publisher-name.ellipsis");
        publisherDisplayName.textContent = this.extension.publisherDisplayName;
        const verifiedPublisher = $(".verified-publisher");
        append(
            verifiedPublisher,
            $("span.extension-verified-publisher.clickable"),
            renderIcon(verifiedPublisherIcon)
        );
        if (this.small) {
            if (this.extension.publisherDomain?.verified) {
                append(this.element, verifiedPublisher);
            }
            append(this.element, publisherDisplayName);
        } else {
            this.element.classList.toggle("clickable", !!this.extension.url);
            this.element.setAttribute("role", "button");
            this.element.tabIndex = 0;
            this.containerHover = this.disposables.add(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), this.element, ( localize(9310, "Publisher ({0})", this.extension.publisherDisplayName)))
            );
            append(this.element, publisherDisplayName);
            if (this.extension.publisherDomain?.verified) {
                append(this.element, verifiedPublisher);
                const publisherDomainLink = ( URI.parse(this.extension.publisherDomain.link));
                verifiedPublisher.tabIndex = 0;
                verifiedPublisher.setAttribute("role", "button");
                this.containerHover.update(( localize(
                    9311,
                    "This publisher has verified ownership of {0}",
                    this.extension.publisherDomain.link
                )));
                verifiedPublisher.setAttribute("role", "link");
                append(verifiedPublisher, $(
                    "span.extension-verified-publisher-domain",
                    undefined,
                    publisherDomainLink.authority.startsWith("www.") ? publisherDomainLink.authority.substring(4) : publisherDomainLink.authority
                ));
                this.disposables.add(
                    onClick(verifiedPublisher, () => this.openerService.open(publisherDomainLink))
                );
            }
            if (this.extension.url) {
                this.disposables.add(onClick(
                    this.element,
                    () => this.extensionsWorkbenchService.openSearch(`publisher:"${this.extension?.publisherDisplayName}"`)
                ));
            }
        }
    }
};
PublisherWidget = ( __decorate([( __param(2, IExtensionsWorkbenchService)), ( __param(3, IHoverService)), ( __param(4, IOpenerService))], PublisherWidget));
let SponsorWidget = class SponsorWidget extends ExtensionWidget {
    constructor(container, hoverService, openerService) {
        super();
        this.container = container;
        this.hoverService = hoverService;
        this.openerService = openerService;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
    }
    render() {
        reset(this.container);
        this.disposables.clear();
        if (!this.extension?.publisherSponsorLink) {
            return;
        }
        const sponsor = append(this.container, $("span.sponsor.clickable", {
            tabIndex: 0
        }));
        this.disposables.add(this.hoverService.setupManagedHover(
            getDefaultHoverDelegate("mouse"),
            sponsor,
            this.extension?.publisherSponsorLink.toString() ?? ""
        ));
        sponsor.setAttribute("role", "link");
        const sponsorIconElement = renderIcon(sponsorIcon);
        const label = $("span", undefined, ( localize(9312, "Sponsor")));
        append(sponsor, sponsorIconElement, label);
        this.disposables.add(onClick(sponsor, () => {
            this.openerService.open(this.extension.publisherSponsorLink);
        }));
    }
};
SponsorWidget = ( __decorate([( __param(1, IHoverService)), ( __param(2, IOpenerService))], SponsorWidget));
let RecommendationWidget = class RecommendationWidget extends ExtensionWidget {
    constructor(parent, extensionRecommendationsService) {
        super();
        this.parent = parent;
        this.extensionRecommendationsService = extensionRecommendationsService;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
        this._register(toDisposable(() => this.clear()));
        this._register(
            this.extensionRecommendationsService.onDidChangeRecommendations(() => this.render())
        );
    }
    clear() {
        this.element?.remove();
        this.element = undefined;
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (!this.extension || this.extension.state === ExtensionState.Installed || this.extension.deprecationInfo) {
            return;
        }
        const extRecommendations = this.extensionRecommendationsService.getAllRecommendationsWithReason();
        if (extRecommendations[this.extension.identifier.id.toLowerCase()]) {
            this.element = append(this.parent, $("div.extension-bookmark"));
            const recommendation = append(this.element, $(".recommendation"));
            append(recommendation, $("span" + ThemeIcon.asCSSSelector(ratingIcon)));
        }
    }
};
RecommendationWidget = ( __decorate([( __param(1, IExtensionRecommendationsService))], RecommendationWidget));
class PreReleaseBookmarkWidget extends ExtensionWidget {
    constructor(parent) {
        super();
        this.parent = parent;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.element?.remove();
        this.element = undefined;
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (this.extension?.state === ExtensionState.Installed ? this.extension.preRelease : this.extension?.hasPreReleaseVersion) {
            this.element = append(this.parent, $("div.extension-bookmark"));
            const preRelease = append(this.element, $(".pre-release"));
            append(preRelease, $("span" + ThemeIcon.asCSSSelector(preReleaseIcon)));
        }
    }
}
let RemoteBadgeWidget = class RemoteBadgeWidget extends ExtensionWidget {
    constructor(parent, tooltip, extensionManagementServerService, instantiationService) {
        super();
        this.tooltip = tooltip;
        this.extensionManagementServerService = extensionManagementServerService;
        this.instantiationService = instantiationService;
        this.remoteBadge = this._register(( new MutableDisposable()));
        this.element = append(parent, $(""));
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.remoteBadge.value?.element.remove();
        this.remoteBadge.clear();
    }
    render() {
        this.clear();
        if (!this.extension || !this.extension.local || !this.extension.server || !(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) || this.extension.server !== this.extensionManagementServerService.remoteExtensionManagementServer) {
            return;
        }
        let tooltip;
        if (this.tooltip && this.extensionManagementServerService.remoteExtensionManagementServer) {
            tooltip = ( localize(
                9313,
                "Extension in {0}",
                this.extensionManagementServerService.remoteExtensionManagementServer.label
            ));
        }
        this.remoteBadge.value = this.instantiationService.createInstance(ExtensionIconBadge, remoteIcon, tooltip);
        append(this.element, this.remoteBadge.value.element);
    }
};
RemoteBadgeWidget = ( __decorate([( __param(2, IExtensionManagementServerService)), ( __param(3, IInstantiationService))], RemoteBadgeWidget));
let ExtensionIconBadge = class ExtensionIconBadge extends Disposable {
    constructor(icon, tooltip, hoverService, labelService, themeService) {
        super();
        this.icon = icon;
        this.tooltip = tooltip;
        this.labelService = labelService;
        this.themeService = themeService;
        this.element = $("div.extension-badge.extension-icon-badge");
        this.elementHover = this._register(
            hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), this.element, "")
        );
        this.render();
    }
    render() {
        append(this.element, $("span" + ThemeIcon.asCSSSelector(this.icon)));
        const applyBadgeStyle = () => {
            if (!this.element) {
                return;
            }
            const bgColor = this.themeService.getColorTheme().getColor(EXTENSION_BADGE_BACKGROUND);
            const fgColor = this.themeService.getColorTheme().getColor(EXTENSION_BADGE_FOREGROUND);
            this.element.style.backgroundColor = bgColor ? ( bgColor.toString()) : "";
            this.element.style.color = fgColor ? ( fgColor.toString()) : "";
        };
        applyBadgeStyle();
        this._register(this.themeService.onDidColorThemeChange(() => applyBadgeStyle()));
        if (this.tooltip) {
            const updateTitle = () => {
                if (this.element) {
                    this.elementHover.update(this.tooltip);
                }
            };
            this._register(this.labelService.onDidChangeFormatters(() => updateTitle()));
            updateTitle();
        }
    }
};
ExtensionIconBadge = ( __decorate([( __param(2, IHoverService)), ( __param(3, ILabelService)), ( __param(4, IThemeService))], ExtensionIconBadge));
class ExtensionPackCountWidget extends ExtensionWidget {
    constructor(parent) {
        super();
        this.parent = parent;
        this.render();
        this._register(toDisposable(() => this.clear()));
    }
    clear() {
        this.element?.remove();
        this.countBadge?.dispose();
        this.countBadge = undefined;
    }
    render() {
        this.clear();
        if (!this.extension || !(this.extension.categories?.some(category => category.toLowerCase() === "extension packs")) || !this.extension.extensionPack.length) {
            return;
        }
        this.element = append(this.parent, $(".extension-badge.extension-pack-badge"));
        this.countBadge = ( new CountBadge(this.element, {}, defaultCountBadgeStyles));
        this.countBadge.setCount(this.extension.extensionPack.length);
    }
}
let ExtensionKindIndicatorWidget = class ExtensionKindIndicatorWidget extends ExtensionWidget {
    constructor(
        container,
        small,
        hoverService,
        contextService,
        uriIdentityService,
        explorerService,
        viewsService,
        extensionGalleryManifestService
    ) {
        super();
        this.container = container;
        this.small = small;
        this.hoverService = hoverService;
        this.contextService = contextService;
        this.uriIdentityService = uriIdentityService;
        this.explorerService = explorerService;
        this.viewsService = viewsService;
        this.extensionGalleryManifest = null;
        this.disposables = this._register(( new DisposableStore()));
        this.render();
        this._register(toDisposable(() => this.clear()));
        extensionGalleryManifestService.getExtensionGalleryManifest().then(manifest => {
            if (this._store.isDisposed) {
                return;
            }
            this.extensionGalleryManifest = manifest;
            this.render();
        });
    }
    clear() {
        this.element?.remove();
        this.disposables.clear();
    }
    render() {
        this.clear();
        if (!this.extension) {
            return;
        }
        if (this.extension?.private) {
            this.element = append(this.container, $(".extension-kind-indicator"));
            if (!this.small || (this.extensionGalleryManifest?.capabilities.extensions?.includePublicExtensions && this.extensionGalleryManifest?.capabilities.extensions?.includePrivateExtensions)) {
                append(this.element, $("span" + ThemeIcon.asCSSSelector(privateExtensionIcon)));
            }
            if (!this.small) {
                append(this.element, $("span.private-extension-label", undefined, ( localize(9314, "Private Extension"))));
            }
            return;
        }
        if (!this.small) {
            return;
        }
        const location = this.extension.resourceExtension?.location ?? (this.extension.local?.source === "resource" ? this.extension.local?.location : undefined);
        if (!location) {
            return;
        }
        this.element = append(this.container, $(".extension-kind-indicator"));
        const workspaceFolder = this.contextService.getWorkspaceFolder(location);
        if (workspaceFolder && this.extension.isWorkspaceScoped) {
            this.element.textContent = ( localize(9315, "Workspace Extension"));
            this.element.classList.add("clickable");
            this.element.setAttribute("role", "button");
            this.disposables.add(this.hoverService.setupManagedHover(
                getDefaultHoverDelegate("mouse"),
                this.element,
                this.uriIdentityService.extUri.relativePath(workspaceFolder.uri, location)
            ));
            this.disposables.add(onClick(this.element, () => {
                this.viewsService.openView(VIEW_ID, true).then(() => this.explorerService.select(location, true));
            }));
        } else {
            this.disposables.add(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), this.element, location.path)
            );
            this.element.textContent = ( localize(9316, "Local Extension"));
        }
    }
};
ExtensionKindIndicatorWidget = ( __decorate([( __param(2, IHoverService)), ( __param(3, IWorkspaceContextService)), ( __param(4, IUriIdentityService)), ( __param(5, IExplorerService)), ( __param(6, IViewsService)), ( __param(7, IExtensionGalleryManifestService))], ExtensionKindIndicatorWidget));
let SyncIgnoredWidget = class SyncIgnoredWidget extends ExtensionWidget {
    constructor(
        container,
        configurationService,
        extensionsWorkbenchService,
        hoverService,
        userDataSyncEnablementService
    ) {
        super();
        this.container = container;
        this.configurationService = configurationService;
        this.extensionsWorkbenchService = extensionsWorkbenchService;
        this.hoverService = hoverService;
        this.userDataSyncEnablementService = userDataSyncEnablementService;
        this.disposables = this._register(( new DisposableStore()));
        this._register(Event.filter(
            this.configurationService.onDidChangeConfiguration,
            e => e.affectsConfiguration("settingsSync.ignoredExtensions")
        )(() => this.render()));
        this._register(userDataSyncEnablementService.onDidChangeEnablement(() => this.update()));
        this.render();
    }
    render() {
        this.disposables.clear();
        this.container.innerText = "";
        if (this.extension && this.extension.state === ExtensionState.Installed && this.userDataSyncEnablementService.isEnabled() && this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension)) {
            const element = append(
                this.container,
                $("span.extension-sync-ignored" + ThemeIcon.asCSSSelector(syncIgnoredIcon))
            );
            this.disposables.add(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), element, ( localize(9317, "This extension is ignored during sync.")))
            );
            element.classList.add(...ThemeIcon.asClassNameArray(syncIgnoredIcon));
        }
    }
};
SyncIgnoredWidget = ( __decorate([( __param(1, IConfigurationService)), ( __param(2, IExtensionsWorkbenchService)), ( __param(3, IHoverService)), ( __param(4, IUserDataSyncEnablementService))], SyncIgnoredWidget));
let ExtensionRestartRequiredWidget = class ExtensionRestartRequiredWidget extends ExtensionWidget {
    constructor(container, hoverService) {
        super();
        this.container = container;
        this.hoverService = hoverService;
        this.disposables = this._register(( new DisposableStore()));
    }
    render() {
        this.disposables.clear();
        this.container.innerText = "";
        const runtimeState = this.extension?.runtimeState;
        const reason = typeof runtimeState?.reason === "string" ? runtimeState.reason : "";
        if (runtimeState && /restart|reload/i.test(reason)) {
            const element = append(this.container, $(
                "span.extension-restart-required" + ThemeIcon.asCSSSelector(restartRequiredIcon)
            ));
            append(
                this.container,
                $("span.extension-restart-required-label", undefined, ( localize(9318, "Restart Required")))
            );
            this.disposables.add(
                this.hoverService.setupManagedHover(getDefaultHoverDelegate("mouse"), element, reason)
            );
        }
    }
};
ExtensionRestartRequiredWidget = ( __decorate([( __param(1, IHoverService))], ExtensionRestartRequiredWidget));
let ExtensionRuntimeStatusWidget = class ExtensionRuntimeStatusWidget extends ExtensionWidget {
    constructor(
        extensionViewState,
        container,
        extensionService,
        extensionFeaturesManagementService,
        extensionsWorkbenchService
    ) {
        super();
        this.extensionViewState = extensionViewState;
        this.container = container;
        this.extensionFeaturesManagementService = extensionFeaturesManagementService;
        this.extensionsWorkbenchService = extensionsWorkbenchService;
        this._register(extensionService.onDidChangeExtensionsStatus(extensions => {
            if (this.extension && ( extensions.some(e => areSameExtensions({
                id: e.value
            }, this.extension.identifier)))) {
                this.update();
            }
        }));
        this._register(extensionFeaturesManagementService.onDidChangeAccessData(e => {
            if (this.extension && ExtensionIdentifier.equals(this.extension.identifier.id, e.extension)) {
                this.update();
            }
        }));
    }
    render() {
        this.container.innerText = "";
        if (!this.extension) {
            return;
        }
        if (this.extensionViewState.filters.featureId && this.extension.state === ExtensionState.Installed) {
            const accessData = this.extensionFeaturesManagementService.getAllAccessDataForExtension(( new ExtensionIdentifier(this.extension.identifier.id))).get(this.extensionViewState.filters.featureId);
            const feature = ( Registry.as(Extensions.ExtensionFeaturesRegistry)).getExtensionFeature(this.extensionViewState.filters.featureId);
            if (feature?.icon && accessData) {
                const featureAccessTimeElement = append(this.container, $("span.activationTime"));
                featureAccessTimeElement.textContent = ( localize(9319, "{0} reqs", accessData.accessTimes.length));
                const iconElement = append(this.container, $("span" + ThemeIcon.asCSSSelector(feature.icon)));
                iconElement.style.paddingLeft = "4px";
                return;
            }
        }
        const extensionStatus = this.extensionsWorkbenchService.getExtensionRuntimeStatus(this.extension);
        if (extensionStatus?.activationTimes) {
            const activationTime = extensionStatus.activationTimes.codeLoadingTime + extensionStatus.activationTimes.activateCallTime;
            append(this.container, $("span" + ThemeIcon.asCSSSelector(activationTimeIcon)));
            const activationTimeElement = append(this.container, $("span.activationTime"));
            activationTimeElement.textContent = `${activationTime}ms`;
        }
    }
};
ExtensionRuntimeStatusWidget = ( __decorate([( __param(2, IExtensionService)), ( __param(3, IExtensionFeaturesManagementService)), ( __param(4, IExtensionsWorkbenchService))], ExtensionRuntimeStatusWidget));
let ExtensionHoverWidget = ExtensionHoverWidget_1 = class ExtensionHoverWidget extends ExtensionWidget {
    constructor(
        options,
        extensionStatusAction,
        extensionsWorkbenchService,
        extensionFeaturesManagementService,
        hoverService,
        configurationService,
        extensionRecommendationsService,
        themeService,
        contextService
    ) {
        super();
        this.options = options;
        this.extensionStatusAction = extensionStatusAction;
        this.extensionsWorkbenchService = extensionsWorkbenchService;
        this.extensionFeaturesManagementService = extensionFeaturesManagementService;
        this.hoverService = hoverService;
        this.configurationService = configurationService;
        this.extensionRecommendationsService = extensionRecommendationsService;
        this.themeService = themeService;
        this.contextService = contextService;
        this.hover = this._register(( new MutableDisposable()));
    }
    render() {
        this.hover.value = undefined;
        if (this.extension) {
            this.hover.value = this.hoverService.setupManagedHover({
                delay: this.configurationService.getValue("workbench.hover.delay"),
                showHover: (options, focus) => {
                    return this.hoverService.showInstantHover({
                        ...options,
                        additionalClasses: ["extension-hover"],
                        position: {
                            hoverPosition: this.options.position(),
                            forcePosition: true
                        },
                        persistence: {
                            hideOnKeyDown: true
                        }
                    }, focus);
                },
                placement: "element"
            }, this.options.target, {
                markdown: () => Promise.resolve(this.getHoverMarkdown()),
                markdownNotSupportedFallback: undefined
            }, {
                appearance: {
                    showHoverHint: true
                }
            });
        }
    }
    getHoverMarkdown() {
        if (!this.extension) {
            return undefined;
        }
        const markdown = ( new MarkdownString("", {
            isTrusted: true,
            supportThemeIcons: true
        }));
        markdown.appendMarkdown(`**${this.extension.displayName}**`);
        if (semverExports.valid(this.extension.version)) {
            markdown.appendMarkdown(
                `&nbsp;<span style="background-color:#8080802B;">**&nbsp;_v${this.extension.version}${(this.extension.isPreReleaseVersion ? " (pre-release)" : "")}_**&nbsp;</span>`
            );
        }
        markdown.appendText(`\n`);
        let addSeparator = false;
        if (this.extension.private) {
            markdown.appendMarkdown(`$(${privateExtensionIcon.id}) ${( localize(9314, "Private Extension"))}`);
            addSeparator = true;
        }
        if (this.extension.state === ExtensionState.Installed) {
            const installLabel = InstallCountWidget.getInstallLabel(this.extension, true);
            if (installLabel) {
                if (addSeparator) {
                    markdown.appendText(`  |  `);
                }
                markdown.appendMarkdown(`$(${installCountIcon.id}) ${installLabel}`);
                addSeparator = true;
            }
            if (this.extension.rating) {
                if (addSeparator) {
                    markdown.appendText(`  |  `);
                }
                const rating = Math.round(this.extension.rating * 2) / 2;
                markdown.appendMarkdown(
                    `$(${starFullIcon.id}) [${rating}](${this.extension.url}&ssr=false#review-details)`
                );
                addSeparator = true;
            }
            if (this.extension.publisherSponsorLink) {
                if (addSeparator) {
                    markdown.appendText(`  |  `);
                }
                markdown.appendMarkdown(`$(${sponsorIcon.id}) [${( localize(9312, "Sponsor"))}](${this.extension.publisherSponsorLink})`);
                addSeparator = true;
            }
        }
        if (addSeparator) {
            markdown.appendText(`\n`);
        }
        const location = this.extension.resourceExtension?.location ?? (this.extension.local?.source === "resource" ? this.extension.local?.location : undefined);
        if (location) {
            if (this.extension.isWorkspaceScoped && this.contextService.isInsideWorkspace(location)) {
                markdown.appendMarkdown(( localize(9315, "Workspace Extension")));
            } else {
                markdown.appendMarkdown(( localize(9316, "Local Extension")));
            }
            markdown.appendText(`\n`);
        }
        if (this.extension.description) {
            markdown.appendMarkdown(`${this.extension.description}`);
            markdown.appendText(`\n`);
        }
        if (this.extension.publisherDomain?.verified) {
            const bgColor = this.themeService.getColorTheme().getColor(extensionVerifiedPublisherIconColor);
            const publisherVerifiedTooltip = ( localize(
                9320,
                "This publisher has verified ownership of {0}",
                `[${( URI.parse(this.extension.publisherDomain.link)).authority}](${this.extension.publisherDomain.link})`
            ));
            markdown.appendMarkdown(
                `<span style="color:${bgColor ? Color.Format.CSS.formatHex(bgColor) : "#ffffff"};">$(${verifiedPublisherIcon.id})</span>&nbsp;${publisherVerifiedTooltip}`
            );
            markdown.appendText(`\n`);
        }
        if (this.extension.outdated) {
            markdown.appendMarkdown(( localize(9321, "Latest version:")));
            markdown.appendMarkdown(
                `&nbsp;<span style="background-color:#8080802B;">**&nbsp;_v${this.extension.latestVersion}_**&nbsp;</span>`
            );
            markdown.appendText(`\n`);
        }
        const preReleaseMessage = ExtensionHoverWidget_1.getPreReleaseMessage(this.extension);
        const extensionRuntimeStatus = this.extensionsWorkbenchService.getExtensionRuntimeStatus(this.extension);
        const extensionFeaturesAccessData = this.extensionFeaturesManagementService.getAllAccessDataForExtension(( new ExtensionIdentifier(this.extension.identifier.id)));
        const extensionStatus = this.extensionStatusAction.status;
        const runtimeState = this.extension.runtimeState;
        const recommendationMessage = this.getRecommendationMessage(this.extension);
        if (extensionRuntimeStatus || extensionFeaturesAccessData.size || extensionStatus.length || runtimeState || recommendationMessage || preReleaseMessage) {
            markdown.appendMarkdown(`---`);
            markdown.appendText(`\n`);
            if (extensionRuntimeStatus) {
                if (extensionRuntimeStatus.activationTimes) {
                    const activationTime = extensionRuntimeStatus.activationTimes.codeLoadingTime + extensionRuntimeStatus.activationTimes.activateCallTime;
                    markdown.appendMarkdown(`${( localize(9322, "Activation time"))}${extensionRuntimeStatus.activationTimes.activationReason.startup ? ` (${( localize(9323, "Startup"))})` : ""}: \`${activationTime}ms\``);
                    markdown.appendText(`\n`);
                }
                if (extensionRuntimeStatus.runtimeErrors.length || extensionRuntimeStatus.messages.length) {
                    const hasErrors = extensionRuntimeStatus.runtimeErrors.length || ( extensionRuntimeStatus.messages.some(message => message.type === Severity$1.Error));
                    const hasWarnings = ( extensionRuntimeStatus.messages.some(message => message.type === Severity$1.Warning));
                    const errorsLink = extensionRuntimeStatus.runtimeErrors.length ? `[${extensionRuntimeStatus.runtimeErrors.length === 1 ? ( localize(9324, "1 uncaught error")) : ( localize(9325, "{0} uncaught errors", extensionRuntimeStatus.runtimeErrors.length))}](${createCommandUri(
    "extension.open",
    this.extension.identifier.id,
    ExtensionEditorTab.Features
)})` : undefined;
                    const messageLink = extensionRuntimeStatus.messages.length ? `[${extensionRuntimeStatus.messages.length === 1 ? ( localize(9326, "1 message")) : ( localize(9327, "{0} messages", extensionRuntimeStatus.messages.length))}](${createCommandUri(
    "extension.open",
    this.extension.identifier.id,
    ExtensionEditorTab.Features
)})` : undefined;
                    markdown.appendMarkdown(
                        `$(${hasErrors ? errorIcon.id : hasWarnings ? warningIcon.id : infoIcon.id}) This extension has reported `
                    );
                    if (errorsLink && messageLink) {
                        markdown.appendMarkdown(`${errorsLink} and ${messageLink}`);
                    } else {
                        markdown.appendMarkdown(`${errorsLink || messageLink}`);
                    }
                    markdown.appendText(`\n`);
                }
            }
            if (extensionFeaturesAccessData.size) {
                const registry = ( Registry.as(Extensions.ExtensionFeaturesRegistry));
                for (const [featureId, accessData] of extensionFeaturesAccessData) {
                    if (accessData?.accessTimes.length) {
                        const feature = registry.getExtensionFeature(featureId);
                        if (feature) {
                            markdown.appendMarkdown(( localize(9328, "{0} usage", feature.label)));
                            markdown.appendMarkdown(`: [${( localize(
                                9329,
                                "{0} {1} requests in last 30 days",
                                accessData.accessTimes.length,
                                feature.accessDataLabel ?? feature.label
                            ))}](${createCommandUri(
    "extension.open",
    this.extension.identifier.id,
    ExtensionEditorTab.Features
)})`);
                            markdown.appendText(`\n`);
                        }
                    }
                }
            }
            for (const status of extensionStatus) {
                if (status.icon) {
                    markdown.appendMarkdown(`$(${status.icon.id})&nbsp;`);
                }
                markdown.appendMarkdown(status.message.value);
                markdown.appendText(`\n`);
            }
            if (runtimeState) {
                markdown.appendMarkdown(`$(${infoIcon.id})&nbsp;`);
                markdown.appendMarkdown(`${runtimeState.reason}`);
                markdown.appendText(`\n`);
            }
            if (preReleaseMessage) {
                const extensionPreReleaseIcon = this.themeService.getColorTheme().getColor(extensionPreReleaseIconColor);
                markdown.appendMarkdown(
                    `<span style="color:${extensionPreReleaseIcon ? Color.Format.CSS.formatHex(extensionPreReleaseIcon) : "#ffffff"};">$(${preReleaseIcon.id})</span>&nbsp;${preReleaseMessage}`
                );
                markdown.appendText(`\n`);
            }
            if (recommendationMessage) {
                markdown.appendMarkdown(recommendationMessage);
                markdown.appendText(`\n`);
            }
        }
        return markdown;
    }
    getRecommendationMessage(extension) {
        if (extension.state === ExtensionState.Installed) {
            return undefined;
        }
        if (extension.deprecationInfo) {
            return undefined;
        }
        const recommendation = this.extensionRecommendationsService.getAllRecommendationsWithReason()[extension.identifier.id.toLowerCase()];
        if (!recommendation?.reasonText) {
            return undefined;
        }
        const bgColor = this.themeService.getColorTheme().getColor(extensionButtonProminentBackground);
        return `<span style="color:${bgColor ? Color.Format.CSS.formatHex(bgColor) : "#ffffff"};">$(${starEmptyIcon.id})</span>&nbsp;${recommendation.reasonText}`;
    }
    static getPreReleaseMessage(extension) {
        if (!extension.hasPreReleaseVersion) {
            return undefined;
        }
        if (extension.isBuiltin) {
            return undefined;
        }
        if (extension.isPreReleaseVersion) {
            return undefined;
        }
        if (extension.preRelease) {
            return undefined;
        }
        const preReleaseVersionLink = `[${( localize(9330, "Pre-Release version"))}](${createCommandUri(
    "workbench.extensions.action.showPreReleaseVersion",
    extension.identifier.id
)})`;
        return localize(9331, "This extension has a {0} available", preReleaseVersionLink);
    }
};
ExtensionHoverWidget = ExtensionHoverWidget_1 = ( __decorate([( __param(2, IExtensionsWorkbenchService)), ( __param(3, IExtensionFeaturesManagementService)), ( __param(4, IHoverService)), ( __param(5, IConfigurationService)), ( __param(6, IExtensionRecommendationsService)), ( __param(7, IThemeService)), ( __param(8, IWorkspaceContextService))], ExtensionHoverWidget));
let ExtensionStatusWidget = class ExtensionStatusWidget extends ExtensionWidget {
    constructor(container, extensionStatusAction, markdownRendererService) {
        super();
        this.container = container;
        this.extensionStatusAction = extensionStatusAction;
        this.markdownRendererService = markdownRendererService;
        this.renderDisposables = this._register(( new MutableDisposable()));
        this._onDidRender = this._register(( new Emitter()));
        this.onDidRender = this._onDidRender.event;
        this.render();
        this._register(extensionStatusAction.onDidChangeStatus(() => this.render()));
    }
    render() {
        reset(this.container);
        this.renderDisposables.value = undefined;
        const disposables = ( new DisposableStore());
        this.renderDisposables.value = disposables;
        const extensionStatus = this.extensionStatusAction.status;
        if (extensionStatus.length) {
            const markdown = ( new MarkdownString("", {
                isTrusted: true,
                supportThemeIcons: true
            }));
            for (let i = 0; i < extensionStatus.length; i++) {
                const status = extensionStatus[i];
                if (status.icon) {
                    markdown.appendMarkdown(`$(${status.icon.id})&nbsp;`);
                }
                markdown.appendMarkdown(status.message.value);
                if (i < extensionStatus.length - 1) {
                    markdown.appendText(`\n`);
                }
            }
            const rendered = disposables.add(this.markdownRendererService.render(markdown));
            append(this.container, rendered.element);
        }
        this._onDidRender.fire();
    }
};
ExtensionStatusWidget = ( __decorate([( __param(2, IMarkdownRendererService))], ExtensionStatusWidget));
let ExtensionRecommendationWidget = class ExtensionRecommendationWidget extends ExtensionWidget {
    constructor(
        container,
        extensionRecommendationsService,
        extensionIgnoredRecommendationsService
    ) {
        super();
        this.container = container;
        this.extensionRecommendationsService = extensionRecommendationsService;
        this.extensionIgnoredRecommendationsService = extensionIgnoredRecommendationsService;
        this._onDidRender = this._register(( new Emitter()));
        this.onDidRender = this._onDidRender.event;
        this.render();
        this._register(
            this.extensionRecommendationsService.onDidChangeRecommendations(() => this.render())
        );
    }
    render() {
        reset(this.container);
        const recommendationStatus = this.getRecommendationStatus();
        if (recommendationStatus) {
            if (recommendationStatus.icon) {
                append(
                    this.container,
                    $(`div${ThemeIcon.asCSSSelector(recommendationStatus.icon)}`)
                );
            }
            append(
                this.container,
                $(`div.recommendation-text`, undefined, recommendationStatus.message)
            );
        }
        this._onDidRender.fire();
    }
    getRecommendationStatus() {
        if (!this.extension || this.extension.deprecationInfo || this.extension.state === ExtensionState.Installed) {
            return undefined;
        }
        const extRecommendations = this.extensionRecommendationsService.getAllRecommendationsWithReason();
        if (extRecommendations[this.extension.identifier.id.toLowerCase()]) {
            const reasonText = extRecommendations[this.extension.identifier.id.toLowerCase()].reasonText;
            if (reasonText) {
                return {
                    icon: starEmptyIcon,
                    message: reasonText
                };
            }
        } else if (this.extensionIgnoredRecommendationsService.globalIgnoredRecommendations.indexOf(this.extension.identifier.id.toLowerCase()) !== -1) {
            return {
                icon: undefined,
                message: ( localize(9332, "You have chosen not to receive recommendations for this extension."))
            };
        }
        return undefined;
    }
};
ExtensionRecommendationWidget = ( __decorate([( __param(1, IExtensionRecommendationsService)), ( __param(2, IExtensionIgnoredRecommendationsService))], ExtensionRecommendationWidget));
const extensionRatingIconColor = registerColor("extensionIcon.starForeground", {
    light: "#DF6100",
    dark: "#FF8E00",
    hcDark: "#FF8E00",
    hcLight: textLinkForeground
}, ( localize(9333, "The icon color for extension ratings.")), false);
const extensionPreReleaseIconColor = registerColor("extensionIcon.preReleaseForeground", {
    dark: "#1d9271",
    light: "#1d9271",
    hcDark: "#1d9271",
    hcLight: textLinkForeground
}, ( localize(9334, "The icon color for pre-release extension.")), false);
registerColor("extensionIcon.sponsorForeground", {
    light: "#B51E78",
    dark: "#D758B3",
    hcDark: null,
    hcLight: "#B51E78"
}, ( localize(9335, "The icon color for extension sponsor.")), false);
const extensionPrivateBadgeBackground = registerColor("extensionIcon.privateForeground", {
    dark: "#ffffff60",
    light: "#00000060",
    hcDark: "#ffffff60",
    hcLight: "#00000060"
}, ( localize(9336, "The icon color for private extensions.")));
registerThemingParticipant((theme, collector) => {
    const extensionRatingIcon = theme.getColor(extensionRatingIconColor);
    if (extensionRatingIcon) {
        collector.addRule(
            `.extension-ratings .codicon-extensions-star-full, .extension-ratings .codicon-extensions-star-half { color: ${extensionRatingIcon}; }`
        );
        collector.addRule(
            `.monaco-hover.extension-hover .markdown-hover .hover-contents ${ThemeIcon.asCSSSelector(starFullIcon)} { color: ${extensionRatingIcon}; }`
        );
    }
    const extensionVerifiedPublisherIcon = theme.getColor(extensionVerifiedPublisherIconColor);
    if (extensionVerifiedPublisherIcon) {
        collector.addRule(
            `${ThemeIcon.asCSSSelector(verifiedPublisherIcon)} { color: ${extensionVerifiedPublisherIcon}; }`
        );
    }
    collector.addRule(
        `.monaco-hover.extension-hover .markdown-hover .hover-contents ${ThemeIcon.asCSSSelector(sponsorIcon)} { color: var(--vscode-extensionIcon-sponsorForeground); }`
    );
    collector.addRule(
        `.extension-editor > .header > .details > .subtitle .sponsor ${ThemeIcon.asCSSSelector(sponsorIcon)} { color: var(--vscode-extensionIcon-sponsorForeground); }`
    );
    const privateBadgeBackground = theme.getColor(extensionPrivateBadgeBackground);
    if (privateBadgeBackground) {
        collector.addRule(`.extension-private-badge { color: ${privateBadgeBackground}; }`);
    }
});

export { ExtensionHoverWidget, ExtensionIconBadge, ExtensionIconWidget, ExtensionKindIndicatorWidget, ExtensionPackCountWidget, ExtensionRecommendationWidget, ExtensionRestartRequiredWidget, ExtensionRuntimeStatusWidget, ExtensionStatusWidget, ExtensionWidget, InstallCountWidget, PreReleaseBookmarkWidget, PublisherWidget, RatingsWidget, RecommendationWidget, RemoteBadgeWidget, SponsorWidget, SyncIgnoredWidget, extensionPreReleaseIconColor, extensionPrivateBadgeBackground, extensionRatingIconColor, onClick };
