<commit_before>const { BrowserWindow, app, shell } = require('electron').remote;
const remote = require('electron').remote;
const { Menu, autoUpdater, dialog, TouchBar } = remote;
const defaultMenu = require('electron-default-menu');
const fs = require('fs');
const css = fs.readFileSync(__dirname + '/assets/fb.css', 'utf-8');
const env = require('./config/env.js');
const userConfig = require('./modules/userConfig');
const constants = require('./helpers/constants');
const FocusHandler = require('./modules/focusHandler');
let loginWindow;

const getURL = (domain = userConfig.get('domain')) =>
	env.product === constants.PRODUCT_WWW ? 'https://www.facebook.com/messages' : `https://${domain}.facebook.com/chat`;

onload = () => {
	document.getElementById('logo').setAttribute('src', `./assets/${env.product}.png`);
	const webview = document.getElementById('webview');
	const setup = document.getElementById('setup');
	const domain = userConfig.get('domain');
	const menu = defaultMenu(app);

	menu.splice(menu.findIndex(item => item.label === 'Edit'), 0, {
		label: 'File',
		submenu: [
			{
				label: 'New Conversation',
				accelerator: 'CmdOrCtrl+N',
				click() {
					webview.send(constants.NEW_CONVERSATION);
				},
			},
		],
	});

	menu[0].submenu.splice(
		1,
		0,
		{
			type: 'separator',
		},
		{
			label: 'Preferences...',
			accelerator: 'CmdOrCtrl+,',
			click() {
				webview.send(constants.SHOW_SETTINGS);
			},
		}
	);

	let viewMenu = menu[menu.findIndex(item => item.label === 'View')];
	viewMenu.submenu.splice(
		0,
		0,
		{
			type: 'separator',
		},
		{
			label: 'Inbox',
			accelerator: 'CmdOrCtrl+1',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_INBOX);
			},
		},
		{
			label: 'Active contacts',
			accelerator: 'CmdOrCtrl+2',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_ACTIVE_CONTACTS);
			},
		},
		{
			label: 'Message requests',
			accelerator: 'CmdOrCtrl+3',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_MESSAGE_REQUESTS);
			},
		},
		{
			label: 'Archived threads',
			accelerator: 'CmdOrCtrl+4',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_ARCHIVED_THREADS);
			},
		},
		{
			type: 'separator',
		}
	);

	let windowMenu = menu[menu.findIndex(item => item.label === 'Window')];
	windowMenu.submenu.push(
		{
			label: 'Select Next Conversation',
			accelerator: 'CmdOrCtrl+]',
			click() {
				webview.send(constants.NEXT_CONVERSATION);
			},
		},
		{
			label: 'Select Previous Conversation',
			accelerator: 'CmdOrCtrl+[',
			click() {
				webview.send(constants.PREV_CONVERSATION);
			},
		},
		{
			type: 'separator',
		}
	);

	if (env.product === constants.PRODUCT_WORKPLACE) {
		windowMenu.submenu.push({
			label: 'Show notifications in menu bar',
			type: 'checkbox',
			checked: userConfig.get('menubar'),
			click() {
				userConfig.set('menubar', !userConfig.get('menubar'));
				remote.app.relaunch();
				remote.app.exit(0);
			},
		});
	}

	if (env.product === constants.PRODUCT_WWW) {
		document.getElementById('webview').setAttribute('src', getURL());
	}

	if (domain || env.product === constants.PRODUCT_WWW) {
		menu[1].submenu.push(
			{
				type: 'separator',
			},
			{
				label: env.product === constants.PRODUCT_WWW ? 'Logout' : `Logout from “${domain}”`,
				click() {
					const c = webview.getWebContents().session.cookies;
					c.get({}, (error, cookies) => {
						for (var i = cookies.length - 1; i >= 0; i--) {
							const { name, domain, path, secure } = cookies[i];
							const url = 'http' + (secure ? 's' : '') + '://' + domain + path;
							c.remove(url, name, () => {});
						}
					});

					// this waits for all cookies to be removed, it would be nicer to wait for all callbacks to be called
					setTimeout(
						() => {
							if (env.product === constants.PRODUCT_WORKPLACE) {
								userConfig.delete('domain');
							}
							app.relaunch();
							app.exit(0);
						},
						500
					);
				},
			}
		);
		document.getElementById('webview').setAttribute('src', getURL());
	} else {
		setup.className = 'active';
		setup.onsubmit = () => {
			let domain = setup.querySelector('input').value.trim();
			userConfig.set('domain', domain);
			document.getElementById('webview').setAttribute('src', getURL());
		};
	}

	if (env.name === 'production') {
		menu[0].submenu.splice(1, 0, {
			label: 'Check for Update',
			click() {
				autoUpdater.on('update-not-available', () => {
					autoUpdater.removeAllListeners('update-not-available');
					dialog.showMessageBox({
						message: 'No update available',
						detail: `${env.appName} ${app.getVersion()} is the latest version available.`,
						buttons: [ 'OK' ],
					});
				});
				autoUpdater.checkForUpdates();
			},
		});
	}

	Menu.setApplicationMenu(Menu.buildFromTemplate(menu));

	webview.addEventListener('did-stop-loading', () => {
		if (webview.getURL().startsWith(getURL())) {
			webview.className = '';
		}
	});

	webview.addEventListener('dom-ready', () => {
		webview.insertCSS(css);
		if (env.name === 'development') {
			webview.openDevTools();
		}
	});

	webview.addEventListener('ipc-message', e => {
		if (e.channel === constants.DOCK_COUNT) {
			app.setBadgeCount(e.args[0]);
		} else if (e.channel === constants.TOUCH_BAR) {
			try {
				const data = JSON.parse(e.args[0]);
				remote.getCurrentWindow().setTouchBar(
					new TouchBar(
						data.map(
							({ name, active, unread, id }) => new TouchBar.TouchBarButton({
								label: unread ? `💬 ${name}` : name,
								backgroundColor: active ? '#0084FF' : undefined,
								click: () => {
									webview.send(constants.JUMP_TO_CONVERATION, id);
								},
							})
						)
					)
				);
			} catch (e) {
				//
			}
		}
	});

	webview.addEventListener('did-get-redirect-request', ({ oldURL, newURL }) => {
		if (oldURL.startsWith(getURL()) && newURL.indexOf('/login') > -1) {
			loginWindow = new BrowserWindow({
				parent: remote.getCurrentWindow(),
				show: false,
				minimizable: false,
				maximizable: false,
				webPreferences: {
					nodeIntegration: false,
				},
			});
			loginWindow.loadURL(oldURL);
			loginWindow.once('ready-to-show', () => {
				loginWindow.show();
			});
			loginWindow.webContents.on('will-navigate', (e, url) => {
				if (url.startsWith(getURL())) {
					loginWindow.close();
					webview.loadURL(getURL());
				}
			});
		} else if (newURL.startsWith(getURL()) && loginWindow) {
			loginWindow.close();
		}
	});

	webview.addEventListener('new-window', ({ url }) => {
		shell.openExternal(url);
	});

	// Ensure focus propagates when the application is focused
	const webviewFocusHandler = new FocusHandler(webview);
	app.on('browser-window-focus', webviewFocusHandler);
};
<commit_msg>Fix incorrect accelerator for Hide Others<commit_after>const { BrowserWindow, app, shell } = require('electron').remote;
const remote = require('electron').remote;
const { Menu, autoUpdater, dialog, TouchBar } = remote;
const defaultMenu = require('electron-default-menu');
const fs = require('fs');
const css = fs.readFileSync(__dirname + '/assets/fb.css', 'utf-8');
const env = require('./config/env.js');
const userConfig = require('./modules/userConfig');
const constants = require('./helpers/constants');
const FocusHandler = require('./modules/focusHandler');
let loginWindow;

const getURL = (domain = userConfig.get('domain')) =>
	env.product === constants.PRODUCT_WWW ? 'https://www.facebook.com/messages' : `https://${domain}.facebook.com/chat`;

onload = () => {
	document.getElementById('logo').setAttribute('src', `./assets/${env.product}.png`);
	const webview = document.getElementById('webview');
	const setup = document.getElementById('setup');
	const domain = userConfig.get('domain');
	const menu = defaultMenu(app, shell);

	menu.splice(menu.findIndex(item => item.label === 'Edit'), 0, {
		label: 'File',
		submenu: [
			{
				label: 'New Conversation',
				accelerator: 'CmdOrCtrl+N',
				click() {
					webview.send(constants.NEW_CONVERSATION);
				},
			},
		],
	});

	let mainMenu = menu[0];
	mainMenu.submenu.splice(
		1,
		0,
		{
			type: 'separator',
		},
		{
			label: 'Preferences...',
			accelerator: 'CmdOrCtrl+,',
			click() {
				webview.send(constants.SHOW_SETTINGS);
			},
		}
	);

	// Fix incorrect accelerator from defaultMenu()
	mainMenu.submenu[mainMenu.submenu.findIndex(item => item.label === 'Hide Others')].accelerator = 'Command+Option+H';

	let viewMenu = menu[menu.findIndex(item => item.label === 'View')];
	viewMenu.submenu.splice(
		0,
		0,
		{
			type: 'separator',
		},
		{
			label: 'Inbox',
			accelerator: 'CmdOrCtrl+1',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_INBOX);
			},
		},
		{
			label: 'Active contacts',
			accelerator: 'CmdOrCtrl+2',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_ACTIVE_CONTACTS);
			},
		},
		{
			label: 'Message requests',
			accelerator: 'CmdOrCtrl+3',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_MESSAGE_REQUESTS);
			},
		},
		{
			label: 'Archived threads',
			accelerator: 'CmdOrCtrl+4',
			click() {
				webview.send(constants.SHOW_MESSAGE_LIST_ARCHIVED_THREADS);
			},
		},
		{
			type: 'separator',
		}
	);

	let windowMenu = menu[menu.findIndex(item => item.label === 'Window')];
	windowMenu.submenu.push(
		{
			label: 'Select Next Conversation',
			accelerator: 'CmdOrCtrl+]',
			click() {
				webview.send(constants.NEXT_CONVERSATION);
			},
		},
		{
			label: 'Select Previous Conversation',
			accelerator: 'CmdOrCtrl+[',
			click() {
				webview.send(constants.PREV_CONVERSATION);
			},
		},
		{
			type: 'separator',
		}
	);

	if (env.product === constants.PRODUCT_WORKPLACE) {
		windowMenu.submenu.push({
			label: 'Show notifications in menu bar',
			type: 'checkbox',
			checked: userConfig.get('menubar'),
			click() {
				userConfig.set('menubar', !userConfig.get('menubar'));
				remote.app.relaunch();
				remote.app.exit(0);
			},
		});
	}

	if (env.product === constants.PRODUCT_WWW) {
		document.getElementById('webview').setAttribute('src', getURL());
	}

	if (domain || env.product === constants.PRODUCT_WWW) {
		menu[1].submenu.push(
			{
				type: 'separator',
			},
			{
				label: env.product === constants.PRODUCT_WWW ? 'Logout' : `Logout from “${domain}”`,
				click() {
					const c = webview.getWebContents().session.cookies;
					c.get({}, (error, cookies) => {
						for (var i = cookies.length - 1; i >= 0; i--) {
							const { name, domain, path, secure } = cookies[i];
							const url = 'http' + (secure ? 's' : '') + '://' + domain + path;
							c.remove(url, name, () => {});
						}
					});

					// this waits for all cookies to be removed, it would be nicer to wait for all callbacks to be called
					setTimeout(
						() => {
							if (env.product === constants.PRODUCT_WORKPLACE) {
								userConfig.delete('domain');
							}
							app.relaunch();
							app.exit(0);
						},
						500
					);
				},
			}
		);
		document.getElementById('webview').setAttribute('src', getURL());
	} else {
		setup.className = 'active';
		setup.onsubmit = () => {
			let domain = setup.querySelector('input').value.trim();
			userConfig.set('domain', domain);
			document.getElementById('webview').setAttribute('src', getURL());
		};
	}

	if (env.name === 'production') {
		menu[0].submenu.splice(1, 0, {
			label: 'Check for Update',
			click() {
				autoUpdater.on('update-not-available', () => {
					autoUpdater.removeAllListeners('update-not-available');
					dialog.showMessageBox({
						message: 'No update available',
						detail: `${env.appName} ${app.getVersion()} is the latest version available.`,
						buttons: [ 'OK' ],
					});
				});
				autoUpdater.checkForUpdates();
			},
		});
	}

	Menu.setApplicationMenu(Menu.buildFromTemplate(menu));

	webview.addEventListener('did-stop-loading', () => {
		if (webview.getURL().startsWith(getURL())) {
			webview.className = '';
		}
	});

	webview.addEventListener('dom-ready', () => {
		webview.insertCSS(css);
		if (env.name === 'development') {
			webview.openDevTools();
		}
	});

	webview.addEventListener('ipc-message', e => {
		if (e.channel === constants.DOCK_COUNT) {
			app.setBadgeCount(e.args[0]);
		} else if (e.channel === constants.TOUCH_BAR) {
			try {
				const data = JSON.parse(e.args[0]);
				remote.getCurrentWindow().setTouchBar(
					new TouchBar(
						data.map(
							({ name, active, unread, id }) => new TouchBar.TouchBarButton({
								label: unread ? `💬 ${name}` : name,
								backgroundColor: active ? '#0084FF' : undefined,
								click: () => {
									webview.send(constants.JUMP_TO_CONVERATION, id);
								},
							})
						)
					)
				);
			} catch (e) {
				//
			}
		}
	});

	webview.addEventListener('did-get-redirect-request', ({ oldURL, newURL }) => {
		if (oldURL.startsWith(getURL()) && newURL.indexOf('/login') > -1) {
			loginWindow = new BrowserWindow({
				parent: remote.getCurrentWindow(),
				show: false,
				minimizable: false,
				maximizable: false,
				webPreferences: {
					nodeIntegration: false,
				},
			});
			loginWindow.loadURL(oldURL);
			loginWindow.once('ready-to-show', () => {
				loginWindow.show();
			});
			loginWindow.webContents.on('will-navigate', (e, url) => {
				if (url.startsWith(getURL())) {
					loginWindow.close();
					webview.loadURL(getURL());
				}
			});
		} else if (newURL.startsWith(getURL()) && loginWindow) {
			loginWindow.close();
		}
	});

	webview.addEventListener('new-window', ({ url }) => {
		shell.openExternal(url);
	});

	// Ensure focus propagates when the application is focused
	const webviewFocusHandler = new FocusHandler(webview);
	app.on('browser-window-focus', webviewFocusHandler);
};
<|endoftext|>


<commit_before>const apps = {
  version: 20171017,
  apps: [
    {
      name: 'Todo App',
      displayName: 'To Do List',
      description: 'A simple todo app build on blockstack.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-todo-list-256x256.png',
        large: 'app-icon-todo-list-1024x1024.png'
      },
      website: 'http://blockstack-todos.appartisan.com',
      launchLink: 'http://blockstack-todos.appartisan.com',
      developer: 'Larry Salibra',
      storageRequired: true,
      status: 'user_ready'
    }, {
      name: 'Guild',
      displayName: 'Guild',
      description: 'A blogging app powered by Blockstack.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-guild-256x256.png',
        large: 'app-icon-guild-1024x1024.png'
      },
      website: 'http://www.guildblog.com',
      launchLink: 'http://www.guildblog.com',
      developer: 'Jay Hwang',
      storageRequired: true,
      status: 'in_progress'
    }, {
      name: 'Ongaku Ryoho',
      displayName: 'Ongaku Ryoho',
      description: 'A music player which connects to your cloud/distributed storage.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-ongaku-ryoho-256x256.png',
        large: 'app-icon-ongaku-ryoho-1024x1024.png'
      },
      website: 'http://www.ongakuryoho.com',
      launchLink: 'http://www.ongakuryoho.com',
      developer: '',
      storageRequired: true,
      status: 'in_progress'
    }, {
      name: 'Hello, Blockstack',
      displayName: 'Hello, Blockstack',
      description: 'A simple demo of Blockstack Auth',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-hello-blockstack-256x256.png',
        large: 'app-icon-hello-blockstack-1024x1024.png'
      },
      website: 'https://www.helloblockstack.com',
      launchLink: 'https://www.helloblockstack.com',
      developer: 'Blockstack PBC',
      status: 'user_ready'
    }, {
      name: 'Blockstack Forum',
      displayName: 'Forum',
      description: 'Blockstack Forum',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-forum-256x256.png',
        large: 'app-icon-forum-1024x1024.png'
      },
      website: 'https://forum.blockstack.org',
      launchLink: 'https://forum.blockstack.org',
      developer: 'Blockstack PBC',
      status: 'user_ready'
    }, {
      name: 'Coinfolio',
      displayName: 'Coinfolio',
      description: 'Coinfolio',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinfolio-256x256.png',
        large: 'app-icon-coinfolio-1024x1024.png'
      },
      website: 'http://coinfolio-app.herokuapp.com/',
      launchLink: 'http://coinfolio-app.herokuapp.com/',
      developer: 'Coinfolio',
      status: 'user_ready_token'
    }, {
      name: 'Casa',
      displayName: 'Casa',
      description: 'Open source home sharing protocol.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-casa-256x256.png',
        large: 'app-icon-casa-1024x1024.png'
      },
      website: 'https://casa.cash',
      launchLink: 'https://casa.cash',
      developer: 'Bedkin, Inc.',
      status: 'in_progress'
    }, {
      name: 'Beacon',
      displayName: 'Beacon',
      description: 'Decentralized, transparent, secure voting.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-beacon-256x256.png',
        large: 'app-icon-beacon-1024x1024.png'
      },
      website: 'https://ntzwrk.org/projects/beacon/',
      launchLink: 'https://ntzwrk.org/projects/beacon/',
      developer: 'ntzwrk',
      status: 'in_progress'
    }, {
      name: 'Afia',
      displayName: 'Afia',
      description: 'A brand new way to control your health data.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-afia-256x256.png',
        large: 'app-icon-afia-1024x1024.png'
      },
      website: 'http://www.afiabeta.com/',
      launchLink: 'http://www.afiabeta.com/',
      developer: 'Afia',
      status: 'in_progress'
    }, {
      name: 'DotPodcast',
      displayName: 'DotPodcast',
      description: 'A software lab for podcasts and blockchains.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-dotpodcast-256x256.png',
        large: 'app-icon-dotpodcast-1024x1024.png'
      },
      website: 'https://dotpodcast.co/',
      launchLink: 'https://dotpodcast.co/',
      developer: 'DotPodcast',
      status: 'in_progress'
    }, {
      name: 'Postly',
      displayName: 'Postly',
      description: 'The best way to share and discover content with friends.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-postly-256x256.png',
        large: 'app-icon-postly-512x512.png'
      },
      website: 'https://www.postly.co/blockstack',
      launchLink: 'https://www.postly.co/blockstack',
      developer: 'Postly',
      status: 'in_progress'
    }, {
      name: 'Arenaplay',
      displayName: 'Arenaplay',
      description: 'Games where players time is valued.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-arenaplay-256x256.png',
        large: 'app-icon-arenaplay-512x512.png'
      },
      website: 'https://arenaplay.io/start',
      launchLink: 'https://arenaplay.io/start',
      developer: 'Arenaplay',
      status: 'in_progress'
    }, {
      name: 'AMGiving',
      displayName: 'AMGiving',
      description: 'Creating transparency in charitable giving.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-amgiving-256x256.png',
        large: 'app-icon-amgiving-512x512.png'
      },
      website: 'http://amgiving.io',
      launchLink: 'http://amgiving.io',
      developer: 'AMGiving',
      status: 'in_progress'
    }, {
      name: 'Symmitree',
      displayName: 'Symmitree',
      description: 'Providing free connectivity to the displaced and deprived.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-symmitree-256x256.png',
        large: 'app-icon-symmitree-512x512.png'
      },
      website: 'http://symmitree.com',
      launchLink: 'http://symmitree.com',
      developer: 'Symmitree',
      status: 'in_progress'
    }, {
      name: 'Eder',
      displayName: 'Eder',
      description: 'A decentralized stash for your personal data.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-eder-256x256.png',
        large: 'app-icon-eder-512x512.png'
      },
      website: 'http://eder.io',
      launchLink: 'http://eder.io',
      developer: 'Eder',
      status: 'in_progress'
    }, {
      name: 'Souq',
      displayName: 'Souq',
      description: 'Project Management Platform.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-souq-256x256.png',
        large: 'app-icon-souq-512x512.png'
      },
      website: 'http://beta.cryptocracy.io',
      launchLink: 'http://beta.cryptocracy.io',
      developer: 'Souq',
      status: 'in_progress'
    }, {
      name: 'CoinStack',
      displayName: 'CoinStack',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinstack-a-256x256.png',
        large: 'app-icon-coinstack-a-512x512.png'
      },
      website: 'http://coinstack.one/',
      launchLink: 'http://coinstack.one/',
      developer: 'CoinStack',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coins',
      displayName: 'Coins',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coins-256x256.png',
        large: 'app-icon-coins-512x512.png'
      },
      website: 'http://use.coinsapp.co/',
      launchLink: 'http://use.coinsapp.co/',
      developer: 'Coins',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'BlockPortfolio',
      displayName: 'BlockPortfolio',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-blockportfolio-256x256.png',
        large: 'app-icon-blockportfolio-512x512.png'
      },
      website: 'https://www.blockportfol.io/',
      launchLink: 'https://www.blockportfol.io/',
      developer: 'BlockPortfolio',
      status: 'user_ready_token',
      storageRequired: true
    }
  ]
}

module.exports = apps
<commit_msg>added 14 new apps to home screen #1108<commit_after>const apps = {
  version: 20171017,
  apps: [
    {
      name: 'Todo App',
      displayName: 'To Do List',
      description: 'A simple todo app build on blockstack.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-todo-list-256x256.png',
        large: 'app-icon-todo-list-1024x1024.png'
      },
      website: 'http://blockstack-todos.appartisan.com',
      launchLink: 'http://blockstack-todos.appartisan.com',
      developer: 'Larry Salibra',
      storageRequired: true,
      status: 'user_ready'
    }, {
      name: 'Guild',
      displayName: 'Guild',
      description: 'A blogging app powered by Blockstack.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-guild-256x256.png',
        large: 'app-icon-guild-1024x1024.png'
      },
      website: 'http://www.guildblog.com',
      launchLink: 'http://www.guildblog.com',
      developer: 'Jay Hwang',
      storageRequired: true,
      status: 'in_progress'
    }, {
      name: 'Ongaku Ryoho',
      displayName: 'Ongaku Ryoho',
      description: 'A music player which connects to your cloud/distributed storage.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-ongaku-ryoho-256x256.png',
        large: 'app-icon-ongaku-ryoho-1024x1024.png'
      },
      website: 'http://www.ongakuryoho.com',
      launchLink: 'http://www.ongakuryoho.com',
      developer: '',
      storageRequired: true,
      status: 'in_progress'
    }, {
      name: 'Hello, Blockstack',
      displayName: 'Hello, Blockstack',
      description: 'A simple demo of Blockstack Auth',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-hello-blockstack-256x256.png',
        large: 'app-icon-hello-blockstack-1024x1024.png'
      },
      website: 'https://www.helloblockstack.com',
      launchLink: 'https://www.helloblockstack.com',
      developer: 'Blockstack PBC',
      status: 'user_ready'
    }, {
      name: 'Blockstack Forum',
      displayName: 'Forum',
      description: 'Blockstack Forum',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-forum-256x256.png',
        large: 'app-icon-forum-1024x1024.png'
      },
      website: 'https://forum.blockstack.org',
      launchLink: 'https://forum.blockstack.org',
      developer: 'Blockstack PBC',
      status: 'user_ready'
    }, {
      name: 'Coinfolio',
      displayName: 'Coinfolio',
      description: 'Coinfolio',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinfolio-256x256.png',
        large: 'app-icon-coinfolio-1024x1024.png'
      },
      website: 'http://coinfolio-app.herokuapp.com/',
      launchLink: 'http://coinfolio-app.herokuapp.com/',
      developer: 'Coinfolio',
      status: 'user_ready_token'
    }, {
      name: 'Casa',
      displayName: 'Casa',
      description: 'Open source home sharing protocol.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-casa-256x256.png',
        large: 'app-icon-casa-1024x1024.png'
      },
      website: 'https://casa.cash',
      launchLink: 'https://casa.cash',
      developer: 'Bedkin, Inc.',
      status: 'in_progress'
    }, {
      name: 'Beacon',
      displayName: 'Beacon',
      description: 'Decentralized, transparent, secure voting.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-beacon-256x256.png',
        large: 'app-icon-beacon-1024x1024.png'
      },
      website: 'https://ntzwrk.org/projects/beacon/',
      launchLink: 'https://ntzwrk.org/projects/beacon/',
      developer: 'ntzwrk',
      status: 'in_progress'
    }, {
      name: 'Afia',
      displayName: 'Afia',
      description: 'A brand new way to control your health data.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-afia-256x256.png',
        large: 'app-icon-afia-1024x1024.png'
      },
      website: 'http://www.afiabeta.com/',
      launchLink: 'http://www.afiabeta.com/',
      developer: 'Afia',
      status: 'in_progress'
    }, {
      name: 'DotPodcast',
      displayName: 'DotPodcast',
      description: 'A software lab for podcasts and blockchains.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-dotpodcast-256x256.png',
        large: 'app-icon-dotpodcast-1024x1024.png'
      },
      website: 'https://dotpodcast.co/',
      launchLink: 'https://dotpodcast.co/',
      developer: 'DotPodcast',
      status: 'in_progress'
    }, {
      name: 'Postly',
      displayName: 'Postly',
      description: 'The best way to share and discover content with friends.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-postly-256x256.png',
        large: 'app-icon-postly-512x512.png'
      },
      website: 'https://www.postly.co/blockstack',
      launchLink: 'https://www.postly.co/blockstack',
      developer: 'Postly',
      status: 'in_progress'
    }, {
      name: 'Arenaplay',
      displayName: 'Arenaplay',
      description: 'Games where players time is valued.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-arenaplay-256x256.png',
        large: 'app-icon-arenaplay-512x512.png'
      },
      website: 'https://arenaplay.io/start',
      launchLink: 'https://arenaplay.io/start',
      developer: 'Arenaplay',
      status: 'in_progress'
    }, {
      name: 'AMGiving',
      displayName: 'AMGiving',
      description: 'Creating transparency in charitable giving.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-amgiving-256x256.png',
        large: 'app-icon-amgiving-512x512.png'
      },
      website: 'http://amgiving.io',
      launchLink: 'http://amgiving.io',
      developer: 'AMGiving',
      status: 'in_progress'
    }, {
      name: 'Symmitree',
      displayName: 'Symmitree',
      description: 'Providing free connectivity to the displaced and deprived.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-symmitree-256x256.png',
        large: 'app-icon-symmitree-512x512.png'
      },
      website: 'http://symmitree.com',
      launchLink: 'http://symmitree.com',
      developer: 'Symmitree',
      status: 'in_progress'
    }, {
      name: 'Eder',
      displayName: 'Eder',
      description: 'A decentralized stash for your personal data.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-eder-256x256.png',
        large: 'app-icon-eder-512x512.png'
      },
      website: 'http://eder.io',
      launchLink: 'http://eder.io',
      developer: 'Eder',
      status: 'in_progress'
    }, {
      name: 'Souq',
      displayName: 'Souq',
      description: 'Project Management Platform.',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-souq-256x256.png',
        large: 'app-icon-souq-512x512.png'
      },
      website: 'http://beta.cryptocracy.io',
      launchLink: 'http://beta.cryptocracy.io',
      developer: 'Souq',
      status: 'in_progress'
    }, {
      name: 'Coins',
      displayName: 'Coins',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coins-256x256.png',
        large: 'app-icon-coins-512x512.png'
      },
      website: 'http://use.coinsapp.co',
      launchLink: 'http://use.coinsapp.co',
      developer: 'Chase Wackerfuss',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coinfort',
      displayName: 'Coinfort',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinfort-256x256.png',
        large: 'app-icon-coinfort-512x512.png'
      },
      website: 'http://www.coinfort.io',
      launchLink: 'http://www.coinfort.io',
      developer: 'Satraj Bambra',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Cryptagon',
      displayName: 'Cryptagon',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-cryptagon-256x256.png',
        large: 'app-icon-cryptagon-512x512.png'
      },
      website: 'http://app.cryptagon.io/',
      launchLink: 'http://app.cryptagon.io/',
      developer: 'Bernat Fortet Unanue',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coinbrella',
      displayName: 'Coinbrella',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinbrella-256x256.png',
        large: 'app-icon-coinbrella-512x512.png'
      },
      website: 'http://coinbrella.com/',
      launchLink: 'http://coinbrella.com/',
      developer: 'Luciano Leal',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'CoinKitty',
      displayName: 'CoinKitty',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinkitty-256x256.png',
        large: 'app-icon-coinkitty-512x512.png'
      },
      website: 'http://www.coinkitty.co/',
      launchLink: 'http://www.coinkitty.co/',
      developer: 'Vince DePalma',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coinocle',
      displayName: 'Coinocle',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinocle-256x256.png',
        large: 'app-icon-coinocle-512x512.png'
      },
      website: 'http://blockstack.coinocle.com',
      launchLink: 'http://blockstack.coinocle.com',
      developer: 'Justin Hunter',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'faa.st',
      displayName: 'faa.st',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-faast-256x256.png',
        large: 'app-icon-faast-512x512.png'
      },
      website: 'http://faa.st/portfolio',
      launchLink: 'http://faa.st/portfolio',
      developer: 'Moe Adham',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coinremix',
      displayName: 'Coinremix',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinremix-256x256.png',
        large: 'app-icon-coinremix-512x512.png'
      },
      website: 'http://coinremix.netlify.com/',
      launchLink: 'http://coinremix.netlify.com/',
      developer: 'Ben Longstaff',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'BlockPortfolio',
      displayName: 'BlockPortfolio',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-blockfolio-256x256.png',
        large: 'app-icon-blockfolio-512x512.png'
      },
      website: 'http://www.blockportfol.io/',
      launchLink: 'http://www.blockportfol.io/',
      developer: 'Patrick DeVivo',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'CoinStack',
      displayName: 'CoinStack',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coinstack-256x256.png',
        large: 'app-icon-coinstack-512x512.png'
      },
      website: 'http://www.coinstack.one/',
      launchLink: 'http://www.coinstack.one/',
      developer: 'Ben Rogmans',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Proem',
      displayName: 'Proem',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-proem-256x256.png',
        large: 'app-icon-proem-512x512.png'
      },
      website: 'http://proem.io',
      launchLink: 'http://proem.io',
      developer: 'Cole Jorissen',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Coindex',
      displayName: 'Coindex',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-coindex-256x256.png',
        large: 'app-icon-coindex-512x512.png'
      },
      website: 'http://coindexapp.herokuapp.com',
      launchLink: 'http://coindexapp.herokuapp.com',
      developer: 'Daniel Shijia Wang',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Lio',
      displayName: 'Lio',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-lio-256x256.png',
        large: 'app-icon-lio-512x512.png'
      },
      website: 'http://tap-five-lio.herokuapp.com',
      launchLink: 'http://tap-five-lio.herokuapp.com',
      developer: 'Alec Richter',
      status: 'user_ready_token',
      storageRequired: true
    }, {
      name: 'Peachy Portfolio',
      displayName: 'Peachy Portfolio',
      description: '',
      version: '1.0.0',
      appIcon: {
        small: 'app-icon-peachy-256x256.png',
        large: 'app-icon-peachy-512x512.png'
      },
      website: 'http://peachyportfolio.com/',
      launchLink: 'http://peachyportfolio.com/',
      developer: 'Brandon Paree',
      status: 'user_ready_token',
      storageRequired: true
    }
  ]
}

module.exports = apps
<|endoftext|>


<commit_before>angular.module('BWMonApp').run(['$templateCache', function($templateCache) {
  'use strict';

  $templateCache.put('templates/UsageByMonth.tpl.html',
    "<form class=\"form-inline\" role=\"form\">\n" +
    "\t<button id=\"buttonShowChart\" class=\"btn btn-primary\" ng-click=\"showChart=!showChart\">Show\n" +
    "\t\tData\n" +
    "\t\tChart\n" +
    "\t</button>\n" +
    " \t
\n" +
    "\t\tYear\n" +
    "\t\t<select class=\"form-control\" name=\"year\" ng-model=\"year\" ng-options=\"choiceYear for choiceYear in years\"></select>\n" +
    "\t
\n" +
    "\t
\n" +
    "\t\tChart Type\n" +
    "\t\t<select class=\"form-control\" name=\"chartType\" ng-model=\"chartSeries[0].type\" ng-options=\"chartType for chartType in chartTypes\"></select>\n" +
    "\t
\n" +
    "</form>\n" +
    "
\n" +
    "\t<linechart id=\"chartData\" data=\"chartData\" options=\"chartOptions\"></linechart>\n" +
    "
\n" +
    "
\n" +
    "\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\tMonth	\n" +
    "\t\t\t\tDown	\n" +
    "\t\t\t\tUp	\n" +
    "\t\t\t\tTotal	\n" +
    "\t\t\t\tPercent	\n" +
    "\t\t\t\tAverage	\n" +
    "\t\t\t\tDays	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\t{{current.id | toMonth}}	\n" +
    "\t\t\t\t{{current.download | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.upload | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.total | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{(current.total * 100 / total.total) | number:1}}%	\n" +
    "\t\t\t\t{{current.average | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.days}}	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\t{{year}} Totals	\n" +
    "\t\t\t\t{{total.download | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.upload | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.total | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t	\n" +
    "\t\t\t\t{{total.average | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.days}}	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t
\n" +
    "
\n"
  );

  $templateCache.put('templates/UsageByUser.tpl.html',
    "<form class=\"form-inline\" role=\"form\">\n" +
    "\t<button id=\"buttonShowChart\" class=\"btn btn-primary\" ng-click=\"showChart=!showChart\">Show\n" +
    "\t\tData\n" +
    "\t\tChart\n" +
    "\t</button>\n" +
    " \t
\n" +
    "\t\tYear\n" +
    "\t\t<select class=\"form-control\" name=\"year\" ng-model=\"selected.year\" ng-options=\"choiceYear for choiceYear in years\"></select>\n" +
    "\t
\n" +
    " \t
\n" +
    "\t\tMonth\n" +
    "\t\t<select class=\"form-control\" name=\"month\" ng-model=\"selected.month\" ng-options=\"choiceMonth for choiceMonth in months\"></select>\n" +
    "\t
\n" +
    " \t
\n" +
    "\t\tFilter by IP, MAC or User\n" +
    "\t\t<input class=\"form-control\" name=\"filter\" placeholder=\"IP, MAC or User\" ng-model=\"selected.filter\"/>\n" +
    "\t
\n" +
    "\t
\n" +
    "\t\tChart Type\n" +
    "\t\t<select class=\"form-control\" name=\"chartType\" ng-model=\"chartSeries[0].type\" ng-options=\"chartType for chartType in chartTypes\"></select>\n" +
    "\t
\n" +
    "\t
\n" +
    "\t\t\n" +
    "\t\t\t<button id=\"buttonPrevious\" class=\"btn btn-primary\" ng-disabled=\"!page.hasPrevious()\" ng-click=\"page.previous()\">Previous</button>\n" +
    "\t\t\t{{page.current + 1}}/{{page.pages(data)}}\n" +
    "\t\t\t<button id=\"buttonNext\" class=\"btn btn-primary\" ng-disabled=\"!page.hasNext(data)\" ng-click=\"page.next(data)\">Next</button>\n" +
    "\t\t\n" +
    "\t
\n" +
    "</form>\n" +
    "
\n" +
    "\t<linechart id=\"chartData\" data=\"chartData\" options=\"chartOptions\"></linechart>\n" +
    "
\n" +
    "
\n" +
    "\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\tIP	\n" +
    "\t\t\t\tMAC	\n" +
    "\t\t\t\tUser	\n" +
    "\t\t\t\tDown	\n" +
    "\t\t\t\tUp	\n" +
    "\t\t\t\tTotal	\n" +
    "\t\t\t\tPercent	\n" +
    "\t\t\t\tAverage	\n" +
    "\t\t\t\tDays	\n" +
    "\t\t\t\tFirst Seen	\n" +
    "\t\t\t\tLast Seen	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\t{{current.IP}}	\n" +
    "\t\t\t\t{{current.MAC}}	\n" +
    "\t\t\t\t{{current.user}}	\n" +
    "\t\t\t\t{{current.download | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.upload | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.total | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{(current.total * 100 / total.total) | number:1}}%	\n" +
    "\t\t\t\t{{current.average | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.days}}	\n" +
    "\t\t\t\t{{current.firstSeen | timeToDate | date: 'medium'}}	\n" +
    "\t\t\t\t{{current.lastSeen | timeToDate | date: 'medium'}}	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\t{{selected.month}} {{selected.year}} Totals	\n" +
    "\t\t\t\t{{total.download | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.upload | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.total | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t	\n" +
    "\t\t\t\t{{total.average | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{total.days}}	\n" +
    "\t\t\t\t	\n" +
    "\t\t\t\t	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t
\n" +
    "
\n"
  );

  $templateCache.put('templates/UsageByYear.tpl.html',
    "<form class=\"form-inline\" role=\"form\">\n" +
    "\t<button id=\"buttonShowChart\" class=\"btn btn-primary\" ng-click=\"showChart=!showChart\">Show\n" +
    "\t\tData\n" +
    "\t\tChart\n" +
    "\t</button>\n" +
    "\t
\n" +
    "\t\tChart Type\n" +
    "\t\t<select class=\"form-control\" name=\"chartType\" ng-model=\"chartSeries[0].type\" ng-options=\"chartType for chartType in chartTypes\"></select>\n" +
    "\t
\n" +
    "</form>\n" +
    "
\n" +
    "\t<linechart id=\"chartData\" data=\"chartData\" options=\"chartOptions\"></linechart>\n" +
    "
\n" +
    "
\n" +
    "\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\tYear	\n" +
    "\t\t\t\tDown	\n" +
    "\t\t\t\tUp	\n" +
    "\t\t\t\tTotal	\n" +
    "\t\t\t\tAverage	\n" +
    "\t\t\t\tDays	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t\t
\n" +
    "\t\t\t
\n" +
    "\t\t\t\t{{current.id}}	\n" +
    "\t\t\t\t{{current.download | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.upload | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.total | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.average | usageInGBytes | number:3}}	\n" +
    "\t\t\t\t{{current.days}}	\n" +
    "\t\t\t
\n" +
    "\t\t
\n" +
    "\t
\n" +
    "
\n"
  );

}]);
<commit_msg>removed template.js since it is now part of build process<commit_after><|endoftext|>


<commit_before>module.exports = function(win,firstScene){
	var platino = require('io.platino');
	var game = platino.createGameView({
		fps:30,                                                 // Game frame rate. Set 30fps for Iphone4, iPad1 and old android devices
		debug:true,                                            // Enable debug logs
		usePerspective:false                                    // Sets/gets viewpoint type of the GameView (perspective or orthogonal).
	});
	game.color(1, 1, 1);                                    	 // set initial background color to white

	game.TARGET_SCREEN = {height:1536,width:2048};

	function onGameActivated(e){

	 	Ti.API.info('Game Onload');

		var screenScale = game.size.height / game.TARGET_SCREEN.height;
		Ti.API.info("Screen scale "+screenScale);
		Ti.API.info("view size: " + game.size.width + "x" + game.size.height);
		Ti.API.info("game screen size before: " + game.screen.width + "x" + game.screen.height);
		game.screen = {width:game.size.width / screenScale, height:game.size.height / screenScale};
		Ti.API.info("game screen size after: " + game.screen.width + "x" + game.screen.height);

		game.offset = (game.screen.width - game.TARGET_SCREEN.width)/2;

		game.screenScale = game.screen.height / game.TARGET_SCREEN.height;

		var MainScene  = require(firstScene);   			// Import the MainScene module into the current scope
		game.currentScene = new MainScene(win, game);       // Set MainScene as the current scene

		game.pushScene(game.currentScene);                  // Pushes the specified Scene instance into the scene stack (places it at the very top). The scene (now at the top) will then become the currently shown (active) scene.
		game.start();                                       // Starts the game

	};

	game.oX=function(x){
		return x+game.offset;
	};

	game.addEventListener('onload', onGameActivated);

	return game;
};
<commit_msg>test 3<commit_after>module.exports = function(win,firstScene){
	var platino = require('io.platino');
	var game = platino.createGameView({
		fps:30,                                                 // Game frame rate. Set 30fps for Iphone4, iPad1 and old android devices
		debug:true,                                            // Enable debug logs
		usePerspective:false                                    // Sets/gets viewpoint type of the GameView (perspective or orthogonal).
	});
	game.color(1, 1, 1);                                    	 // set initial background color to white

	game.TARGET_SCREEN = {height:1536,width:2048};

	function onGameActivated(e){

	 	Ti.API.info('Game Onload');

		var screenScale = game.size.height / game.TARGET_SCREEN.height;
		Ti.API.info("Screen scale "+screenScale);
		Ti.API.info("view size: " + game.size.width + "x" + game.size.height);
		Ti.API.info("game screen size before: " + game.screen.width + "x" + game.screen.height);
		game.screen = {width:game.size.width / screenScale, height:game.size.height / screenScale};
		Ti.API.info("game screen size after: " + game.screen.width + "x" + game.screen.height);

		game.offset = (game.screen.width - game.TARGET_SCREEN.width)/2;

		game.screenScale = game.screen.height / game.TARGET_SCREEN.height;

		var MainScene  = require(firstScene);   			// Import the MainScene module into the current scope
		game.currentScene = new MainScene(win, game);       // Set MainScene as the current scene

		game.pushScene(game.currentScene);                  // Pushes the specified Scene instance into the scene stack (places it at the very top). The scene (now at the top) will then become the currently shown (active) scene.
		game.start();                                       // Starts the game

	};

  //test comment
	game.oX=function(x){
		return x+game.offset;
	};

	game.addEventListener('onload', onGameActivated);

	return game;
};
<|endoftext|>


<commit_before>/**
 * A module containing shuttle-related helper functions
 * @module util/shuttle
 */
module.exports = {

	/**
	 * Gets the minutes of "estimated time of arrival" from an amount of seconds
	 * @function
	 * @param {number} secondToArrival The number of seconds until arrival
	 * @returns {string} A user-friendly respresentation of the number of minutes
	 */
	getMinutesETA(secondsToArrival) {
		if (secondsToArrival < 1) {
			return ('Arrived');
		} else if (secondsToArrival < 60) {
			return ('<1 min');
		} else {
			let secondsToArrivalDec = secondsToArrival;
			let minsToArrival = 1;

			while (secondsToArrivalDec > 60) {
				secondsToArrivalDec -= 60;
				minsToArrival++;
			}

			if (minsToArrival === 1) {
				return ('1 min');
			} else {
				return (minsToArrival + ' mins');
			}
		}
	},

};
<commit_msg>condense shuttle eta<commit_after>/**
 * A module containing shuttle-related helper functions
 * @module util/shuttle
 */
module.exports = {

	/**
	 * Gets the minutes of "estimated time of arrival" from an amount of seconds
	 * @function
	 * @param {number} secondToArrival The number of seconds until arrival
	 * @returns {string} A user-friendly respresentation of the number of minutes
	 */
	getMinutesETA(secondsToArrival) {
		if (secondsToArrival < 1) {
			return ('Arrived');
		} else if (secondsToArrival < 60) {
			return ('<1 m');
		} else {
			let secondsToArrivalDec = secondsToArrival;
			let minsToArrival = 1;

			while (secondsToArrivalDec > 60) {
				secondsToArrivalDec -= 60;
				minsToArrival++;
			}

			return (minsToArrival + 'm');
		}
	},
};
<|endoftext|>


<commit_before>"use strict";

var CONF = {
    baseUrl: 'lib/ion-tree-list',
    digestTtl: 35
};

function addDepthToTree(obj, depth, collapsed) {
    for (var key in obj) {
        if (typeof(obj[key]) == 'object') {
            obj[key].depth = depth;
            obj[key].collapsed = collapsed;
            addDepthToTree(obj[key], key === 'tree' ? ++ depth : depth, collapsed)
        }
    }
    return obj
}

function toggleCollapse(obj) {
    for (var key in obj) {
        if (typeof(obj[key]) == 'object') {
            obj[key].collapsed = !obj[key].collapsed;
            toggleCollapse(obj[key])
        }
    }
    return obj
}

angular.module('ion-tree-list', [], function($rootScopeProvider){
    $rootScopeProvider.digestTtl(CONF.digestTtl)
})
.directive('ionTreeList', function () {
    return {
        restrict: 'E',
        scope: {
            items: '=',
            collapsed: '='
        },
        templateUrl: CONF.baseUrl + '/ion-tree-list.tmpl.html',
        controller: function($scope){
            $scope.baseUrl = CONF.baseUrl;
            $scope.items = addDepthToTree($scope.items, 1, $scope.collapsed);
            $scope.toggleCollapse = toggleCollapse;

            $scope.$watch('collapsed', function(){
                $scope.toggleCollapse($scope.items);
            })
        }
    }
});
<commit_msg>FIX watch items when loaded (also async)<commit_after>"use strict";

var CONF = {
    baseUrl: 'lib/ion-tree-list',
    digestTtl: 35
};

function addDepthToTree(obj, depth, collapsed) {
    for (var key in obj) {
        if (typeof(obj[key]) == 'object') {
            obj[key].depth = depth;
            obj[key].collapsed = collapsed;
            addDepthToTree(obj[key], key === 'tree' ? ++ depth : depth, collapsed)
        }
    }
    return obj
}

function toggleCollapse(obj) {
    for (var key in obj) {
        if (typeof(obj[key]) == 'object') {
            obj[key].collapsed = !obj[key].collapsed;
            toggleCollapse(obj[key])
        }
    }
    return obj
}

angular.module('ion-tree-list', [], function($rootScopeProvider){
    $rootScopeProvider.digestTtl(CONF.digestTtl)
})
.directive('ionTreeList', function () {
    return {
        restrict: 'E',
        scope: {
            items: '=',
            collapsed: '='
        },
        templateUrl: CONF.baseUrl + '/ion-tree-list.tmpl.html',
        controller: function($scope){
            $scope.baseUrl = CONF.baseUrl;
            $scope.toggleCollapse = toggleCollapse;

            $scope.$watch('collapsed', function(){
                $scope.toggleCollapse($scope.items);
            });

            $scope.$watch('items', function(){
                $scope.items = addDepthToTree($scope.items, 1, $scope.collapsed);
            });
        }
    }
});
<|endoftext|>


<commit_before>import { gltfInput } from './input.js';

import { GltfView, computePrimitiveCentroids, loadGltf, loadEnvironment, initKtxLib, initDracoLib } from 'gltf-sample-viewer';

import { UIModel } from './logic/uimodel.js';
import { app } from './ui/ui.js';
import { Observable, Subject, from, merge } from 'rxjs';
import { mergeMap, filter, map, multicast } from 'rxjs/operators';
import { gltfModelPathProvider } from './model_path_provider.js';

async function main()
{
    const canvas = document.getElementById("canvas");
    const context = canvas.getContext("webgl2", { alpha: false, antialias: true });
    const ui = document.getElementById("app");
    const view = new GltfView(context, ui);
    const state = view.createState();

    initDracoLib();
    initKtxLib(view);

    loadEnvironment("assets/environments/footprint_court_512.hdr", view).then( (environment) => {
        state.environment = environment;
    });
    const pathProvider = new gltfModelPathProvider('assets/models/2.0/model-index.json');
    await pathProvider.initialize();

    const uiModel = await new UIModel(app, pathProvider, state);

    // whenever a new model is selected, load it and when complete pass the loaded gltf
    // into a stream back into the UI
    const subject = new Subject();
    const gltfLoadedMulticast = uiModel.model.pipe(
        mergeMap( (model) =>
        {
            return from(loadGltf(model.mainFile, view, model.additionalFiles).then( (gltf) => {
                state.gltf = gltf;
                const defaultScene = state.gltf.scene;
                state.sceneIndex = defaultScene === undefined ? 0 : defaultScene;
                const scene = state.gltf.scenes[state.sceneIndex];
                scene.applyTransformHierarchy(state.gltf);
                computePrimitiveCentroids(state.gltf);
                state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
                state.userCamera.updatePosition();
                state.animationIndices = [0];
                state.animationTimer.start();
                return state;
            })
            );
        }),
        // transform gltf loaded observable to multicast observable to avoid multiple execution with multiple subscriptions
        multicast(subject)
    );

    const sceneChangedObservable = uiModel.scene.pipe(map( newSceneIndex => {
        state.sceneIndex = newSceneIndex;
        const scene = state.gltf.scenes[state.sceneIndex];
        scene.applyTransformHierarchy(state.gltf);
        computePrimitiveCentroids(state.gltf);
        state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
        state.userCamera.updatePosition();
    }));

    const statisticsUpdateObservableTemp = merge(
        gltfLoadedMulticast,
        sceneChangedObservable
    );

    const statisticsUpdateObservable = statisticsUpdateObservableTemp.pipe(
        map( (_) => view.gatherStatistics(state) )
    );

    uiModel.camera.pipe(filter(camera => camera === "User Camera")).subscribe( () => {
        state.cameraIndex = undefined;
    });
    uiModel.camera.pipe(filter(camera => camera !== "User Camera")).subscribe( camera => {
        state.cameraIndex = camera;
    });

    uiModel.variant.subscribe( variant => {
        state.variant = variant;
    });

    uiModel.tonemap.subscribe( tonemap => {
        state.renderingParameters.toneMap = tonemap;
    });

    uiModel.debugchannel.subscribe( debugchannel => {
        state.renderingParameters.debugOutput = debugchannel;
    });

    uiModel.skinningEnabled.subscribe( skinningEnabled => {
        state.renderingParameters.skinning = skinningEnabled;
    });

    uiModel.exposurecompensation.subscribe( exposurecompensation => {
        state.renderingParameters.exposure = Math.pow(2, exposurecompensation);
    });

    uiModel.morphingEnabled.subscribe( morphingEnabled => {
        state.renderingParameters.morphing = morphingEnabled;
    });

    uiModel.iblEnabled.subscribe( iblEnabled => {
        state.renderingParameters.useIBL = iblEnabled;
    });

    uiModel.punctualLightsEnabled.subscribe( punctualLightsEnabled => {
        state.renderingParameters.usePunctual = punctualLightsEnabled;
    });

    uiModel.environmentEnabled.subscribe( environmentEnabled => {
        state.renderingParameters.environmentBackground = environmentEnabled;
    });

    uiModel.environmentRotation.subscribe( environmentRotation => {
        switch (environmentRotation)
        {
        case "+Z":
            state.renderingParameters.environmentRotation = 90.0;
            break;
        case "-X":
            state.renderingParameters.environmentRotation = 180.0;
            break;
        case "-Z":
            state.renderingParameters.environmentRotation = 270.0;
            break;
        case "+X":
            state.renderingParameters.environmentRotation = 0.0;
            break;
        }
    });

    uiModel.clearColor.subscribe( clearColor => {
        state.renderingParameters.clearColor = clearColor;
    });

    uiModel.animationPlay.subscribe( animationPlay => {
        if(animationPlay)
        {
            state.animationTimer.unpause();
        }
        else
        {
            state.animationTimer.pause();
        }
    })

    uiModel.hdr.subscribe( hdrFile => {
        loadEnvironment(hdrFile, view).then( (environment) => {
            state.environment = environment;
        });
    });

    uiModel.attachGltfLoaded(gltfLoadedMulticast);
    uiModel.updateStatistics(statisticsUpdateObservable);
    gltfLoadedMulticast.connect();

    const input = new gltfInput(canvas);
    input.setupGlobalInputBindings(document);
    input.setupCanvasInputBindings(canvas);
    input.onRotate = (deltaX, deltaY) =>
    {
        state.userCamera.rotate(deltaX, deltaY);
        state.userCamera.updatePosition();
    };
    input.onPan = (deltaX, deltaY) =>
    {
        state.userCamera.pan(deltaX, deltaY);
        state.userCamera.updatePosition();
    };
    input.onZoom = (delta) =>
    {
        state.userCamera.zoomIn(delta);
        state.userCamera.updatePosition();
    };

    await view.startRendering(state, canvas);
}

export { main };
<commit_msg>fix cameraIndex reset<commit_after>import { gltfInput } from './input.js';

import { GltfView, computePrimitiveCentroids, loadGltf, loadEnvironment, initKtxLib, initDracoLib } from 'gltf-sample-viewer';

import { UIModel } from './logic/uimodel.js';
import { app } from './ui/ui.js';
import { Observable, Subject, from, merge } from 'rxjs';
import { mergeMap, filter, map, multicast } from 'rxjs/operators';
import { gltfModelPathProvider } from './model_path_provider.js';

async function main()
{
    const canvas = document.getElementById("canvas");
    const context = canvas.getContext("webgl2", { alpha: false, antialias: true });
    const ui = document.getElementById("app");
    const view = new GltfView(context, ui);
    const state = view.createState();

    initDracoLib();
    initKtxLib(view);

    loadEnvironment("assets/environments/footprint_court_512.hdr", view).then( (environment) => {
        state.environment = environment;
    });
    const pathProvider = new gltfModelPathProvider('assets/models/2.0/model-index.json');
    await pathProvider.initialize();

    const uiModel = await new UIModel(app, pathProvider, state);

    // whenever a new model is selected, load it and when complete pass the loaded gltf
    // into a stream back into the UI
    const subject = new Subject();
    const gltfLoadedMulticast = uiModel.model.pipe(
        mergeMap( (model) =>
        {
            return from(loadGltf(model.mainFile, view, model.additionalFiles).then( (gltf) => {
                state.gltf = gltf;
                const defaultScene = state.gltf.scene;
                state.sceneIndex = defaultScene === undefined ? 0 : defaultScene;
                state.cameraIndex = undefined;
                const scene = state.gltf.scenes[state.sceneIndex];
                scene.applyTransformHierarchy(state.gltf);
                computePrimitiveCentroids(state.gltf);
                state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
                state.userCamera.updatePosition();
                state.animationIndices = [0];
                state.animationTimer.start();
                return state;
            })
            );
        }),
        // transform gltf loaded observable to multicast observable to avoid multiple execution with multiple subscriptions
        multicast(subject)
    );

    const sceneChangedObservable = uiModel.scene.pipe(map( newSceneIndex => {
        state.sceneIndex = newSceneIndex;
        const scene = state.gltf.scenes[state.sceneIndex];
        scene.applyTransformHierarchy(state.gltf);
        computePrimitiveCentroids(state.gltf);
        state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
        state.userCamera.updatePosition();
    }));

    const statisticsUpdateObservableTemp = merge(
        gltfLoadedMulticast,
        sceneChangedObservable
    );

    const statisticsUpdateObservable = statisticsUpdateObservableTemp.pipe(
        map( (_) => view.gatherStatistics(state) )
    );

    uiModel.camera.pipe(filter(camera => camera === "User Camera")).subscribe( () => {
        state.cameraIndex = undefined;
    });
    uiModel.camera.pipe(filter(camera => camera !== "User Camera")).subscribe( camera => {
        state.cameraIndex = camera;
    });

    uiModel.variant.subscribe( variant => {
        state.variant = variant;
    });

    uiModel.tonemap.subscribe( tonemap => {
        state.renderingParameters.toneMap = tonemap;
    });

    uiModel.debugchannel.subscribe( debugchannel => {
        state.renderingParameters.debugOutput = debugchannel;
    });

    uiModel.skinningEnabled.subscribe( skinningEnabled => {
        state.renderingParameters.skinning = skinningEnabled;
    });

    uiModel.exposurecompensation.subscribe( exposurecompensation => {
        state.renderingParameters.exposure = Math.pow(2, exposurecompensation);
    });

    uiModel.morphingEnabled.subscribe( morphingEnabled => {
        state.renderingParameters.morphing = morphingEnabled;
    });

    uiModel.iblEnabled.subscribe( iblEnabled => {
        state.renderingParameters.useIBL = iblEnabled;
    });

    uiModel.punctualLightsEnabled.subscribe( punctualLightsEnabled => {
        state.renderingParameters.usePunctual = punctualLightsEnabled;
    });

    uiModel.environmentEnabled.subscribe( environmentEnabled => {
        state.renderingParameters.environmentBackground = environmentEnabled;
    });

    uiModel.environmentRotation.subscribe( environmentRotation => {
        switch (environmentRotation)
        {
        case "+Z":
            state.renderingParameters.environmentRotation = 90.0;
            break;
        case "-X":
            state.renderingParameters.environmentRotation = 180.0;
            break;
        case "-Z":
            state.renderingParameters.environmentRotation = 270.0;
            break;
        case "+X":
            state.renderingParameters.environmentRotation = 0.0;
            break;
        }
    });

    uiModel.clearColor.subscribe( clearColor => {
        state.renderingParameters.clearColor = clearColor;
    });

    uiModel.animationPlay.subscribe( animationPlay => {
        if(animationPlay)
        {
            state.animationTimer.unpause();
        }
        else
        {
            state.animationTimer.pause();
        }
    })

    uiModel.hdr.subscribe( hdrFile => {
        loadEnvironment(hdrFile, view).then( (environment) => {
            state.environment = environment;
        });
    });

    uiModel.attachGltfLoaded(gltfLoadedMulticast);
    uiModel.updateStatistics(statisticsUpdateObservable);
    gltfLoadedMulticast.connect();

    const input = new gltfInput(canvas);
    input.setupGlobalInputBindings(document);
    input.setupCanvasInputBindings(canvas);
    input.onRotate = (deltaX, deltaY) =>
    {
        state.userCamera.rotate(deltaX, deltaY);
        state.userCamera.updatePosition();
    };
    input.onPan = (deltaX, deltaY) =>
    {
        state.userCamera.pan(deltaX, deltaY);
        state.userCamera.updatePosition();
    };
    input.onZoom = (delta) =>
    {
        state.userCamera.zoomIn(delta);
        state.userCamera.updatePosition();
    };

    await view.startRendering(state, canvas);
}

export { main };
<|endoftext|>


<commit_before>import Id from 'septima-utils/id';
import Ui from 'kenga/utils';
import Container from 'kenga/container';

class Split extends Container {
    constructor(orientation) {
        if (arguments.length < 1)
            orientation = Ui.Orientation.HORIZONTAL;

        super();

        const self = this;

        let dividerSize = 10;

        let firstWidget;
        let secondWidget;

        let oneTouchExpandable;
        let dividerLocation = 0;

        this.element.classList.add('p-split');

        this.element.id = `p-${Id.generate()}`;

        const style = document.createElement('style');
        self.element.appendChild(style);

        const superAdd = this.add;
        const superRemove = this.remove;

        function formatChildren() {
            if (orientation === Ui.Orientation.HORIZONTAL) {
                style.innerHTML =
                    // firstWidget
                    // secondWidget
                    `div#${self.element.id} > .p-widget:nth-child(2) {position: absolute;left: ${0}px;top: ${0}px;bottom: ${0}px;width: ${dividerLocation}px;}div#${self.element.id} > .p-widget:last-child {position: absolute;right: ${0}px;top: ${0}px;bottom: ${0}px;left: ${dividerLocation + dividerSize}px;}`;
                divider.style.top = '0px';
                divider.style.bottom = '0px';
                divider.style.width = `${dividerSize}px`;
                divider.style.left = `${dividerLocation}px`;
                divider.style.height = '';
                divider.style.right = '';
            } else {
                style.innerHTML =
                    // firstWidget
                    // secondWidget
                    `div#${self.element.id} > .p-widget:nth-child(2) {position: absolute;left: ${0}px;right: ${0}px;top: ${0}px;height: ${dividerLocation}px;}div#${self.element.id} > .p-widget:last-child {position: absolute;left: ${0}px;right: ${0}px;bottom: ${0}px;top: ${dividerLocation + dividerSize}px;}`;
                divider.style.left = '0px';
                divider.style.right = '0px';
                divider.style.height = `${dividerSize}px`;
                divider.style.top = `${dividerLocation}px`;
                divider.style.width = '';
                divider.style.bottom = '';
            }
        }

        const divider = document.createElement('div');
        divider.classList.add('p-split-divider');
        divider.style.position = 'absolute';
        this.element.appendChild(divider);

        ((() => {
            let mouseDownAt = null;
            let mouseDownDividerAt = null;
            let onMouseUp = null;
            let onMouseMove = null;
            Ui.on(divider, Ui.Events.MOUSEDOWN, event => {
                if (event.button === 0) {
                    event.stopPropagation();
                    if (orientation === Ui.Orientation.HORIZONTAL) {
                        mouseDownAt = event.clientX;
                    } else {
                        mouseDownAt = event.clientY;
                    }
                    mouseDownDividerAt = dividerLocation;
                    if (!onMouseUp) {
                        onMouseUp = Ui.on(document, Ui.Events.MOUSEUP, event => {
                            event.stopPropagation();
                            if (onMouseUp) {
                                onMouseUp.removeHandler();
                                onMouseUp = null;
                            }
                            if (onMouseMove) {
                                onMouseMove.removeHandler();
                                onMouseMove = null;
                            }
                        });
                    }
                    if (!onMouseMove) {
                        onMouseMove = Ui.on(document, Ui.Events.MOUSEMOVE, event => {
                            event.stopPropagation();
                            let mouseDiff;
                            if (orientation === Ui.Orientation.HORIZONTAL) {
                                mouseDiff = event.clientX - mouseDownAt;
                            } else {
                                mouseDiff = event.clientY - mouseDownAt;
                            }
                            self.dividerLocation = mouseDownDividerAt + mouseDiff;
                        });
                    }
                }
            });
        })());

        formatChildren();

        function checkAdd(w) {
            if (!firstWidget) {
                firstWidget = w;
                self.element.insertBefore(firstWidget.element, divider);
            } else {
                if (secondWidget) {
                    superRemove(secondWidget);
                }
                secondWidget = w;
                self.element.appendChild(secondWidget.element);
            }
        }

        function add(w, beforeIndex) {
            if (w) {
                if (w.parent === self)
                    throw 'A widget already added to this container';
                superAdd(w, beforeIndex);
                checkAdd(w);
            }
        }
        Object.defineProperty(this, 'add', {
            get: function() {
                return add;
            }
        });

        function checkRemove(w) {
            if (w === firstWidget) {
                firstWidget = null;
            }
            if (w === secondWidget) {
                secondWidget = null;
            }
        }

        function remove(w) {
            const removed = superRemove(w);
            checkRemove(removed);
            return removed;
        }
        Object.defineProperty(this, 'remove', {
            get: function() {
                return remove;
            }
        });

        const superClear = this.clear;

        function clear() {
            firstWidget = null;
            secondWidget = null;
            superClear();
        }
        Object.defineProperty(this, 'clear', {
            get: function() {
                return clear;
            }
        });

        Object.defineProperty(this, "orientation", {
            get: function() {
                return orientation;
            },
            set: function(aValue) {
                if (orientation !== aValue) {
                    orientation = aValue;
                    formatChildren();
                }
            }
        });
        Object.defineProperty(this, 'firstWidget', {
            get: function() {
                return firstWidget;
            },
            set: function(aFirstWidget) {
                if (firstWidget !== aFirstWidget) {
                    if (firstWidget) {
                        superRemove(firstWidget);
                    }
                    firstWidget = aFirstWidget;
                    if (firstWidget) {
                        superAdd(firstWidget);
                        self.element.insertBefore(firstWidget.element, divider);
                    }
                }
            }
        });
        Object.defineProperty(this, 'secondWidget', {
            get: function() {
                return secondWidget;
            },
            set: function(aSecondWidget) {
                if (secondWidget !== aSecondWidget) {
                    if (secondWidget) {
                        superRemove(secondWidget);
                    }
                    secondWidget = aSecondWidget;
                    if (secondWidget) {
                        superAdd(secondWidget);
                        self.element.appendChild(secondWidget.element);
                    }
                }
            }
        });
        Object.defineProperty(this, 'dividerLocation', {
            get: function() {
                return dividerLocation;
            },
            set: function(aValue) {
                if (dividerLocation !== aValue) {
                    const dividerLimit = (orientation === Ui.Orientation.HORIZONTAL ? self.element.offsetWidth : self.element.offsetHeight) - dividerSize;
                    if (aValue >= 0 && aValue <= dividerLimit) {
                        dividerLocation = aValue;
                        formatChildren();
                    }
                }
            }
        });
        Object.defineProperty(this, 'dividerSize', {
            get: function() {
                return dividerSize;
            },
            set: function(aValue) {
                if (dividerSize !== aValue) {
                    dividerSize = aValue;
                    formatChildren();
                }
            }
        });
        Object.defineProperty(this, 'oneTouchExpandable', {
            get: function() {
                return oneTouchExpandable;
            },
            set: function(aValue) {
                if (oneTouchExpandable !== aValue) {
                    oneTouchExpandable = aValue;
                }
            }
        });

        function ajustLeft(w, aValue) {}
        Object.defineProperty(this, 'ajustLeft', {
            get: function() {
                return ajustLeft;
            }
        });

        function ajustWidth(w, aValue) {}
        Object.defineProperty(this, 'ajustWidth', {
            get: function() {
                return ajustWidth;
            }
        });

        function ajustTop(w, aValue) {}
        Object.defineProperty(this, 'ajustTop', {
            get: function() {
                return ajustTop;
            }
        });

        function ajustHeight(w, aValue) {}
        Object.defineProperty(this, 'ajustHeight', {
            get: function() {
                return ajustHeight;
            }
        });
    }
}

export default Split;<commit_msg>Insuarance<commit_after>import Id from 'septima-utils/id';
import Ui from 'kenga/utils';
import Container from 'kenga/container';

class Split extends Container {
    constructor(orientation) {
        if (arguments.length < 1)
            orientation = Ui.Orientation.HORIZONTAL;

        super();

        const self = this;

        let dividerSize = 10;

        let firstWidget;
        let secondWidget;

        let oneTouchExpandable;
        let dividerLocation = 0;

        this.element.classList.add('p-split');

        this.element.id = `p-${Id.generate()}`;

        const style = document.createElement('style');
        self.element.appendChild(style);

        const superAdd = this.add;
        const superRemove = this.remove;

        function formatChildren() {
            if (orientation === Ui.Orientation.HORIZONTAL) {
                style.innerHTML =
                    // firstWidget
                    // secondWidget
                    `div#${self.element.id} > .p-widget:nth-child(2) {position: absolute;left: ${0}px;top: ${0}px;bottom: ${0}px;width: ${dividerLocation}px;}div#${self.element.id} > .p-widget:last-child {position: absolute;right: ${0}px;top: ${0}px;bottom: ${0}px;left: ${dividerLocation + dividerSize}px;}`;
                divider.style.top = '0px';
                divider.style.bottom = '0px';
                divider.style.width = `${dividerSize}px`;
                divider.style.left = `${dividerLocation}px`;
                divider.style.height = '';
                divider.style.right = '';
            } else {
                style.innerHTML =
                    // firstWidget
                    // secondWidget
                    `div#${self.element.id} > .p-widget:nth-child(2) {position: absolute;left: ${0}px;right: ${0}px;top: ${0}px;height: ${dividerLocation}px;}div#${self.element.id} > .p-widget:last-child {position: absolute;left: ${0}px;right: ${0}px;bottom: ${0}px;top: ${dividerLocation + dividerSize}px;}`;
                divider.style.left = '0px';
                divider.style.right = '0px';
                divider.style.height = `${dividerSize}px`;
                divider.style.top = `${dividerLocation}px`;
                divider.style.width = '';
                divider.style.bottom = '';
            }
        }

        const divider = document.createElement('div');
        divider.classList.add('p-split-divider');
        divider.style.position = 'absolute';
        this.element.appendChild(divider);

        ((() => {
            let mouseDownAt = null;
            let mouseDownDividerAt = null;
            let onMouseUp = null;
            let onMouseMove = null;
            Ui.on(divider, Ui.Events.MOUSEDOWN, event => {
                if (event.button === 0) {
                    event.stopPropagation();
                    if (orientation === Ui.Orientation.HORIZONTAL) {
                        mouseDownAt = event.clientX;
                    } else {
                        mouseDownAt = event.clientY;
                    }
                    mouseDownDividerAt = dividerLocation;
                    if (!onMouseUp) {
                        onMouseUp = Ui.on(document, Ui.Events.MOUSEUP, event => {
                            event.stopPropagation();
                            if (onMouseUp) {
                                onMouseUp.removeHandler();
                                onMouseUp = null;
                            }
                            if (onMouseMove) {
                                onMouseMove.removeHandler();
                                onMouseMove = null;
                            }
                        });
                    }
                    if (!onMouseMove) {
                        onMouseMove = Ui.on(document, Ui.Events.MOUSEMOVE, event => {
                            event.stopPropagation();
                            let mouseDiff;
                            if (orientation === Ui.Orientation.HORIZONTAL) {
                                mouseDiff = event.clientX - mouseDownAt;
                            } else {
                                mouseDiff = event.clientY - mouseDownAt;
                            }
                            self.dividerLocation = mouseDownDividerAt + mouseDiff;
                        });
                    }
                }
            });
        })());

        formatChildren();

        function checkAdd(w) {
            if (!firstWidget) {
                firstWidget = w;
                self.element.insertBefore(firstWidget.element, divider);
            } else {
                if (secondWidget) {
                    superRemove(secondWidget);
                }
                secondWidget = w;
                self.element.appendChild(secondWidget.element);
            }
        }

        function add(w, beforeIndex) {
            if (w) {
                if (w.parent === self)
                    throw 'A widget already added to this container';
                superAdd(w, beforeIndex);
                checkAdd(w);
            }
        }
        Object.defineProperty(this, 'add', {
            get: function() {
                return add;
            }
        });

        function checkRemove(w) {
            if (w === firstWidget) {
                firstWidget = null;
            }
            if (w === secondWidget) {
                secondWidget = null;
            }
        }

        function remove(w) {
            const removed = superRemove(w);
            checkRemove(removed);
            return removed;
        }
        Object.defineProperty(this, 'remove', {
            get: function() {
                return remove;
            }
        });

        const superClear = this.clear;

        function clear() {
            firstWidget = null;
            secondWidget = null;
            superClear();
        }
        Object.defineProperty(this, 'clear', {
            get: function() {
                return clear;
            }
        });

        Object.defineProperty(this, 'orientation', {
            get: function() {
                return orientation;
            },
            set: function(aValue) {
                if (orientation !== aValue) {
                    orientation = aValue;
                    formatChildren();
                }
            }
        });
        Object.defineProperty(this, 'firstWidget', {
            get: function() {
                return firstWidget;
            },
            set: function(aFirstWidget) {
                if (firstWidget !== aFirstWidget) {
                    if (firstWidget) {
                        superRemove(firstWidget);
                    }
                    firstWidget = aFirstWidget;
                    if (firstWidget) {
                        superAdd(firstWidget);
                        self.element.insertBefore(firstWidget.element, divider);
                    }
                }
            }
        });
        Object.defineProperty(this, 'secondWidget', {
            get: function() {
                return secondWidget;
            },
            set: function(aSecondWidget) {
                if (secondWidget !== aSecondWidget) {
                    if (secondWidget) {
                        superRemove(secondWidget);
                    }
                    secondWidget = aSecondWidget;
                    if (secondWidget) {
                        superAdd(secondWidget);
                        self.element.appendChild(secondWidget.element);
                    }
                }
            }
        });
        Object.defineProperty(this, 'dividerLocation', {
            get: function() {
                return dividerLocation;
            },
            set: function(aValue) {
                if (dividerLocation !== aValue) {
                    const dividerLimit = (orientation === Ui.Orientation.HORIZONTAL ? self.element.offsetWidth : self.element.offsetHeight) - dividerSize;
                    if (aValue >= 0 && aValue <= dividerLimit) {
                        dividerLocation = aValue;
                        formatChildren();
                    }
                }
            }
        });
        Object.defineProperty(this, 'dividerSize', {
            get: function() {
                return dividerSize;
            },
            set: function(aValue) {
                if (dividerSize !== aValue) {
                    dividerSize = aValue;
                    formatChildren();
                }
            }
        });
        Object.defineProperty(this, 'oneTouchExpandable', {
            get: function() {
                return oneTouchExpandable;
            },
            set: function(aValue) {
                if (oneTouchExpandable !== aValue) {
                    oneTouchExpandable = aValue;
                }
            }
        });

        function ajustLeft(w, aValue) {}
        Object.defineProperty(this, 'ajustLeft', {
            get: function() {
                return ajustLeft;
            }
        });

        function ajustWidth(w, aValue) {}
        Object.defineProperty(this, 'ajustWidth', {
            get: function() {
                return ajustWidth;
            }
        });

        function ajustTop(w, aValue) {}
        Object.defineProperty(this, 'ajustTop', {
            get: function() {
                return ajustTop;
            }
        });

        function ajustHeight(w, aValue) {}
        Object.defineProperty(this, 'ajustHeight', {
            get: function() {
                return ajustHeight;
            }
        });
    }
}

export default Split;<|endoftext|>


<commit_before>import { Address4, Address6 } from 'ip-address';
import url from 'url';

function capitaliseFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function addLine(name, rule) {
    let contents = '';

    if (rule && Object.prototype.toString.call(rule) === '[object Array]') {
        rule.forEach((item) => {
            contents += addLine(name, item);
        });
    } else {
        contents += `${capitaliseFirstLetter(name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase())}: ${rule}\n`;
    }

    return contents;
}

function generatePoliceItem(item, index) {
    if (!item.userAgent || (item.userAgent && item.userAgent.length === 0)) {
        throw new Error('Each `police` should have single string `userAgent` option');
    }

    let contents = '';

    if (index !== 0) {
        contents += '\n';
    }

    contents += addLine('User-agent', item.userAgent);

    if (item.allow) {
        contents += addLine('Allow', item.allow);
    }

    if (item.disallow) {
        contents += addLine('Disallow', item.disallow);
    }

    if (item.crawlDelay && typeof item.crawlDelay !== 'number' && !isFinite(item.crawlDelay)) {
        throw new Error('Option `crawlDelay` must be integer or float');
    }

    if (item.crawlDelay) {
        contents += addLine('Crawl-delay', item.crawlDelay);
    }

    if (item.cleanParam) {
        contents += addLine('Clean-param', item.cleanParam);
    }

    return contents;
}

export default function ({
    configFile = null,
    policy = [{
        allow: '/',
        cleanParam: null,
        crawlDelay: null,
        userAgent: '*'
    }],
    sitemap = null,
    host = null
} = {}) {
    let options = {
        host,
        policy,
        sitemap
    };

    let starter = Promise.resolve();

    if (configFile) {
        starter = new Promise((resolve) => {
            // eslint-disable-next-line global-require, import/no-dynamic-require
            const optionsFromConfigFile = require(configFile);

            options = Object.assign(
                {},
                options,
                optionsFromConfigFile.default
                    ? optionsFromConfigFile.default
                    : optionsFromConfigFile
            );

            return resolve();
        });
    }

    return starter
        .then(() => new Promise((resolve) => {
            if (!Array.isArray(options.policy)) {
                throw new Error('Options `policy` must be array');
            }

            if (options.host) {
                if (typeof options.host !== 'string') {
                    throw new Error('Options `host` must be `string` and single');
                }

                const address4 = new Address4(options.host);
                const address6 = new Address6(options.host);

                if (address4.isValid() || address6.isValid()) {
                    throw new Error('Options `host` should be not IP address');
                }
            }

            let contents = '';

            options.policy.forEach((item, index) => {
                contents += generatePoliceItem(item, index);
            });

            if (options.sitemap) {
                contents += addLine('Sitemap', options.sitemap);
            }

            if (options.host) {
                let normalizeHost = options.host;

                if (normalizeHost.search(/^http[s]?:\/\//) === -1) {
                    normalizeHost = `http://${host}`;
                }

                const parsedURL = url.parse(normalizeHost, false, true);

                if (!parsedURL.host) {
                    throw new Error('Option `host` does not contain correct host');
                }

                const formattedHost = parsedURL.protocol && parsedURL.protocol === 'https:'
                    ? url.format({
                        host: parsedURL.host,
                        protocol: parsedURL.protocol
                    })
                    : parsedURL.host;

                contents += addLine('Host', formattedHost);
            }

            return resolve(contents);
        }));
}
<commit_msg>Chore: accounted errors before process creating `robots.txt`.<commit_after>import { Address4, Address6 } from 'ip-address';
import url from 'url';

function capitaliseFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function addLine(name, rule) {
    let contents = '';

    if (rule && Object.prototype.toString.call(rule) === '[object Array]') {
        rule.forEach((item) => {
            contents += addLine(name, item);
        });
    } else {
        contents += `${capitaliseFirstLetter(name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase())}: ${rule}\n`;
    }

    return contents;
}

function generatePoliceItem(item, index) {
    let contents = '';

    if (index !== 0) {
        contents += '\n';
    }

    contents += addLine('User-agent', item.userAgent);

    if (item.allow) {
        contents += addLine('Allow', item.allow);
    }

    if (item.disallow) {
        contents += addLine('Disallow', item.disallow);
    }

    if (item.crawlDelay) {
        contents += addLine('Crawl-delay', item.crawlDelay);
    }

    if (item.cleanParam) {
        contents += addLine('Clean-param', item.cleanParam);
    }

    return contents;
}

export default function ({
    configFile = null,
    policy = [{
        allow: '/',
        cleanParam: null,
        crawlDelay: null,
        userAgent: '*'
    }],
    sitemap = null,
    host = null
} = {}) {
    let options = {
        host,
        policy,
        sitemap
    };

    let starter = Promise.resolve();

    if (configFile) {
        starter = new Promise((resolve) => {
            // eslint-disable-next-line global-require, import/no-dynamic-require
            const optionsFromConfigFile = require(configFile);

            options = Object.assign(
                {},
                options,
                optionsFromConfigFile.default
                    ? optionsFromConfigFile.default
                    : optionsFromConfigFile
            );

            return resolve();
        });
    }

    return starter
        .then(() => new Promise((resolve) => {
            if (options.policy) {
                if (!Array.isArray(options.policy)) {
                    throw new Error('Options `policy` must be array');
                }

                options.policy.forEach((item) => {
                    if (!item.userAgent || (item.userAgent && item.userAgent.length === 0)) {
                        throw new Error('Each `police` should have single string `userAgent` option');
                    }

                    if (item.crawlDelay && typeof item.crawlDelay !== 'number' && !isFinite(item.crawlDelay)) {
                        throw new Error('Option `crawlDelay` must be integer or float');
                    }
                });
            }

            if (options.host) {
                if (typeof options.host !== 'string') {
                    throw new Error('Options `host` must be `string` and single');
                }

                const address4 = new Address4(options.host);
                const address6 = new Address6(options.host);

                if (address4.isValid() || address6.isValid()) {
                    throw new Error('Options `host` should be not IP address');
                }
            }

            let contents = '';

            options.policy.forEach((item, index) => {
                contents += generatePoliceItem(item, index);
            });

            if (options.sitemap) {
                contents += addLine('Sitemap', options.sitemap);
            }

            if (options.host) {
                let normalizeHost = options.host;

                if (normalizeHost.search(/^http[s]?:\/\//) === -1) {
                    normalizeHost = `http://${host}`;
                }

                const parsedURL = url.parse(normalizeHost, false, true);

                if (!parsedURL.host) {
                    throw new Error('Option `host` does not contain correct host');
                }

                const formattedHost = parsedURL.protocol && parsedURL.protocol === 'https:'
                    ? url.format({
                        host: parsedURL.host,
                        protocol: parsedURL.protocol
                    })
                    : parsedURL.host;

                contents += addLine('Host', formattedHost);
            }

            return resolve(contents);
        }));
}
<|endoftext|>