<commit_before>const sfw = require('../lib')

const path = require('path')
const fs = require('fs-extra')

describe('entry point', function () {
  let subs, fixtureDir, watchDir, mainLogFile, workerLogFile

  beforeEach(async function () {
    subs = []

    fixtureDir = path.join(__dirname, 'fixture')
    watchDir = path.join(fixtureDir, 'watched')

    mainLogFile = path.join(fixtureDir, 'main.test.log')
    workerLogFile = path.join(fixtureDir, 'worker.test.log')

    await fs.mkdir(watchDir)
  })

  afterEach(async function () {
    if (this.currentTest.state === 'failed') {
      const [mainLog, workerLog] = await Promise.all(
        [mainLogFile, workerLogFile].map(fname => fs.readFile(fname, {encoding: 'utf8'}).catch(() => ''))
      )

      console.log(`main log:\n${mainLog}`)
      console.log(`worker log:\n${workerLog}`)
    }

    const promises = [mainLogFile, workerLogFile].map(fname => fs.unlink(fname).catch(() => {}))
    promises.push(fs.remove(watchDir))
    promises.push(...subs.map(sub => sub.unwatch()))

    await Promise.all(promises)
  })

  describe('configuration', function () {
    it('validates its arguments', async function () {
      await assert.isRejected(sfw.configure(), /requires an option object/)
    })

    it('configures the main thread logger', async function () {
      await sfw.configure({mainLogFile})

      const contents = await fs.readFile(mainLogFile)
      assert.match(contents, /FileLogger opened/)
    })

    it('configures the worker thread logger', async function () {
      await sfw.configure({workerLogFile})

      const contents = await fs.readFile(workerLogFile)
      assert.match(contents, /FileLogger opened/)
    })
  })

  describe('watching a directory', function () {
    beforeEach(async function () {
      await sfw.configure({mainLogFile, workerLogFile})
    })

    it('begins receiving events within that directory', async function () {
      let error = null
      const events = []

      subs.push(await sfw.watch(watchDir, (err, es) => {
        error = err
        events.push(...es)
      }))

      await fs.writeFile(path.join(watchDir, 'file.txt'), 'indeed')

      await until('an event arrives', () => events.length > 0)
      assert.isNull(error)
    })

    it('can watch multiple directories at once and dispatch events appropriately', async function () {
      let errors = []
      const eventsA = []
      const eventsB = []

      const watchDirA = path.join(watchDir, 'dir_a')
      const watchDirB = path.join(watchDir, 'dir_b')
      await Promise.all(
        [watchDirA, watchDirB].map(subdir => fs.mkdir(subdir))
      )

      subs.push(await sfw.watch(watchDirA, (err, es) => {
        errors.push(err)
        eventsA.push(...es)
      }))
      subs.push(await sfw.watch(watchDirB, (err, es) => {
        errors.push(err)
        eventsB.push(...es)
      }))

      const fileA = path.join(watchDirA, 'a.txt')
      await fs.writeFile(fileA, 'file a')
      await until('watcher A picks up its event', () => eventsA.some(event => event.oldPath === fileA))

      const fileB = path.join(watchDirB, 'b.txt')
      await fs.writeFile(fileB, 'file b')
      await until('watcher B picks up its event', () => eventsB.some(event => event.oldPath === fileB))

      // Assert that the streams weren't crossed
      assert.isTrue(errors.every(err => err === null))
      assert.isTrue(eventsA.every(event => event.oldPath !== fileB))
      assert.isTrue(eventsB.every(event => event.oldPath !== fileA))
    })

    describe('events', function () {
      it('when a file is created')
      it('when a file is modified')
      it('when a file is renamed')
      it('when a file is deleted')
      it('when a directory is created')
      it('when a directory is renamed')
      it('when a directory is deleted')
    })
  })

  describe('unwatching a directory', function () {
    it('unwatches a previously watched directory')
    it('is a no-op if the directory is not being watched')
  })
})
<commit_msg>Basic unwatch() test<commit_after>const sfw = require('../lib')

const path = require('path')
const fs = require('fs-extra')

describe('entry point', function () {
  let subs, fixtureDir, watchDir, mainLogFile, workerLogFile

  beforeEach(async function () {
    subs = []

    fixtureDir = path.join(__dirname, 'fixture')
    watchDir = path.join(fixtureDir, 'watched')

    mainLogFile = path.join(fixtureDir, 'main.test.log')
    workerLogFile = path.join(fixtureDir, 'worker.test.log')

    await fs.mkdir(watchDir)
  })

  afterEach(async function () {
    if (this.currentTest.state === 'failed') {
      const [mainLog, workerLog] = await Promise.all(
        [mainLogFile, workerLogFile].map(fname => fs.readFile(fname, {encoding: 'utf8'}).catch(() => ''))
      )

      console.log(`main log:\n${mainLog}`)
      console.log(`worker log:\n${workerLog}`)
    }

    const promises = [mainLogFile, workerLogFile].map(fname => fs.unlink(fname).catch(() => {}))
    promises.push(fs.remove(watchDir))
    promises.push(...subs.map(sub => sub.unwatch()))

    await Promise.all(promises)
  })

  describe('configuration', function () {
    it('validates its arguments', async function () {
      await assert.isRejected(sfw.configure(), /requires an option object/)
    })

    it('configures the main thread logger', async function () {
      await sfw.configure({mainLogFile})

      const contents = await fs.readFile(mainLogFile)
      assert.match(contents, /FileLogger opened/)
    })

    it('configures the worker thread logger', async function () {
      await sfw.configure({workerLogFile})

      const contents = await fs.readFile(workerLogFile)
      assert.match(contents, /FileLogger opened/)
    })
  })

  describe('watching a directory', function () {
    beforeEach(async function () {
      await sfw.configure({mainLogFile, workerLogFile})
    })

    it('begins receiving events within that directory', async function () {
      let error = null
      const events = []

      subs.push(await sfw.watch(watchDir, (err, es) => {
        error = err
        events.push(...es)
      }))

      await fs.writeFile(path.join(watchDir, 'file.txt'), 'indeed')

      await until('an event arrives', () => events.length > 0)
      assert.isNull(error)
    })

    it('can watch multiple directories at once and dispatch events appropriately', async function () {
      let errors = []
      const eventsA = []
      const eventsB = []

      const watchDirA = path.join(watchDir, 'dir_a')
      const watchDirB = path.join(watchDir, 'dir_b')
      await Promise.all(
        [watchDirA, watchDirB].map(subdir => fs.mkdir(subdir))
      )

      subs.push(await sfw.watch(watchDirA, (err, es) => {
        errors.push(err)
        eventsA.push(...es)
      }))
      subs.push(await sfw.watch(watchDirB, (err, es) => {
        errors.push(err)
        eventsB.push(...es)
      }))

      const fileA = path.join(watchDirA, 'a.txt')
      await fs.writeFile(fileA, 'file a')
      await until('watcher A picks up its event', () => eventsA.some(event => event.oldPath === fileA))

      const fileB = path.join(watchDirB, 'b.txt')
      await fs.writeFile(fileB, 'file b')
      await until('watcher B picks up its event', () => eventsB.some(event => event.oldPath === fileB))

      // Assert that the streams weren't crossed
      assert.isTrue(errors.every(err => err === null))
      assert.isTrue(eventsA.every(event => event.oldPath !== fileB))
      assert.isTrue(eventsB.every(event => event.oldPath !== fileA))
    })

    describe('events', function () {
      it('when a file is created')
      it('when a file is modified')
      it('when a file is renamed')
      it('when a file is deleted')
      it('when a directory is created')
      it('when a directory is renamed')
      it('when a directory is deleted')
    })
  })

  describe('unwatching a directory', function () {
    beforeEach(async function () {
      await sfw.configure({mainLogFile, workerLogFile})
    })

    it('unwatches a previously watched directory', async function () {
      let error = null
      const events = []

      const sub = await sfw.watch(watchDir, (err, es) => {
        error = err
        events.push(...es)
      })
      subs.push(sub)

      const filePath = path.join(watchDir, 'file.txt')
      await fs.writeFile(filePath, 'original')

      await until('the event arrives', () => events.some(event => event.oldPath === filePath))
      const eventCount = events.length
      assert.isNull(error)

      await sub.unwatch()

      await fs.writeFile(filePath, 'the modification')

      // Give the modification event a chance to arrive.
      // Not perfect, but adequate.
      await new Promise(resolve => setTimeout(resolve, 100))

      assert.lengthOf(events, eventCount)
    })

    it('is a no-op if the directory is not being watched')
  })
})
<|endoftext|>


<commit_before>/*
Copyright (C) 2016 by Joel Kozikowski

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */

"use strict";

var metaModel = require('../meta/meta-model.js');
var winston = require('winston');

(function(meta){

	var warnCount = 0;
	var errorCount = 0;

	meta.validate = function(metaModel) {

		warnCount = 0;
		errorCount = 0;

		winston.info("Validating model...");

		var logWarn = function(typeName, metaObj, msg) {
			let msg = "WARN: " + typeName + " " + metaObj._name + msg;
			winston.warn(msg);
			warnCount++;
		};

		var logError = function(typeName, metaObj, msg) {
			let msg = "ERROR: " + typeName + " " + metaObj._name + msg;
			winston.error(msg);
			errorCount++;
		};

		var isMissing = function(obj) {
			return (obj === undefined || obj === null ||
					(typeof(obj) === "string" && obj.length === 0));
		};

		metaModel.classes.forEach(function(metaClass) {

			if (metaClass.getPackageName().length === 0) {
				logWarn("Class", metaClass, " has no package specified. Code will be in root of project.");
			}

			if (metaClass._stereotypes.length === 0) {
				logWarn("Class", metaClass, " has no stereotypes. No class code will be generated.");
			}

			metaClass.attributes.forEach(function(metaAttribute) {
			   if (isMissing(metaAttribute._type)) {
				   logError("Attribute", metaAttribute, " on class " + metaClass._name + " has no data type defined.");
			   }
			});

			metaClass.operations.forEach(function(metaOperation) {
			    metaOperation.parameters.forEach(function (metaParameter) {
			        if (isMissing(metaParameter._type)) {
			        	logError("Paramter", metaParameter,
			        			" in operation " + metaOperation._name +
			        			" of class " + metaClass._name +
			        			" has no data type");
			        }
			    });
			});

		});

		var logLevel;
		if (errorCount > 0) {
			logLevel = "error";
		}
		else if (warnCount > 0) {
			logLevel = "warn";
		}
		else {
			logLevel = "info";
		}

		winston.log(logLevel, "Validation completed: " + errorCount + " errors, " + warnCount + " warnings");

		return (errorCount === 0);

	};

})(metaModel);
<commit_msg>change var def for older js<commit_after>/*
Copyright (C) 2016 by Joel Kozikowski

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */

"use strict";

var metaModel = require('../meta/meta-model.js');
var winston = require('winston');

(function(meta){

	var warnCount = 0;
	var errorCount = 0;

	meta.validate = function(metaModel) {

		warnCount = 0;
		errorCount = 0;
		var msg;

		winston.info("Validating model...");

		var logWarn = function(typeName, metaObj, msg) {
			msg = "WARN: " + typeName + " " + metaObj._name + msg;
			winston.warn(msg);
			warnCount++;
		};

		var logError = function(typeName, metaObj, msg) {
			msg = "ERROR: " + typeName + " " + metaObj._name + msg;
			winston.error(msg);
			errorCount++;
		};

		var isMissing = function(obj) {
			return (obj === undefined || obj === null ||
					(typeof(obj) === "string" && obj.length === 0));
		};

		metaModel.classes.forEach(function(metaClass) {

			if (metaClass.getPackageName().length === 0) {
				logWarn("Class", metaClass, " has no package specified. Code will be in root of project.");
			}

			if (metaClass._stereotypes.length === 0) {
				logWarn("Class", metaClass, " has no stereotypes. No class code will be generated.");
			}

			metaClass.attributes.forEach(function(metaAttribute) {
			   if (isMissing(metaAttribute._type)) {
				   logError("Attribute", metaAttribute, " on class " + metaClass._name + " has no data type defined.");
			   }
			});

			metaClass.operations.forEach(function(metaOperation) {
			    metaOperation.parameters.forEach(function (metaParameter) {
			        if (isMissing(metaParameter._type)) {
			        	logError("Paramter", metaParameter,
			        			" in operation " + metaOperation._name +
			        			" of class " + metaClass._name +
			        			" has no data type");
			        }
			    });
			});

		});

		var logLevel;
		if (errorCount > 0) {
			logLevel = "error";
		}
		else if (warnCount > 0) {
			logLevel = "warn";
		}
		else {
			logLevel = "info";
		}

		winston.log(logLevel, "Validation completed: " + errorCount + " errors, " + warnCount + " warnings");

		return (errorCount === 0);

	};

})(metaModel);
<|endoftext|>


<commit_before>import electron from 'electron';
import path from 'path';
import { Curl } from 'node-libcurl';
import fs from 'fs';
import LocalStorage from './local-storage';
import {
  changelogUrl,
  getAppLongName,
  getAppName,
  getAppVersion,
  isDevelopment,
  isMac,
  MNEMONIC_SYM,
} from '../common/constants';
import * as misc from '../common/misc';
import { docsBase } from '../common/documentation';

const { app, Menu, BrowserWindow, shell, dialog } = electron;

// So we can use native modules in renderer
// NOTE: This will be deprecated in Electron 10 and impossible in 11
//   https://github.com/electron/electron/issues/18397
app.allowRendererProcessReuse = false;

const DEFAULT_WIDTH = 1280;
const DEFAULT_HEIGHT = 700;
const MINIMUM_WIDTH = 500;
const MINIMUM_HEIGHT = 400;

let mainWindow = null;
let localStorage = null;

export function init() {
  initLocalStorage();
  initContextMenus();
}

export function createWindow() {
  const zoomFactor = getZoomFactor();
  const { bounds, fullscreen, maximize } = getBounds();
  const { x, y, width, height } = bounds;

  let isVisibleOnAnyDisplay = true;
  for (const d of electron.screen.getAllDisplays()) {
    const isVisibleOnDisplay =
      x >= d.bounds.x &&
      y >= d.bounds.y &&
      x + width <= d.bounds.x + d.bounds.width &&
      y + height <= d.bounds.y + d.bounds.height;

    if (!isVisibleOnDisplay) {
      isVisibleOnAnyDisplay = false;
    }
  }

  mainWindow = new BrowserWindow({
    // Make sure we don't initialize the window outside the bounds
    x: isVisibleOnAnyDisplay ? x : undefined,
    y: isVisibleOnAnyDisplay ? y : undefined,

    // Other options
    fullscreen: fullscreen,
    fullscreenable: true,
    title: getAppName(),
    width: width || DEFAULT_WIDTH,
    height: height || DEFAULT_HEIGHT,
    minHeight: MINIMUM_HEIGHT,
    minWidth: MINIMUM_WIDTH,
    acceptFirstMouse: true,
    icon: path.resolve(__dirname, 'static/icon.png'),
    webPreferences: {
      zoomFactor: zoomFactor,
      nodeIntegration: true,
      webviewTag: true,
      enableRemoteModule: true,
    },
  });

  // BrowserWindow doesn't have an option for this, so we have to do it manually :(
  if (maximize) {
    mainWindow.maximize();
  }

  mainWindow.on('resize', e => saveBounds());

  mainWindow.on('maximize', e => saveBounds());

  mainWindow.on('unmaximize', e => saveBounds());

  mainWindow.on('move', e => saveBounds());

  mainWindow.on('unresponsive', e => {
    showUnresponsiveModal();
  });

  // Open generic links (<a .../>) in default browser
  mainWindow.webContents.on('will-navigate', (e, url) => {
    if (url === appUrl) {
      return;
    }

    console.log('[app] Navigate to ' + url);
    e.preventDefault();
    electron.shell.openExternal(url);
  });

  // Load the html of the app.
  const url = process.env.APP_RENDER_URL;
  const appUrl = url || `file://${app.getAppPath()}/renderer.html`;
  console.log(`[main] Loading ${appUrl}`);
  mainWindow.loadURL(appUrl);

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });

  const applicationMenu = {
    label: `${MNEMONIC_SYM}Application`,
    submenu: [
      ...(isMac()
        ? [{ label: `A${MNEMONIC_SYM}bout ${getAppName()}`, role: 'about' }, { type: 'separator' }]
        : []),
      {
        label: `${MNEMONIC_SYM}Preferences`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          window.webContents.send('toggle-preferences');
        },
      },
      {
        label: `${MNEMONIC_SYM}Changelog`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          misc.clickLink(changelogUrl());
        },
      },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideothers' },
      { type: 'separator' },
      { label: `${MNEMONIC_SYM}Quit`, accelerator: 'CmdOrCtrl+Q', click: () => app.quit() },
    ],
  };

  const editMenu = {
    label: `${MNEMONIC_SYM}Edit`,
    submenu: [
      { label: `${MNEMONIC_SYM}Undo`, accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: `${MNEMONIC_SYM}Redo`, accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: `Cu${MNEMONIC_SYM}t`, accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: `${MNEMONIC_SYM}Copy`, accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: `${MNEMONIC_SYM}Paste`, accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      {
        label: `Select ${MNEMONIC_SYM}All`,
        accelerator: 'CmdOrCtrl+A',
        selector: 'selectAll:',
      },
    ],
  };

  const viewMenu = {
    label: `${MNEMONIC_SYM}View`,
    submenu: [
      { label: `Toggle ${MNEMONIC_SYM}Full Screen`, role: 'togglefullscreen' },
      {
        label: `${MNEMONIC_SYM}Actual Size`,
        accelerator: 'CmdOrCtrl+0',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = 1;
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}In`,
        accelerator: 'CmdOrCtrl+=',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.min(1.8, getZoomFactor() + 0.05);
          w.webContents.setZoomFactor(zoomFactor);

          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}Out`,
        accelerator: 'CmdOrCtrl+-',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.max(0.5, getZoomFactor() - 0.05);
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: 'Toggle Sidebar',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-sidebar');
        },
      },
      {
        label: `Toggle ${MNEMONIC_SYM}DevTools`,
        accelerator: 'Alt+CmdOrCtrl+I',
        click: () => mainWindow.toggleDevTools(),
      },
    ],
  };

  const windowMenu = {
    label: `${MNEMONIC_SYM}Window`,
    role: 'window',
    submenu: [
      { label: `${MNEMONIC_SYM}Minimize`, role: 'minimize' },
      ...(isMac() ? [{ label: `${MNEMONIC_SYM}Close`, role: 'close' }] : []),
    ],
  };

  const helpMenu = {
    label: `${MNEMONIC_SYM}Help`,
    role: 'help',
    id: 'help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Help and Support`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal(docsBase);
        },
      },
      {
        label: `${MNEMONIC_SYM}Keyboard Shortcuts`,
        accelerator: 'CmdOrCtrl+Shift+?',
        click: (menuItem, w, e) => {
          if (!w || !w.webContents) {
            return;
          }
          w.webContents.send('toggle-preferences-shortcuts');
        },
      },
      {
        label: `Show App ${MNEMONIC_SYM}Data Folder`,
        click: (menuItem, w, e) => {
          const directory = misc.getDataDirectory();
          shell.showItemInFolder(directory);
        },
      },
      {
        label: 'Show Open Source Licenses',
        click: (menuItem, w, e) => {
          const licensePath = path.resolve(app.getAppPath(), '../opensource-licenses.txt');
          shell.openPath(licensePath);
        },
      },
      {
        label: 'Show Software License',
        click: () => {
          shell.openExternal('https://insomnia.rest/license');
        },
      },
      {
        label: `Insomnia ${MNEMONIC_SYM}Help`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal('https://support.insomnia.rest');
        },
      },
    ],
  };

  if (!isMac()) {
    helpMenu.submenu.unshift({
      label: `${MNEMONIC_SYM}About`,
      click: async () => {
        await dialog.showMessageBox({
          type: 'info',
          title: getAppName(),
          message: getAppLongName(),
          detail: [
            'Version ' + getAppVersion(),
            'Shell ' + process.versions.electron,
            'Node ' + process.versions.node,
            'V8 ' + process.versions.v8,
            'Architecture ' + process.arch,
            '', // Blank line before libcurl
            Curl.getVersion(),
          ].join('\n'),
        });
      },
    });
  }

  const developerMenu = {
    label: `${MNEMONIC_SYM}Developer`,
    position: 'before=help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload`,
        accelerator: 'Shift+F5',
        click: () => mainWindow.reload(),
      },
      {
        label: `Resize to Defaul${MNEMONIC_SYM}t`,
        click: () =>
          mainWindow.setBounds({
            x: 100,
            y: 100,
            width: DEFAULT_WIDTH,
            height: DEFAULT_HEIGHT,
          }),
      },
      {
        label: `Take ${MNEMONIC_SYM}Screenshot`,
        click: function() {
          mainWindow.capturePage(image => {
            const buffer = image.toPNG();
            const dir = app.getPath('desktop');
            fs.writeFileSync(path.join(dir, `Screenshot-${new Date()}.png`), buffer);
          });
        },
      },
      {
        label: `${MNEMONIC_SYM}Toggle Insomnia`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-insomnia');
        },
      },
    ],
  };

  const toolsMenu = {
    label: `${MNEMONIC_SYM}Tools`,
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload Plugins`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('reload-plugins');
        },
      },
    ],
  };

  const template = [];

  template.push(applicationMenu);
  template.push(editMenu);
  template.push(viewMenu);
  template.push(windowMenu);
  template.push(toolsMenu);
  template.push(helpMenu);

  if (isDevelopment() || process.env.INSOMNIA_FORCE_DEBUG) {
    template.push(developerMenu);
  }

  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  return mainWindow;
}

async function showUnresponsiveModal() {
  const id = await dialog.showMessageBox({
    type: 'info',
    buttons: ['Cancel', 'Reload'],
    defaultId: 1,
    cancelId: 0,
    title: 'Unresponsive',
    message: 'Insomnia has become unresponsive. Do you want to reload?',
  });

  if (id === 1) {
    mainWindow.destroy();
    createWindow();
  }
}

function saveBounds() {
  if (!mainWindow) {
    return;
  }

  const fullscreen = mainWindow.isFullScreen();

  // Only save the size if we're not in fullscreen
  if (!fullscreen) {
    localStorage.setItem('bounds', mainWindow.getBounds());
    localStorage.setItem('maximize', mainWindow.isMaximized());
    localStorage.setItem('fullscreen', false);
  } else {
    localStorage.setItem('fullscreen', true);
  }
}

function getBounds() {
  let bounds = {};
  let fullscreen = false;
  let maximize = false;
  try {
    bounds = localStorage.getItem('bounds', {});
    fullscreen = localStorage.getItem('fullscreen', false);
    maximize = localStorage.getItem('maximize', false);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse window bounds', e);
  }

  return { bounds, fullscreen, maximize };
}

function saveZoomFactor(zoomFactor) {
  localStorage.setItem('zoomFactor', zoomFactor);
}

function getZoomFactor() {
  let zoomFactor = 1;
  try {
    zoomFactor = localStorage.getItem('zoomFactor', 1);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse zoomFactor', e);
  }

  return zoomFactor;
}

function initLocalStorage() {
  const localStoragePath = path.join(misc.getDataDirectory(), 'localStorage');
  localStorage = new LocalStorage(localStoragePath);
}

function initContextMenus() {
  require('electron-context-menu')({});
}
<commit_msg>Copy info to clipboard (#2480)<commit_after>import electron from 'electron';
import path from 'path';
import { Curl } from 'node-libcurl';
import fs from 'fs';
import LocalStorage from './local-storage';
import {
  changelogUrl,
  getAppLongName,
  getAppName,
  getAppVersion,
  isDevelopment,
  isMac,
  MNEMONIC_SYM,
} from '../common/constants';
import * as misc from '../common/misc';
import * as os from 'os';
import { docsBase } from '../common/documentation';

const { app, Menu, BrowserWindow, shell, dialog, clipboard } = electron;

// So we can use native modules in renderer
// NOTE: This will be deprecated in Electron 10 and impossible in 11
//   https://github.com/electron/electron/issues/18397
app.allowRendererProcessReuse = false;

const DEFAULT_WIDTH = 1280;
const DEFAULT_HEIGHT = 700;
const MINIMUM_WIDTH = 500;
const MINIMUM_HEIGHT = 400;

let mainWindow = null;
let localStorage = null;

export function init() {
  initLocalStorage();
  initContextMenus();
}

export function createWindow() {
  const zoomFactor = getZoomFactor();
  const { bounds, fullscreen, maximize } = getBounds();
  const { x, y, width, height } = bounds;

  let isVisibleOnAnyDisplay = true;
  for (const d of electron.screen.getAllDisplays()) {
    const isVisibleOnDisplay =
      x >= d.bounds.x &&
      y >= d.bounds.y &&
      x + width <= d.bounds.x + d.bounds.width &&
      y + height <= d.bounds.y + d.bounds.height;

    if (!isVisibleOnDisplay) {
      isVisibleOnAnyDisplay = false;
    }
  }

  mainWindow = new BrowserWindow({
    // Make sure we don't initialize the window outside the bounds
    x: isVisibleOnAnyDisplay ? x : undefined,
    y: isVisibleOnAnyDisplay ? y : undefined,

    // Other options
    fullscreen: fullscreen,
    fullscreenable: true,
    title: getAppName(),
    width: width || DEFAULT_WIDTH,
    height: height || DEFAULT_HEIGHT,
    minHeight: MINIMUM_HEIGHT,
    minWidth: MINIMUM_WIDTH,
    acceptFirstMouse: true,
    icon: path.resolve(__dirname, 'static/icon.png'),
    webPreferences: {
      zoomFactor: zoomFactor,
      nodeIntegration: true,
      webviewTag: true,
      enableRemoteModule: true,
    },
  });

  // BrowserWindow doesn't have an option for this, so we have to do it manually :(
  if (maximize) {
    mainWindow.maximize();
  }

  mainWindow.on('resize', e => saveBounds());

  mainWindow.on('maximize', e => saveBounds());

  mainWindow.on('unmaximize', e => saveBounds());

  mainWindow.on('move', e => saveBounds());

  mainWindow.on('unresponsive', e => {
    showUnresponsiveModal();
  });

  // Open generic links (<a .../>) in default browser
  mainWindow.webContents.on('will-navigate', (e, url) => {
    if (url === appUrl) {
      return;
    }

    console.log('[app] Navigate to ' + url);
    e.preventDefault();
    electron.shell.openExternal(url);
  });

  // Load the html of the app.
  const url = process.env.APP_RENDER_URL;
  const appUrl = url || `file://${app.getAppPath()}/renderer.html`;
  console.log(`[main] Loading ${appUrl}`);
  mainWindow.loadURL(appUrl);

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });

  const applicationMenu = {
    label: `${MNEMONIC_SYM}Application`,
    submenu: [
      {
        label: `${MNEMONIC_SYM}Preferences`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          window.webContents.send('toggle-preferences');
        },
      },
      {
        label: `${MNEMONIC_SYM}Changelog`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          misc.clickLink(changelogUrl());
        },
      },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideothers' },
      { type: 'separator' },
      { label: `${MNEMONIC_SYM}Quit`, accelerator: 'CmdOrCtrl+Q', click: () => app.quit() },
    ],
  };

  const editMenu = {
    label: `${MNEMONIC_SYM}Edit`,
    submenu: [
      { label: `${MNEMONIC_SYM}Undo`, accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: `${MNEMONIC_SYM}Redo`, accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: `Cu${MNEMONIC_SYM}t`, accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: `${MNEMONIC_SYM}Copy`, accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: `${MNEMONIC_SYM}Paste`, accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      {
        label: `Select ${MNEMONIC_SYM}All`,
        accelerator: 'CmdOrCtrl+A',
        selector: 'selectAll:',
      },
    ],
  };

  const viewMenu = {
    label: `${MNEMONIC_SYM}View`,
    submenu: [
      { label: `Toggle ${MNEMONIC_SYM}Full Screen`, role: 'togglefullscreen' },
      {
        label: `${MNEMONIC_SYM}Actual Size`,
        accelerator: 'CmdOrCtrl+0',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = 1;
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}In`,
        accelerator: 'CmdOrCtrl+=',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.min(1.8, getZoomFactor() + 0.05);
          w.webContents.setZoomFactor(zoomFactor);

          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}Out`,
        accelerator: 'CmdOrCtrl+-',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.max(0.5, getZoomFactor() - 0.05);
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: 'Toggle Sidebar',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-sidebar');
        },
      },
      {
        label: `Toggle ${MNEMONIC_SYM}DevTools`,
        accelerator: 'Alt+CmdOrCtrl+I',
        click: () => mainWindow.toggleDevTools(),
      },
    ],
  };

  const windowMenu = {
    label: `${MNEMONIC_SYM}Window`,
    role: 'window',
    submenu: [
      { label: `${MNEMONIC_SYM}Minimize`, role: 'minimize' },
      ...(isMac() ? [{ label: `${MNEMONIC_SYM}Close`, role: 'close' }] : []),
    ],
  };

  const helpMenu = {
    label: `${MNEMONIC_SYM}Help`,
    role: 'help',
    id: 'help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Help and Support`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal(docsBase);
        },
      },
      {
        label: `${MNEMONIC_SYM}Keyboard Shortcuts`,
        accelerator: 'CmdOrCtrl+Shift+?',
        click: (menuItem, w, e) => {
          if (!w || !w.webContents) {
            return;
          }
          w.webContents.send('toggle-preferences-shortcuts');
        },
      },
      {
        label: `Show App ${MNEMONIC_SYM}Data Folder`,
        click: (menuItem, w, e) => {
          const directory = misc.getDataDirectory();
          shell.showItemInFolder(directory);
        },
      },
      {
        label: 'Show Open Source Licenses',
        click: (menuItem, w, e) => {
          const licensePath = path.resolve(app.getAppPath(), '../opensource-licenses.txt');
          shell.openPath(licensePath);
        },
      },
      {
        label: 'Show Software License',
        click: () => {
          shell.openExternal('https://insomnia.rest/license');
        },
      },
      {
        label: `Insomnia ${MNEMONIC_SYM}Help`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal('https://support.insomnia.rest');
        },
      },
    ],
  };

  const aboutDetail = [
    `OS ${os.type()} ${os.arch()} ${os.release()}`,
    `Version ${getAppLongName()} ${getAppVersion()}`,
    `Shell ${process.versions.electron}`,
    `Node ${process.versions.node}`,
    `V8 ${process.versions.v8}`,
    `Architecture ${process.arch}`,
    Curl.getVersion(),
  ].join('\n');

  const aboutMsgOptions = {
    type: 'info',
    title: getAppName(),
    message: getAppLongName(),
    detail: aboutDetail,
    noLink: true,
  };

  if (isMac()) {
    applicationMenu.submenu.unshift(
      {
        label: `A${MNEMONIC_SYM}bout ${getAppName()}`,
        click: async () => {
          const buttons = ['OK', 'Copy'];
          const msgBox = await dialog.showMessageBox({
            ...aboutMsgOptions,
            buttons: buttons,
            defaultId: buttons.indexOf('OK'),
            cancelId: buttons.indexOf('OK'),
          });

          if (msgBox.response === buttons.indexOf('Copy')) {
            clipboard.writeText(aboutDetail);
          }
        },
      },
      { type: 'separator' },
    );
  } else {
    helpMenu.submenu.unshift({
      label: `${MNEMONIC_SYM}About`,
      click: async () => {
        const buttons = ['Copy', 'OK'];
        const msgBox = await dialog.showMessageBox({
          ...aboutMsgOptions,
          buttons: buttons,
          defaultId: buttons.indexOf('OK'),
          cancelId: buttons.indexOf('OK'),
        });
        if (msgBox.response === buttons.indexOf('Copy')) {
          clipboard.writeText(aboutDetail);
        }
      },
    });
  }

  const developerMenu = {
    label: `${MNEMONIC_SYM}Developer`,
    position: 'before=help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload`,
        accelerator: 'Shift+F5',
        click: () => mainWindow.reload(),
      },
      {
        label: `Resize to Defaul${MNEMONIC_SYM}t`,
        click: () =>
          mainWindow.setBounds({
            x: 100,
            y: 100,
            width: DEFAULT_WIDTH,
            height: DEFAULT_HEIGHT,
          }),
      },
      {
        label: `Take ${MNEMONIC_SYM}Screenshot`,
        click: function() {
          mainWindow.capturePage(image => {
            const buffer = image.toPNG();
            const dir = app.getPath('desktop');
            fs.writeFileSync(path.join(dir, `Screenshot-${new Date()}.png`), buffer);
          });
        },
      },
      {
        label: `${MNEMONIC_SYM}Toggle Insomnia`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-insomnia');
        },
      },
    ],
  };

  const toolsMenu = {
    label: `${MNEMONIC_SYM}Tools`,
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload Plugins`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('reload-plugins');
        },
      },
    ],
  };

  const template = [];

  template.push(applicationMenu);
  template.push(editMenu);
  template.push(viewMenu);
  template.push(windowMenu);
  template.push(toolsMenu);
  template.push(helpMenu);

  if (isDevelopment() || process.env.INSOMNIA_FORCE_DEBUG) {
    template.push(developerMenu);
  }

  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  return mainWindow;
}

async function showUnresponsiveModal() {
  const id = await dialog.showMessageBox({
    type: 'info',
    buttons: ['Cancel', 'Reload'],
    defaultId: 1,
    cancelId: 0,
    title: 'Unresponsive',
    message: 'Insomnia has become unresponsive. Do you want to reload?',
  });

  if (id === 1) {
    mainWindow.destroy();
    createWindow();
  }
}

function saveBounds() {
  if (!mainWindow) {
    return;
  }

  const fullscreen = mainWindow.isFullScreen();

  // Only save the size if we're not in fullscreen
  if (!fullscreen) {
    localStorage.setItem('bounds', mainWindow.getBounds());
    localStorage.setItem('maximize', mainWindow.isMaximized());
    localStorage.setItem('fullscreen', false);
  } else {
    localStorage.setItem('fullscreen', true);
  }
}

function getBounds() {
  let bounds = {};
  let fullscreen = false;
  let maximize = false;
  try {
    bounds = localStorage.getItem('bounds', {});
    fullscreen = localStorage.getItem('fullscreen', false);
    maximize = localStorage.getItem('maximize', false);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse window bounds', e);
  }

  return { bounds, fullscreen, maximize };
}

function saveZoomFactor(zoomFactor) {
  localStorage.setItem('zoomFactor', zoomFactor);
}

function getZoomFactor() {
  let zoomFactor = 1;
  try {
    zoomFactor = localStorage.getItem('zoomFactor', 1);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse zoomFactor', e);
  }

  return zoomFactor;
}

function initLocalStorage() {
  const localStoragePath = path.join(misc.getDataDirectory(), 'localStorage');
  localStorage = new LocalStorage(localStoragePath);
}

function initContextMenus() {
  require('electron-context-menu')({});
}
<|endoftext|>


<commit_before>import flattenDeep from 'lodash/flattenDeep'
import head from 'lodash/head'
import map from 'lodash/map'
import noop from 'lodash/noop'

export default function traverseMJML(mjml, predicate = noop) {
  const traverse = mjml =>
    map(mjml.children, child => {
      if (predicate(child)) {
        return child
      }

      return traverse(child)
    })

  return head(flattenDeep(traverse(mjml)))
}
<commit_msg>remove unused helper<commit_after><|endoftext|>


<commit_before>/*
 * gennumplan.js - ilib tool to generate the json numplan information from the libphonefmt-js
 * library
 *
 * Copyright © 2019 JEDLSoft
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /*
 * This code is intended to be run under node.js
 */

var fs = require('fs');
var util = require('util');
var path = require('path');
var common = require('../cldr/common.js');
var mkdirs = common.makeDirs;
var toDir = "tmp";

if (process.argv.length > 2) {
    toDir = process.argv[2];
}

function usage() {
    console.log("Usage: gengeoinfo.js [-h] [ output_dir ]\n" +
            "-h or --help\n" + "  this help\n");
    process.exit(1);
}

process.argv.forEach(function (val, index, array) {
    if (val === "-h" || val === "--help") {
        usage();
    }
});

console.log("gennumplan.js - generate the numplan.json file.\n");

var metadata = require("./libphonenumber-js/metadata.json");
var countryData = metadata.countries;
var country, filename, exampleNums = {};

function getFormatChars(phonedata) {
    var formats = phonedata.formats;
    if (!formats) return "";

    var numformats = formats.length;
    var combineString = "", uniqChars = "";
    var i;

    for (i=0; i< numformats; i++) {
        combineString += formats[i].format;
    }

    trimString = combineString.replace(/[\$[0-9]|[0-9]*/g, "").replace(/\s+/g," ");

    if (trimString.length >1) {
        for (i=0; i < trimString.length; i++) {
            if (uniqChars.indexOf(trimString[i]) == -1) {
                uniqChars += trimString[i];
            }
        }
    }
    return uniqChars ? uniqChars : trimString;
}

for (country in countryData) {
    if (country === "001") break;
    var numPlanData = {};
    var regx = RegExp(/[\!|\?|\:]/);
    var phoneMetadata = countryData[country];

    filename = path.join(toDir, 'und', country)
    if (!fs.existsSync(filename)) {
        mkdirs(filename);
    }
    numPlanData["region"] = country;
    numPlanData["countryCode"] = phoneMetadata["phone_code"];

    if (regx.test(countryData[country]["idd_prefix"])){
        numPlanData["iddCode"] = phoneMetadata["idd_prefix"] + "  - It's a regular expression. It needs to be checked";
    } else {
        numPlanData["iddCode"] = phoneMetadata["idd_prefix"];
    }
    numPlanData["trunkCode"] = phoneMetadata["national_prefix"];
    numPlanData["skipTrunk"] = (phoneMetadata["national_prefix"] ? true : false);

    /*
    *  No info in metadata. Just set default value
    * "dialingPlan": "closed"
    */
    numPlanData["dialingPlan"] = "closed";

    numPlanData["commonFormatChars"] = getFormatChars(phoneMetadata);

    var fieldLength = {
        "areaCode": 0,
        "cic": 0,
        "vsc": 0,
        "mobilePrefix": 0,
        "serviceCode": 0,
        "personal": 0,
        "minLocalLength": 0,
        "maxLocalLength": 8,
        "emergency": 0,
        "special": 0
    };

    if (phoneMetadata["types"]["fixed_line"] && phoneMetadata["types"]["fixed_line"]["possible_lengths"]) {
        countLength = phoneMetadata["types"]["fixed_line"]["possible_lengths"];
        if (countLength.length == 1) {
            fieldLength["maxLocalLength"] = countLength[0];
        } else {
            fieldLength["minLocalLength"] = countLength[0];
            fieldLength["maxLocalLength"] = countLength[countLength.length-1];
        }
    }

    numPlanData["fieldLengths"] = fieldLength;

    exampleNums[country]= phoneMetadata["examples"];
    if (typeof phoneMetadata["national_prefix"] !== "undefined") {
        exampleNums[country]["trunkCode"] = phoneMetadata["national_prefix"];
    }

    var file1 = path.join(filename, "numplan.json");
    console.log("Creating " + filename + "/numplan.json")
    fs.writeFileSync(file1, JSON.stringify(numPlanData, true, 4), "utf-8");
}

var file2 = path.join(toDir, "exampleNums.json");
fs.writeFileSync(file2, JSON.stringify(exampleNums, true, 4), "utf-8");<commit_msg>Update gennumplan.js<commit_after>/*
 * gennumplan.js - ilib tool to generate the json numplan information from the libphonefmt-js
 * library
 *
 * Copyright © 2019 JEDLSoft
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /*
 * This code is intended to be run under node.js
 */

var fs = require('fs');
var util = require('util');
var path = require('path');
var common = require('../cldr/common.js');
var mkdirs = common.makeDirs;
var toDir = "tmp";

var skipCountry = ["KR", "US", "GB", "ES", "MX", "AR", "CO", "BR", "CA", "FR", "IT", "DE", "RU", "JP", "CN", "TW", "NL"];

if (process.argv.length > 2) {
    toDir = process.argv[2];
}

function usage() {
    console.log("Usage: gengeoinfo.js [-h] [ output_dir ]\n" +
            "-h or --help\n" + "  this help\n");
    process.exit(1);
}

process.argv.forEach(function (val, index, array) {
    if (val === "-h" || val === "--help") {
        usage();
    }
});

console.log("gennumplan.js - generate the numplan.json file.\n");

var metadata = require("./libphonenumber-js/metadata.json");
var countryData = metadata.countries;
var country, filename, exampleNums = {};

function getFormatChars(phonedata) {
    var formats = phonedata.formats;
    if (!formats) return "";

    var numformats = formats.length;
    var combineString = "", uniqChars = "";
    var i;

    for (i=0; i< numformats; i++) {
        combineString += formats[i].format;
    }

    trimString = combineString.replace(/[\$[0-9]|[0-9]*/g, "").replace(/\s+/g," ");

    if (trimString.length >1) {
        for (i=0; i < trimString.length; i++) {
            if (uniqChars.indexOf(trimString[i]) == -1) {
                uniqChars += trimString[i];
            }
        }
    }
    return uniqChars ? uniqChars : trimString;
}

for (country in countryData) {
    if (country === "001" ||
       (skipCountry.indexOf(country) !== -1 ) ) {
        console.log("skip country.... : ", country)
        continue;
    }

    var numPlanData = {};
    var regx = RegExp(/[\!|\?|\:]/);
    var phoneMetadata = countryData[country];

    filename = path.join(toDir, 'und', country)
    if (!fs.existsSync(filename)) {
        mkdirs(filename);
    }
    numPlanData["region"] = country;
    numPlanData["countryCode"] = phoneMetadata["phone_code"];

    if (regx.test(countryData[country]["idd_prefix"])){
        numPlanData["iddCode"] = phoneMetadata["idd_prefix"] + "  - It's a regular expression. It needs to be checked";
    } else {
        numPlanData["iddCode"] = phoneMetadata["idd_prefix"];
    }
    numPlanData["trunkCode"] = phoneMetadata["national_prefix"];
    numPlanData["skipTrunk"] = (phoneMetadata["national_prefix"] ? true : false);

    /*
    *  No info in metadata. Just set default value
    * "dialingPlan": "closed"
    */
    numPlanData["dialingPlan"] = "closed";

    numPlanData["commonFormatChars"] = getFormatChars(phoneMetadata);

    var fieldLength = {
        "areaCode": 0,
        "cic": 0,
        "vsc": 0,
        "mobilePrefix": 0,
        "serviceCode": 0,
        "personal": 0,
        "minLocalLength": 0,
        "maxLocalLength": 8,
        "emergency": 0,
        "special": 0
    };

    if (phoneMetadata["types"]["fixed_line"] && phoneMetadata["types"]["fixed_line"]["possible_lengths"]) {
        countLength = phoneMetadata["types"]["fixed_line"]["possible_lengths"];
        if (countLength.length == 1) {
            fieldLength["maxLocalLength"] = countLength[0];
        } else {
            fieldLength["minLocalLength"] = countLength[0];
            fieldLength["maxLocalLength"] = countLength[countLength.length-1];
        }
    }

    numPlanData["fieldLengths"] = fieldLength;

    exampleNums[country]= phoneMetadata["examples"];
    if (typeof phoneMetadata["national_prefix"] !== "undefined") {
        exampleNums[country]["trunkCode"] = phoneMetadata["national_prefix"];
    }

    var file1 = path.join(filename, "numplan.json");
    console.log("Creating " + filename + "/numplan.json")
    fs.writeFileSync(file1, JSON.stringify(numPlanData, true, 4), "utf-8");
}

var file2 = path.join(toDir, "exampleNums.json");
fs.writeFileSync(file2, JSON.stringify(exampleNums, true, 4), "utf-8");<|endoftext|>


<commit_before>'use strict';

describe('auth-service', function () {

  var AuthService,
      StorageService,
      StorageServiceMock,
      authClientMock = {
        $login: function(){},
        $logout: function(){},
        $getCurrentUser: function(){}
      };

  beforeEach(module('kosh'));

  beforeEach(module(function($provide) {
    StorageServiceMock = {
      getAuthClient: function() {
        return authClientMock;
      }
    };
    $provide.value('StorageService', StorageServiceMock);
  }));

  beforeEach(inject(function(_AuthService_, _StorageService_) {
    AuthService = _AuthService_;
    StorageService = _StorageService_;
  }));

  describe('test login and logout', function() {

    it('should call $login on the authClient object', function() {
      spyOn(authClientMock, '$login');
      AuthService.login();
      expect(authClientMock.$login).toHaveBeenCalledWith('github', {rememberMe: true});
    });

    it('should call $logout on the authClient object', function() {
      spyOn(authClientMock, '$logout');
      AuthService.logout();
      expect(authClientMock.$logout).toHaveBeenCalled();
    });

    it('should tell that user is logged in when uid is present', function() {
      AuthService.user = {
        uid: 123
      };
      expect(AuthService.loggedIn()).toBe(true);
    });

    it('should tell that user is logged out when uid is not present', function() {
      AuthService.user = {};
      expect(AuthService.loggedIn()).toBe(false);
    });

  });

  describe('test authorization', function () {

    var USER_ROLES,
        $q,
        $rootScope;

    beforeEach(inject(function(_USER_ROLES_, _$q_, _$rootScope_) {
      USER_ROLES = _USER_ROLES_;
      $q = _$q_;
      $rootScope = _$rootScope_;
    }));

    describe('test rules that require user to be logged in', function() {

      it('should deny access if user is not logged in', function() {
        var deferred = $q.defer(),
            catchHandler = jasmine.createSpy('catchHandler');
        spyOn(authClientMock, '$getCurrentUser').andReturn(deferred.promise);
        AuthService.isAuthorized(USER_ROLES.LOGGED_IN).catch(catchHandler);
        deferred.resolve(null);
        $rootScope.$digest();
        expect(catchHandler).toHaveBeenCalled();
      });

      it('should grant access if user is logged in', function() {
        var deferred = $q.defer(),
            thenHandler = jasmine.createSpy('thenHandler');
        spyOn(authClientMock, '$getCurrentUser').andReturn(deferred.promise);
        AuthService.isAuthorized(USER_ROLES.LOGGED_IN).then(thenHandler);
        deferred.resolve('some user');
        $rootScope.$digest();
        expect(thenHandler).toHaveBeenCalled();
      });

    });

    describe('test rules that allow guest users', function () {

      it('should grant access if user is logged in', function() {
        var deferred = $q.defer(),
            thenHandler = jasmine.createSpy('thenHandler');
        AuthService.isAuthorized(USER_ROLES.GUEST).then(thenHandler);
        deferred.resolve('some user');
        $rootScope.$digest();
        expect(thenHandler).toHaveBeenCalled();
      });

    });

  });

});
<commit_msg>test guest rules<commit_after>'use strict';

describe('auth-service', function () {

  var AuthService,
      StorageService,
      StorageServiceMock,
      authClientMock = {
        $login: function(){},
        $logout: function(){},
        $getCurrentUser: function(){}
      };

  beforeEach(module('kosh'));

  beforeEach(module(function($provide) {
    StorageServiceMock = {
      getAuthClient: function() {
        return authClientMock;
      }
    };
    $provide.value('StorageService', StorageServiceMock);
  }));

  beforeEach(inject(function(_AuthService_, _StorageService_) {
    AuthService = _AuthService_;
    StorageService = _StorageService_;
  }));

  describe('test login and logout', function() {

    it('should call $login on the authClient object', function() {
      spyOn(authClientMock, '$login');
      AuthService.login();
      expect(authClientMock.$login).toHaveBeenCalledWith('github', {rememberMe: true});
    });

    it('should call $logout on the authClient object', function() {
      spyOn(authClientMock, '$logout');
      AuthService.logout();
      expect(authClientMock.$logout).toHaveBeenCalled();
    });

    it('should tell that user is logged in when uid is present', function() {
      AuthService.user = {
        uid: 123
      };
      expect(AuthService.loggedIn()).toBe(true);
    });

    it('should tell that user is logged out when uid is not present', function() {
      AuthService.user = {};
      expect(AuthService.loggedIn()).toBe(false);
    });

  });

  describe('test authorization', function () {

    var USER_ROLES,
        $q,
        $rootScope;

    beforeEach(inject(function(_USER_ROLES_, _$q_, _$rootScope_) {
      USER_ROLES = _USER_ROLES_;
      $q = _$q_;
      $rootScope = _$rootScope_;
    }));

    describe('test rules that require user to be logged in', function() {

      it('should deny access if user is not logged in', function() {
        var deferred = $q.defer(),
            catchHandler = jasmine.createSpy('catchHandler');
        spyOn(authClientMock, '$getCurrentUser').andReturn(deferred.promise);
        AuthService.isAuthorized(USER_ROLES.LOGGED_IN).catch(catchHandler);
        deferred.resolve(null);
        $rootScope.$digest();
        expect(catchHandler).toHaveBeenCalled();
      });

      it('should grant access if user is logged in', function() {
        var deferred = $q.defer(),
            thenHandler = jasmine.createSpy('thenHandler');
        spyOn(authClientMock, '$getCurrentUser').andReturn(deferred.promise);
        AuthService.isAuthorized(USER_ROLES.LOGGED_IN).then(thenHandler);
        deferred.resolve('some user');
        $rootScope.$digest();
        expect(thenHandler).toHaveBeenCalled();
      });

    });

    describe('test rules that allow guest users', function () {

      it('should grant access if user is logged in', function() {
        var deferred = $q.defer(),
            thenHandler = jasmine.createSpy('thenHandler');
        AuthService.isAuthorized(USER_ROLES.GUEST).then(thenHandler);
        deferred.resolve('some user');
        $rootScope.$digest();
        expect(thenHandler).toHaveBeenCalled();
      });

      it('should grant access if user is not logged in', function() {
        var deferred = $q.defer(),
            thenHandler = jasmine.createSpy('thenHandler');
        AuthService.isAuthorized(USER_ROLES.GUEST).then(thenHandler);
        deferred.resolve(null);
        $rootScope.$digest();
        expect(thenHandler).toHaveBeenCalled();
      });

    });

  });

});
<|endoftext|>


<commit_before>#!/usr/bin/env node
const octicons = require('octicons')
const fse = require('fs-extra')
const {join, resolve} = require('path')

const srcDir = resolve(__dirname, '../src/__generated__')
const iconsFile = join(srcDir, 'icons.js')
const typesFile = join(srcDir, 'icons.d.ts')

function CamelCase(str) {
  return str.replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase())
}

const octiconNames = [...Object.entries(octicons)]

const icons = octiconNames
  .map(([key, octicon]) => {
    const name = CamelCase(key)
    const {width, height, path} = octicon
    // convert attributes like fill-rule into JSX equivalents, e.g. fillRule
    const svg = path.replace(/([a-z]+)-([a-z]+)=/g, (_, a, b) => `${a}${CamelCase(b)}=`)
    const type = `Icon<${width}, ${height}>`
    const code = `function ${name}() {
  return ${svg}
}
${name}.size = [${width}, ${height}]
`

    return {
      key,
      name,
      octicon,
      type,
      code
    }
  })
  .sort((a, b) => a.key.localeCompare(b.key))

function writeIcons(file) {
  const count = icons.length
  const code = `/* THIS FILE IS GENERATED. DO NOT EDIT IT. */
import React from 'react'

${icons.map(({code}) => code).join('\n')}

const iconsByName = {
  ${icons.map(({key, name}) => `'${key}': ${name}`).join(',\n  ')}
}

function getIconByName(name) {
  return iconsByName[name]
}

export {
  getIconByName,
  iconsByName,
  ${icons.map(({name}) => name).join(',\n  ')}
}`
  return fse.writeFile(file, code, 'utf8').then(() => {
    console.warn('wrote %s with %d exports', file, count)
    return icons
  })
}

function writeTypes(file) {
  const count = icons.length
  const code = `/* THIS FILE IS GENERATED. DO NOT EDIT IT. */
import * as React from 'react'

type Icon<
  W extends number = number,
  H extends number = number
> = React.SFC<{}> & { size: [W, H] };

${icons.map(({name, type}) => `declare const ${name}: ${type}`).join('\n')}

type iconsByName = {
  ${icons.map(({key, type}) => `'${key}': ${type}`).join(',\n  ')}
}
declare const iconsByName: iconsByName

declare function getIconByName<T extends keyof iconsByName>(
  name: T
): IconsByName[T];
declare function getIconByName(name: string): Icon | undefined

export {
  Icon,
  getIconByName,
  iconsByName,
  ${icons.map(({name}) => name).join(',\n  ')}
}`
  return fse.writeFile(file, code, 'utf8').then(() => {
    console.warn('wrote %s with %d exports', file, count)
    return icons
  })
}

fse
  .mkdirs(srcDir)
  .then(() => writeIcons(iconsFile))
  .then(() => writeTypes(typesFile))
  .catch(error => {
    console.error(error)
    process.exit(1)
  })
<commit_msg>dry up generated header<commit_after>#!/usr/bin/env node
const octicons = require('octicons')
const fse = require('fs-extra')
const {join, resolve} = require('path')

const srcDir = resolve(__dirname, '../src/__generated__')
const iconsFile = join(srcDir, 'icons.js')
const typesFile = join(srcDir, 'icons.d.ts')

const GENERATED_HEADER = '/* THIS FILE IS GENERATED. DO NOT EDIT IT. */'

function CamelCase(str) {
  return str.replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase())
}

const octiconNames = [...Object.entries(octicons)]

const icons = octiconNames
  .map(([key, octicon]) => {
    const name = CamelCase(key)
    const {width, height, path} = octicon
    // convert attributes like fill-rule into JSX equivalents, e.g. fillRule
    const svg = path.replace(/([a-z]+)-([a-z]+)=/g, (_, a, b) => `${a}${CamelCase(b)}=`)
    const type = `Icon<${width}, ${height}>`
    const code = `function ${name}() {
  return ${svg}
}
${name}.size = [${width}, ${height}]
`

    return {
      key,
      name,
      octicon,
      type,
      code
    }
  })
  .sort((a, b) => a.key.localeCompare(b.key))

function writeIcons(file) {
  const count = icons.length
  const code = `${GENERATED_HEADER}
import React from 'react'

${icons.map(({code}) => code).join('\n')}

const iconsByName = {
  ${icons.map(({key, name}) => `'${key}': ${name}`).join(',\n  ')}
}

function getIconByName(name) {
  return iconsByName[name]
}

export {
  getIconByName,
  iconsByName,
  ${icons.map(({name}) => name).join(',\n  ')}
}`
  return fse.writeFile(file, code, 'utf8').then(() => {
    console.warn('wrote %s with %d exports', file, count)
    return icons
  })
}

function writeTypes(file) {
  const count = icons.length
  const code = `${GENERATED_HEADER}
import * as React from 'react'

type Icon<
  W extends number = number,
  H extends number = number
> = React.SFC<{}> & { size: [W, H] };

${icons.map(({name, type}) => `declare const ${name}: ${type}`).join('\n')}

type iconsByName = {
  ${icons.map(({key, type}) => `'${key}': ${type}`).join(',\n  ')}
}
declare const iconsByName: iconsByName

declare function getIconByName<T extends keyof iconsByName>(
  name: T
): IconsByName[T];
declare function getIconByName(name: string): Icon | undefined

export {
  Icon,
  getIconByName,
  iconsByName,
  ${icons.map(({name}) => name).join(',\n  ')}
}`
  return fse.writeFile(file, code, 'utf8').then(() => {
    console.warn('wrote %s with %d exports', file, count)
    return icons
  })
}

fse
  .mkdirs(srcDir)
  .then(() => writeIcons(iconsFile))
  .then(() => writeTypes(typesFile))
  .catch(error => {
    console.error(error)
    process.exit(1)
  })
<|endoftext|>


<commit_before>'use strict';

/* Controllers */

angular.module('homejs.controllers')
  .controller('OverviewController', ['$scope', 'Device', 'Timeserie', function($scope, Device, Timeserie) {

    // @todo how to fetch devices and those sensors timeseries data
    /*Device.query().forEach( function(device){
      console.log(device.data);
    });*/

    // this is hardcoded sensor uuid
    Timeserie.getHourly({uuid: '65a136d1-238a-11e3-987b-f9f88c23cf94'}).then( function(response){
      response.forEach( function(row, key){
        row[0] = new Date(row[0]);
      });
      $scope.someData = [response]
    });

    $scope.myChartOpts = {
        title:'',
        axes:{
          xaxis:{
            renderer:$.jqplot.DateAxisRenderer,
            tickOptions:{
              formatString:'%#d/%#m/%Y'
            }
          },
          yaxis: {
            tickOptions:{
              formatString:'%.2f C'
              }
          }
        },
        legend: { show:true, location: 'e' },
        highlighter: {
          show: true,
          sizeAdjust: 7.5
        },
        cursor: {
          show: false,
          zoom:true,
        }
      }

    // d3js:
    /*
    var scope = $scope;
    $.getJSON('http://localhost:3000/api/v0/timeserie/637670f1-2371-11e3-bbe5-0f40648d40c4/hourly', function(data){
      var arr = []
      data.forEach( function(row){
        arr.push( {x: new Date(row[0]), value: row[1] } );
      });
      scope = arr;
    });
    var today = new Date();
    var after = function(hour)
    {
      return new Date(
        today.getFullYear(),
        today.getMonth(),
        today.getDate(),
        today.getHours()+hour
      );
    }
    $scope.data = [
      {x: after(0), value: 4   },
      {x: after(1), value: 8   },
      {x: after(2), value: 15  },
      {x: after(2), value: 16  },
      {x: after(3), value: 23  },
      {x: after(4), value: 4  }
    ];
    $scope.options = {
      axes: {
        x: {type: 'date', tooltipFormatter: function(x) {return x;}}
      },
      series: [
        {y: 'value', color: 'steelblue', min: 0, type: 'area', label: 'Power consumption kWh'},
      ],
      lineMode: 'linear'
    }
    */

    //google chart:
    /*
    var scope = $scope;
    $scope.chart = {
      "type": "LineChart",
      "displayed": true,
      "cssStyle": "height:300px; width:100%;",
      "data": {
        "cols": [
          {id: "date",  label: "Month", type: "string"},
          {id: "value", label: "Sensor#X", "type": "number" },
        ],
        "rows": [
          {
            "c": [
              {
                "f": "January",
                "v": -30
              },
              {
                "v": -5
              }
            ]
          }
        ]
      },
      "options": {
        "title": "Power consumption avg per month",
        "isStacked": "true",
        "fill": 20,
        "displayExactValues": true,
        "vAxis": { "title": "Power consumption [kWh]", "gridlines": { "count": 10 }, min: -30, max: 30 },
        "hAxis": { "title": "Date" },
        "tooltip": { "isHtml": false }
      },
      "formatters": {}
    }*/
    /*    $.getJSON('http://localhost:3000/api/v0/timeserie/637670f1-2371-11e3-bbe5-0f40648d40c4/hourly', function(json){
      var arr = [];
      var i;
      for(i=0;i<json.length;i++){
        //var obj = {"v": new Date(json[i][0]), "v": json[i][1]};
        arr.push( {v: '1', v: 4} );

      }
      scope.chart.data.rows[0].c = arr;
      //console.log(scope);
    });
    */

  }]);<commit_msg>front-end: tried-fetching all device-sensors and render chart<commit_after>'use strict';

/* Controllers */

angular.module('homejs.controllers')
  .controller('OverviewController', ['$scope', 'Device', 'Timeserie', function($scope, Device, Timeserie) {

    // @todo how to fetch devices and those sensors timeseries data
    $scope.someData = []
    var devices = Device.query( function(){
      devices.forEach( function(device){
        device.sensors.forEach(function(sensor){
          Timeserie.getHourly({uuid: sensor.uuid})
            .then( function(response){
              if( response ){
                response.forEach( function(row, key){
                  row[0] = new Date(row[0]);
                });
                $scope.someData = [response];
              }
            });
        });
      });
    });
    /*
    // this is hardcoded sensor uuid
    Timeserie.getHourly({uuid: '65a136d0-238a-11e3-987b-f9f88c23cf94'})
      .then( function(response){
        response.forEach( function(row, key){
          row[0] = new Date(row[0]);
        });
        $scope.someData = [response]
      });*/

    $scope.myChartOpts = {
        title:'',
        axes:{
          xaxis:{
            renderer:$.jqplot.DateAxisRenderer,
            tickOptions:{
              formatString:'%#d/%#m/%Y'
            }
          },
          yaxis: {
            tickOptions:{
              formatString:'%.2f C'
              }
          }
        },
        legend: { show:true, location: 'e' },
        highlighter: {
          show: true,
          sizeAdjust: 7.5
        },
        cursor: {
          show: false,
          zoom:true,
        }
      }

    // d3js:
    /*
    var scope = $scope;
    $.getJSON('http://localhost:3000/api/v0/timeserie/637670f1-2371-11e3-bbe5-0f40648d40c4/hourly', function(data){
      var arr = []
      data.forEach( function(row){
        arr.push( {x: new Date(row[0]), value: row[1] } );
      });
      scope = arr;
    });
    var today = new Date();
    var after = function(hour)
    {
      return new Date(
        today.getFullYear(),
        today.getMonth(),
        today.getDate(),
        today.getHours()+hour
      );
    }
    $scope.data = [
      {x: after(0), value: 4   },
      {x: after(1), value: 8   },
      {x: after(2), value: 15  },
      {x: after(2), value: 16  },
      {x: after(3), value: 23  },
      {x: after(4), value: 4  }
    ];
    $scope.options = {
      axes: {
        x: {type: 'date', tooltipFormatter: function(x) {return x;}}
      },
      series: [
        {y: 'value', color: 'steelblue', min: 0, type: 'area', label: 'Power consumption kWh'},
      ],
      lineMode: 'linear'
    }
    */

    //google chart:
    /*
    var scope = $scope;
    $scope.chart = {
      "type": "LineChart",
      "displayed": true,
      "cssStyle": "height:300px; width:100%;",
      "data": {
        "cols": [
          {id: "date",  label: "Month", type: "string"},
          {id: "value", label: "Sensor#X", "type": "number" },
        ],
        "rows": [
          {
            "c": [
              {
                "f": "January",
                "v": -30
              },
              {
                "v": -5
              }
            ]
          }
        ]
      },
      "options": {
        "title": "Power consumption avg per month",
        "isStacked": "true",
        "fill": 20,
        "displayExactValues": true,
        "vAxis": { "title": "Power consumption [kWh]", "gridlines": { "count": 10 }, min: -30, max: 30 },
        "hAxis": { "title": "Date" },
        "tooltip": { "isHtml": false }
      },
      "formatters": {}
    }*/
    /*    $.getJSON('http://localhost:3000/api/v0/timeserie/637670f1-2371-11e3-bbe5-0f40648d40c4/hourly', function(json){
      var arr = [];
      var i;
      for(i=0;i<json.length;i++){
        //var obj = {"v": new Date(json[i][0]), "v": json[i][1]};
        arr.push( {v: '1', v: 4} );

      }
      scope.chart.data.rows[0].c = arr;
      //console.log(scope);
    });
    */

  }]);
 <|endoftext|>


<commit_before>define( [
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/aspect",
    "dojo/on",
    "dojo/query",
    "dojo/dom-construct",
    "dojo/topic",
    "dijit/form/FilteringSelect",
    "../Factory",
    "../../../_include/_HelpMixin",
    "./_AttributeWidgetMixin",
    "../../../../model/meta/Model",
    "../../../../locale/Dictionary",
    "dojo/text!./template/Select.html"
],
function(
    declare,
    lang,
    aspect,
    on,
    query,
    domConstruct,
    topic,
    FilteringSelect,
    ControlFactory,
    _HelpMixin,
    _AttributeWidgetMixin,
    Model,
    Dict,
    template
) {
    return declare([FilteringSelect, _HelpMixin, _AttributeWidgetMixin], {

        templateString: template,
        intermediateChanges: true,
        entity: {},
        attribute: {},
        original: {},

        spinnerNode: null,

        searchAttr: "displayText",

        constructor: function(args) {
            declare.safeMixin(this, args);

            var typeClass = Model.getTypeFromOid(this.entity.oid);

            this.label = Dict.translate(this.attribute.name);
            this.disabled = typeClass ? !typeClass.isEditable(this.attribute, this.entity) : false;
            this.name = this.attribute.name;
            this.value = this.entity[this.attribute.name];
            this.helpText = Dict.translate(this.attribute.description);

            this.store = ControlFactory.getListStore(this.attribute.inputType);
            // add empty value for select boxes
            this.store.setAddEmpty(true);

            aspect.before(this, "_startSearch", function(text) {
                // create spinner
                if (!this.spinnerNode) {
                    this.spinnerNode = domConstruct.create("p", {
                        innerHTML: ''
                    }, this.domNode.parentNode, "last");
                }
                this.showSpinner();
                return text;
            });
        },

        postCreate: function() {
            this.inherited(arguments);

            // subscribe to entity change events to change tab links
            this.own(
                topic.subscribe("entity-datachange", lang.hitch(this, function(data) {
                    if (data.name === this.attribute.name) {
                        this.set("value", data.newValue);
                    }
                })),
                on(this, 'search', lang.hitch(this, function() {
                    this.hideSpinner();
                }))
            );
        },

        showSpinner: function() {
            query(this.spinnerNode).style("display", "block");
        },

        hideSpinner: function() {
            query(this.spinnerNode).style("display", "none");
        }
    });
});<commit_msg>fixed select filter<commit_after>define( [
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/aspect",
    "dojo/on",
    "dojo/query",
    "dojo/dom-construct",
    "dojo/topic",
    "dijit/form/FilteringSelect",
    "../Factory",
    "../../../_include/_HelpMixin",
    "./_AttributeWidgetMixin",
    "../../../../model/meta/Model",
    "../../../../locale/Dictionary",
    "dojo/text!./template/Select.html"
],
function(
    declare,
    lang,
    aspect,
    on,
    query,
    domConstruct,
    topic,
    FilteringSelect,
    ControlFactory,
    _HelpMixin,
    _AttributeWidgetMixin,
    Model,
    Dict,
    template
) {
    return declare([FilteringSelect, _HelpMixin, _AttributeWidgetMixin], {

        templateString: template,
        intermediateChanges: true,
        entity: {},
        attribute: {},
        original: {},

        spinnerNode: null,

        searchAttr: "displayText",

        constructor: function(args) {
            declare.safeMixin(this, args);

            var typeClass = Model.getTypeFromOid(this.entity.oid);

            this.label = Dict.translate(this.attribute.name);
            this.disabled = typeClass ? !typeClass.isEditable(this.attribute, this.entity) : false;
            this.name = this.attribute.name;
            this.value = this.entity[this.attribute.name];
            this.helpText = Dict.translate(this.attribute.description);

            this.store = ControlFactory.getListStore(this.attribute.inputType);
            // add empty value for select boxes
            this.store.setAddEmpty(true);

            aspect.before(this, "_startSearch", function(text) {
                // create spinner
                if (!this.spinnerNode) {
                    this.spinnerNode = domConstruct.create("p", {
                        innerHTML: ''
                    }, this.domNode.parentNode, "last");
                }
                this.showSpinner();
            });
        },

        postCreate: function() {
            this.inherited(arguments);

            // subscribe to entity change events to change tab links
            this.own(
                topic.subscribe("entity-datachange", lang.hitch(this, function(data) {
                    if (data.name === this.attribute.name) {
                        this.set("value", data.newValue);
                    }
                })),
                on(this, 'search', lang.hitch(this, function() {
                    this.hideSpinner();
                }))
            );
        },

        showSpinner: function() {
            query(this.spinnerNode).style("display", "block");
        },

        hideSpinner: function() {
            query(this.spinnerNode).style("display", "none");
        }
    });
});<|endoftext|>


<commit_before>/* global moment: false */
/* global app: false */
/* global detailview: false */

app.controller('detailViewController', ['$scope', '$location', '$rootScope', '$timeout', '$routeParams', 'UserService', 'CONFIG', 'AuthService',
function($scope, $location, $rootScope, $timeout, $routeParams, UserService, CONFIG, AuthService) {
  $scope.errorMessage = null;
  $scope.timesheet = {};
  // calculate total minutes of day work
  var getWorkDayHours = function(timeIn, timeOut) {
    var timeInarray = timeIn.toString().split(":");
    var minutes = 60;
    var minutesFirst = parseInt(timeInarray[0], 10) * minutes;
    var totalFirstMin = parseInt(minutesFirst, 10) + parseInt(timeInarray[1], 10);

    var timeOutarray = timeOut.toString().split(":");
    var minutesSecond = parseInt(timeOutarray[0], 10) * minutes;
    var totalSecondMin = parseInt(minutesSecond, 10) + parseInt(timeOutarray[1], 10);

    if (parseInt(totalSecondMin, 10) < parseInt(totalFirstMin, 10)) {
      $scope.errorMessage = "End Time should be greater than Start Time!";
      // return;
    }
    var totalTimeInMinutes = parseInt(totalSecondMin, 10) - parseInt(totalFirstMin, 10);
    return totalTimeInMinutes;
  };

  // save timesheet entry
  this.saveTimesheet = function() {
    // var flag = checkData($scope.timesheet);
    $scope.isInvalid($scope.timesheet.in, $scope.timesheet.out);
    $scope.isInvalid($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    $scope.isInvalid($scope.timesheet.nightIn, $scope.timesheet.nightOut);

    if ($scope.timesheet == null) {
      $scope.errorMessage = "Time fields Can't leave blank!!";
      $('#submit-btn').text('Save').removeAttr("disabled");
      return;
    }
    // totalworkingHour = $scope.getTotoalhours($scope.timesheet);
    if ($scope.errorMessage == null && $scope.lunchErrorMessage == null && $scope.nightErrorMessage == null) {
      var dataPromise = UserService.saveDetailTimeSheet($scope.timesheet, $scope.date);
      $('#submit-btn').text('Please wait...').attr('disabled', 'disabled');
      dataPromise.then(function(response) {
        if (response.success) {
          $scope.successMessage = "Successfully Saved!";
          $('#submit-btn').text('Save').removeAttr("disabled");
          $timeout(function() {
            $location.path("/usertimesheet");
          }, CONFIG.REDIRECT_TIMEOUT);
        }else {
          $scope.errorMessage = "Sorry ! You can fill data only for current week.";
          $('#submit-btn').text('Save').removeAttr("disabled");
        }
      }, function() {
        $scope.errorMessage = "Something wrong on Server Please wait !";
        $('#submit-btn').text('Save').removeAttr("disabled");
      });
    }
  };
  // calculate hours and minutes of day work
  var dayWork = function(dayTime, lunchTime, nightTime) {
    var reminDayTime = parseFloat(dayTime) - parseFloat(lunchTime);
    var totalWorkMinutes = parseFloat(reminDayTime) + parseFloat(nightTime);
    var minute = 60;
    var hours = parseInt(Math.floor(parseInt(totalWorkMinutes, 10)) / minute, 10);
    var minutes = parseInt(totalWorkMinutes, 10) % minute;
    $scope.totalHour = hours + "." + minutes;
    return $scope.totalHour;
  };
  // calculate total hours
  $scope.getTotalhours = function() {
    $scope.dayWork = null;
    $scope.resetMessage();
    var dayTime = 0;
    var lunchTime = 0;
    var nightTime = 0;
    if (isNaN($scope.timesheet.in) && isNaN($scope.timesheet.out) &&
      $scope.timesheet.in != null && $scope.timesheet.out != null) {
      dayTime = getWorkDayHours($scope.timesheet.in, $scope.timesheet.out);
    }
    if (isNaN($scope.timesheet.lunchIn) && isNaN($scope.timesheet.lunchOut) &&
      $scope.timesheet.lunchIn != null && $scope.timesheet.lunchOut != null) {
      lunchTime = getWorkDayHours($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    }
    if (isNaN($scope.timesheet.nightIn) && isNaN($scope.timesheet.nightOut) &&
      $scope.timesheet.nightIn != null && $scope.timesheet.nightOut != null) {
      nightTime = getWorkDayHours($scope.timesheet.nightIn, $scope.timesheet.nightOut);
    }
    // $scope.isInvalid($scope.timesheet.in, $scope.timesheet.out);
    // $scope.isInvalid($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    // $scope.isInvalid($scope.timesheet.nightIn, $scope.timesheet.nightOut);

    dayWork(dayTime, lunchTime, nightTime);
  };
  // check valid time format
  $scope.isInvalid = function(timeIn, timeOut) {
    if ((timeIn != null && timeOut == null) || (timeIn == null && timeOut != null) ||
     (timeIn === "" && timeOut != "") || (timeOut === "" && timeIn != "")) {
      $scope.errorMessage = "Please insert valid combination of input";
      return;
    }
  };
  // initialize method use when some one call detail url direct form browser or edit any
  // existing record
  var init = function() {
    $scope.date = $routeParams.date;
    var newDate = moment($scope.date, ["DD-MM-YYYY"]);
    var month = newDate.month();
    var year = newDate.year();
    var curDate = new Date();
    var curMonth = curDate.getMonth();
    var curYear = curDate.getFullYear();
    $scope.isReadonly = true;
    if ((month == curMonth) && (year == curYear)) {
      $scope.isReadonly = false;
    }
    if ($rootScope.detailTimesheetByIndex) {
      var monthlyDetailTimeSheet = $rootScope.detailTimesheetByIndex;
      var dayObject = monthlyDetailTimeSheet[$scope.date];
      if (dayObject.newEntry) {
        $scope.timesheet.workDate = $scope.date;
        $scope.timesheet = {'in': '09:00', 'out': '18:30', 'lunchIn': '12:30', 'lunchOut': '13:00', 'nightIn': '22:00', 'nightOut': '23:30'};
        $scope.totalHour = '10:30';
      }else if (monthlyDetailTimeSheet[$scope.date]) {
        $scope.timesheet.workDate = $scope.date;
        $scope.timesheet = monthlyDetailTimeSheet[$scope.date];
        $scope.totalHour = $scope.timesheet.totalHour;
      }
    }else {
      var dataPromise = UserService.getDayData($scope.date);
      dataPromise.then(function(response) {
        if (response.success) {
          var cookieObj = AuthService.getAccessToken();
          if(cookieObj) {
            AuthService.setAccessToken(cookieObj.token, cookieObj.userObj, response.expire);
          }
          $scope.timesheet = response.data[0];
          var nightOut = $scope.timesheet.nightOut;
          var num = 6;
          if (parseInt(nightOut, 10) <= num) {
            var timeArray = nightOut.toString().split(":");
            var dayHours = 24;
            var hours = dayHours + parseInt(timeArray[0], 10);
            var minutes = timeArray[1];
            $scope.timesheet.nightOut = hours + ":" + minutes;
          }else {
            $scope.timesheet = response.data[0];
          }
          $scope.totalHour = $scope.timesheet.totalHour;
        }else {
          $scope.errorMessage = response.error;
        }
      }, function() {
        $scope.errorMessage = "Something wrong on Server Please wait !";
      });
    }
  };

  $scope.getDayInStatus = function() {
    var dayin = detailview.dayin.value;
    var dayout = detailview.dayout.value;
    if ($scope.timesheet.lunchIn && dayin) {
      if ($scope.timesheet.lunchIn < dayin || $scope.timesheet.lunchOut > dayout) {
        $scope.lunchErrorMessage = "Looks like you are having lunch before coming to office!";
        return;
      }
    }
    if ($scope.timesheet.lunchIn && dayout) {
      if ($scope.timesheet.lunchIn > dayout || $scope.timesheet.lunchOut > dayout) {
        $scope.lunchErrorMessage = "Looks like you are having lunch after leaving office!";
        return;
      }
    }
  };

  $scope.getNightInStatus = function() {
    var nightin = detailview.nightin.value;
    if (nightin) {
      var night = nightin.split(':');
      var nu = 18;
      var ngtTime = parseInt(night[0], 10);
      if (ngtTime <= nu) {
        $scope.nightErrorMessage = "Looks like you are filling invalid night time!";
        return;
      }
    }
  };

  $scope.reset = function() {
    $scope.timesheet = null;
    $scope.dayWork = null;
    $scope.totalHour = null;
    $scope.resetMessage();
    $scope.detailview.$setPristine();
    $scope.detailview.$setUntouched();
    $('#submit-btn').text('Save').removeAttr("disabled");
  };

  $scope.resetMessage = function() {
    $scope.errorMessage = null;
    $scope.successMessage = null;
    $scope.nightErrorMessage = null;
    $scope.lunchErrorMessage = null;
  };
  init();
}]);
<commit_msg>224-cookies-expire<commit_after>/* global moment: false */
/* global app: false */
/* global detailview: false */

app.controller('detailViewController', ['$scope', '$location', '$rootScope', '$timeout', '$routeParams', 'UserService', 'CONFIG', 'AuthService',
function($scope, $location, $rootScope, $timeout, $routeParams, UserService, CONFIG, AuthService) {
  $scope.errorMessage = null;
  $scope.timesheet = {};
  // calculate total minutes of day work
  var getWorkDayHours = function(timeIn, timeOut) {
    var timeInarray = timeIn.toString().split(":");
    var minutes = 60;
    var minutesFirst = parseInt(timeInarray[0], 10) * minutes;
    var totalFirstMin = parseInt(minutesFirst, 10) + parseInt(timeInarray[1], 10);

    var timeOutarray = timeOut.toString().split(":");
    var minutesSecond = parseInt(timeOutarray[0], 10) * minutes;
    var totalSecondMin = parseInt(minutesSecond, 10) + parseInt(timeOutarray[1], 10);

    if (parseInt(totalSecondMin, 10) < parseInt(totalFirstMin, 10)) {
      $scope.errorMessage = "End Time should be greater than Start Time!";
      // return;
    }
    var totalTimeInMinutes = parseInt(totalSecondMin, 10) - parseInt(totalFirstMin, 10);
    return totalTimeInMinutes;
  };

  // save timesheet entry
  this.saveTimesheet = function() {
    // var flag = checkData($scope.timesheet);
    $scope.isInvalid($scope.timesheet.in, $scope.timesheet.out);
    $scope.isInvalid($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    $scope.isInvalid($scope.timesheet.nightIn, $scope.timesheet.nightOut);

    if ($scope.timesheet == null) {
      $scope.errorMessage = "Time fields Can't leave blank!!";
      $('#submit-btn').text('Save').removeAttr("disabled");
      return;
    }
    // totalworkingHour = $scope.getTotoalhours($scope.timesheet);
    if ($scope.errorMessage == null && $scope.lunchErrorMessage == null && $scope.nightErrorMessage == null) {
      var dataPromise = UserService.saveDetailTimeSheet($scope.timesheet, $scope.date);
      $('#submit-btn').text('Please wait...').attr('disabled', 'disabled');
      dataPromise.then(function(response) {
        if (response.success) {
          $scope.successMessage = "Successfully Saved!";
          $('#submit-btn').text('Save').removeAttr("disabled");
          $timeout(function() {
            $location.path("/usertimesheet");
          }, CONFIG.REDIRECT_TIMEOUT);
        }else {
          $scope.errorMessage = "Sorry ! You can fill data only for current week.";
          $('#submit-btn').text('Save').removeAttr("disabled");
        }
      }, function() {
        $scope.errorMessage = "Something wrong on Server Please wait !";
        $('#submit-btn').text('Save').removeAttr("disabled");
      });
    }
  };
  // calculate hours and minutes of day work
  var dayWork = function(dayTime, lunchTime, nightTime) {
    var reminDayTime = parseFloat(dayTime) - parseFloat(lunchTime);
    var totalWorkMinutes = parseFloat(reminDayTime) + parseFloat(nightTime);
    var minute = 60;
    var hours = parseInt(Math.floor(parseInt(totalWorkMinutes, 10)) / minute, 10);
    var minutes = parseInt(totalWorkMinutes, 10) % minute;
    $scope.totalHour = hours + "." + minutes;
    return $scope.totalHour;
  };
  // calculate total hours
  $scope.getTotalhours = function() {
    $scope.dayWork = null;
    $scope.resetMessage();
    var dayTime = 0;
    var lunchTime = 0;
    var nightTime = 0;
    if (isNaN($scope.timesheet.in) && isNaN($scope.timesheet.out) &&
      $scope.timesheet.in != null && $scope.timesheet.out != null) {
      dayTime = getWorkDayHours($scope.timesheet.in, $scope.timesheet.out);
    }
    if (isNaN($scope.timesheet.lunchIn) && isNaN($scope.timesheet.lunchOut) &&
      $scope.timesheet.lunchIn != null && $scope.timesheet.lunchOut != null) {
      lunchTime = getWorkDayHours($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    }
    if (isNaN($scope.timesheet.nightIn) && isNaN($scope.timesheet.nightOut) &&
      $scope.timesheet.nightIn != null && $scope.timesheet.nightOut != null) {
      nightTime = getWorkDayHours($scope.timesheet.nightIn, $scope.timesheet.nightOut);
    }
    // $scope.isInvalid($scope.timesheet.in, $scope.timesheet.out);
    // $scope.isInvalid($scope.timesheet.lunchIn, $scope.timesheet.lunchOut);
    // $scope.isInvalid($scope.timesheet.nightIn, $scope.timesheet.nightOut);

    dayWork(dayTime, lunchTime, nightTime);
  };
  // check valid time format
  $scope.isInvalid = function(timeIn, timeOut) {
    if ((timeIn != null && timeOut == null) || (timeIn == null && timeOut != null) ||
     (timeIn === "" && timeOut != "") || (timeOut === "" && timeIn != "")) {
      $scope.errorMessage = "Please insert valid combination of input";
      return;
    }
  };
  // initialize method use when some one call detail url direct form browser or edit any
  // existing record
  var init = function() {
    $scope.date = $routeParams.date;
    var newDate = moment($scope.date, ["DD-MM-YYYY"]);
    var month = newDate.month();
    var year = newDate.year();
    var curDate = new Date();
    var curMonth = curDate.getMonth();
    var curYear = curDate.getFullYear();
    $scope.isReadonly = true;
    if ((month == curMonth) && (year == curYear)) {
      $scope.isReadonly = false;
    }
    if ($rootScope.detailTimesheetByIndex) {
      var monthlyDetailTimeSheet = $rootScope.detailTimesheetByIndex;
      var dayObject = monthlyDetailTimeSheet[$scope.date];
      if (dayObject.newEntry) {
        $scope.timesheet.workDate = $scope.date;
        $scope.timesheet = {'in': '09:00', 'out': '18:30', 'lunchIn': '12:30', 'lunchOut': '13:00', 'nightIn': '22:00', 'nightOut': '23:30'};
        $scope.totalHour = '10:30';
      }else if (monthlyDetailTimeSheet[$scope.date]) {
        $scope.timesheet.workDate = $scope.date;
        $scope.timesheet = monthlyDetailTimeSheet[$scope.date];
        $scope.totalHour = $scope.timesheet.totalHour;
      }
    }else {
      var dataPromise = UserService.getDayData($scope.date);
      dataPromise.then(function(response) {
        if (response.success) {
          var cookieObj = AuthService.getAccessToken();
          if (cookieObj) {
            AuthService.setAccessToken(cookieObj.token, cookieObj.userObj, response.expire);
          }
          $scope.timesheet = response.data[0];
          var nightOut = $scope.timesheet.nightOut;
          var num = 6;
          if (parseInt(nightOut, 10) <= num) {
            var timeArray = nightOut.toString().split(":");
            var dayHours = 24;
            var hours = dayHours + parseInt(timeArray[0], 10);
            var minutes = timeArray[1];
            $scope.timesheet.nightOut = hours + ":" + minutes;
          }else {
            $scope.timesheet = response.data[0];
          }
          $scope.totalHour = $scope.timesheet.totalHour;
        }else {
          $scope.errorMessage = response.error;
        }
      }, function() {
        $scope.errorMessage = "Something wrong on Server Please wait !";
      });
    }
  };

  $scope.getDayInStatus = function() {
    var dayin = detailview.dayin.value;
    var dayout = detailview.dayout.value;
    if ($scope.timesheet.lunchIn && dayin) {
      if ($scope.timesheet.lunchIn < dayin || $scope.timesheet.lunchOut > dayout) {
        $scope.lunchErrorMessage = "Looks like you are having lunch before coming to office!";
        return;
      }
    }
    if ($scope.timesheet.lunchIn && dayout) {
      if ($scope.timesheet.lunchIn > dayout || $scope.timesheet.lunchOut > dayout) {
        $scope.lunchErrorMessage = "Looks like you are having lunch after leaving office!";
        return;
      }
    }
  };

  $scope.getNightInStatus = function() {
    var nightin = detailview.nightin.value;
    if (nightin) {
      var night = nightin.split(':');
      var nu = 18;
      var ngtTime = parseInt(night[0], 10);
      if (ngtTime <= nu) {
        $scope.nightErrorMessage = "Looks like you are filling invalid night time!";
        return;
      }
    }
  };

  $scope.reset = function() {
    $scope.timesheet = null;
    $scope.dayWork = null;
    $scope.totalHour = null;
    $scope.resetMessage();
    $scope.detailview.$setPristine();
    $scope.detailview.$setUntouched();
    $('#submit-btn').text('Save').removeAttr("disabled");
  };

  $scope.resetMessage = function() {
    $scope.errorMessage = null;
    $scope.successMessage = null;
    $scope.nightErrorMessage = null;
    $scope.lunchErrorMessage = null;
  };
  init();
}]);
<|endoftext|>