/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
//@ts-check

const fs = require('fs');
const path = require('path');
const os = require('os');
const { ipcRenderer } = require('electron');

const builtInExtensionsPath = path.join(__dirname, '..', '..', 'product.json');
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');

function readJson(filePath) {
	return JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' }));
}

function writeJson(filePath, obj) {
	fs.writeFileSync(filePath, JSON.stringify(obj, null, 2));
}

function renderOption(form, id, title, value, checked) {
	const input = document.createElement('input');
	input.type = 'radio';
	input.id = id;
	input.name = 'choice';
	input.value = value;
	input.checked = !!checked;
	form.appendChild(input);

	const label = document.createElement('label');
	label.setAttribute('for', id);
	label.textContent = title;
	form.appendChild(label);

	return input;
}

function render(el, state) {
	function setState(state) {
		try {
			writeJson(controlFilePath, state.control);
		} catch (err) {
			console.error(err);
		}

		el.innerHTML = '';
		render(el, state);
	}

	const ul = document.createElement('ul');
	const { builtin, control } = state;

	for (const ext of builtin) {
		const controlState = control[ext.name] || 'marketplace';

		const li = document.createElement('li');
		ul.appendChild(li);

		const name = document.createElement('code');
		name.textContent = ext.name;
		li.appendChild(name);

		const form = document.createElement('form');
		li.appendChild(form);

		const marketplaceInput = renderOption(form, `marketplace-${ext.name}`, 'Marketplace', 'marketplace', controlState === 'marketplace');
		marketplaceInput.onchange = function () {
			control[ext.name] = 'marketplace';
			setState({ builtin, control });
		};

		const disabledInput = renderOption(form, `disabled-${ext.name}`, 'Disabled', 'disabled', controlState === 'disabled');
		disabledInput.onchange = function () {
			control[ext.name] = 'disabled';
			setState({ builtin, control });
		};

		let local = undefined;

		if (controlState !== 'marketplace' && controlState !== 'disabled') {
			local = controlState;
		}

		const localInput = renderOption(form, `local-${ext.name}`, 'Local', 'local', !!local);
		localInput.onchange = async function () {
			const result = await ipcRenderer.invoke('pickdir');

			if (result) {
				control[ext.name] = result;
				setState({ builtin, control });
			}
		};

		if (local) {
			const localSpan = document.createElement('code');
			localSpan.className = 'local';
			localSpan.textContent = local;
			form.appendChild(localSpan);
		}
	}

	el.appendChild(ul);
}

function main() {
	const el = document.getElementById('extensions');
	const builtin = readJson(builtInExtensionsPath).builtInExtensions;
	let control;

	try {
		control = readJson(controlFilePath);
	} catch (err) {
		control = {};
	}

	render(el, { builtin, control });
}

window.onload = main;

@@ -665,16 +665,52 @@
 son');%0A%0A
+/**%0A * @param %7Bstring%7D filePath%0A */%0A
 function
@@ -799,24 +799,80 @@
 f8' %7D));%0A%7D%0A%0A
+/**%0A * @param %7Bstring%7D filePath%0A * @param %7Bany%7D obj%0A */%0A
 function wri
@@ -953,24 +953,165 @@
 ll, 2));%0A%7D%0A%0A
+/**%0A * @param %7BHTMLFormElement%7D form%0A * @param %7Bstring%7D id%0A * @param %7Bstring%7D title%0A * @param %7Bstring%7D value%0A * @param %7Bboolean%7D checked%0A */%0A
 function ren
@@ -1500,36 +1500,126 @@
 %0A%7D%0A%0A
-function render(el, state) %7B
+/**%0A * @param %7BHTMLElement%7D el%0A * @param %7Bany%7D state%0A */%0Afunction render(el, state) %7B%0A%09/**%0A%09 * @param %7Bany%7D state%0A%09 */
 %0A%09fu
@@ -3544,16 +3544,28 @@
 %7B%7D;%0A%09%7D%0A%0A
+%09if (el) %7B%0A%09
 %09render(
@@ -3591,16 +3591,19 @@
 rol %7D);%0A
+%09%7D%0A
 %7D%0A%0Awindo

Add type annotations in browser-main