<commit_before>const ADD_LINK_URL = 'https://pinboard.in/add?showtags=yes&url={url}&title={title}&description={description}';
const READ_LATER_URL = 'https://pinboard.in/add?later=yes&noui=yes&jump=close&url={url}&title={title}';
const SAVE_TABS_URL = 'https://pinboard.in/tabs/save/';
const SHOW_TABS_URL = 'https://pinboard.in/tabs/show/';

var pin_window_id;
var toolbar_button_state = 'show_menu';

function prepare_pin_url(url_template, url, title, description) {
    var prepared_url = url_template.replace('{url}', encodeURIComponent(url));
    prepared_url = prepared_url.replace('{title}', encodeURIComponent(title));
    prepared_url = prepared_url.replace('{description}', encodeURIComponent(description));
    return prepared_url;
}

function show_notification(message) {
    browser.notifications.create({
        'type': 'basic',
        'title': 'Pinboard',
        'message': message,
        'iconUrl': 'pinboard_icon_48.png'
    });
}

function change_toolbar_button() {
    browser.storage.sync.get({'toolbar_button': 'show_menu'}).then(function (option) {
        if (option.toolbar_button != toolbar_button_state) {
            switch (option.toolbar_button) {

                case 'show_menu':
                    browser.browserAction.setPopup({popup: 'popup_menu.html'});
                    browser.browserAction.setTitle({title: 'Add to Pinboard'});
                    break;

                case 'save_dialog':
                    browser.browserAction.setPopup({popup: ''});
                    browser.browserAction.setTitle({title: 'Add to Pinboard'});
                    break;

                case 'read_later':
                    browser.browserAction.setPopup({popup: ''});
                    browser.browserAction.setTitle({title: 'Add to Pinboard (read later)'});
                    break;

            }
            toolbar_button_state = option.toolbar_button;
        }
    });
}

function change_context_menu() {
    browser.storage.sync.get({'context_menu_items': true}).then(function (option) {
        if (option.context_menu_items) {
            browser.contextMenus.create({
                id: 'save',
                title: 'Save...',
                contexts: ['link', 'page', 'selection']
            });
            browser.contextMenus.create({
                id: 'read_later',
                title: 'Read later',
                contexts: ['link', 'page', 'selection']
            });
            browser.contextMenus.create({
                id: 'save_tab_set',
                title: 'Save tab set...',
                contexts: ['page', 'selection']
            });
        } else {
            browser.contextMenus.removeAll();
        }
    });
}

function save_bookmark(action_url, action_callback) {
    browser.tabs.executeScript({code: 'getSelection().toString();'}).then(function (selected_text) {
        browser.tabs.query({currentWindow: true, active: true}).then(function (tabs) {
            var pin_url = prepare_pin_url(action_url, tabs[0].url, tabs[0].title, selected_text);
            action_callback(pin_url);
        });
    });
}

function open_pinboard_form(url) {
    browser.windows.getCurrent().then(function (bg_window) {
        browser.windows.create({
            url: url,
            type: 'popup',
            width: 750,
            height: 550,
            incognito: bg_window.incognito
        }).then(function (pin_window) { pin_window_id = pin_window.id; });
    });
}

function add_read_later(url) {

    browser.windows.getCurrent().then(function (bg_window) {

        if (bg_window.incognito) {

            // In private mode we actually have to open a window,
            // because Firefox doesn't support split incognito mode
            // and gets confused about cookie jars.
            open_pinboard_form(url);

        } else {

            fetch(url, {credentials: 'include'}).then(function (response) {
                if (response.redirected && response.url.startsWith('https://pinboard.in/popup_login/')) {
                    open_pinboard_form(response.url);
                } else if (response.status !== 200 || response.ok !== true) {
                    show_notification('FAILED TO ADD LINK. ARE YOU LOGGED-IN?');
                } else {
                    browser.storage.sync.get({show_notifications: true}).then(function (option) {
                        if (option.show_notifications) {
                            show_notification('Saved to read later.');
                        }
                    });
                }
            });
        }

    });

}

function save_tab_set() {
    browser.windows.getCurrent().then(function (bg_window) {
        if (bg_window.incognito) {
            show_notification("Due to a Firefox limitation, saving tab sets does not work in Private mode. Try normal mode!");
            return;
        }

        browser.windows.getAll({populate: true, windowTypes: ['normal']}).then(function (window_info) {
            var windows = [];
            for (var i = 0; i < window_info.length; i++) {
                var current_window_tabs = window_info[i].tabs;
                var tabs = [];
                for (var j = 0; j < current_window_tabs.length; j++) {
                    tabs.push({
                        title: current_window_tabs[j].title,
                        url: current_window_tabs[j].url
                    });
                }
                windows.push(tabs);
            }

            var payload = new FormData();
            payload.append('data', JSON.stringify({browser: 'ffox', windows: windows}));
            fetch(SAVE_TABS_URL, {method: 'POST', body: payload, credentials: 'include'}).then(function (response) {
                if (response.status !== 200 || response.ok !== true) {
                    show_notification('FAILED TO SAVE TAB SET.');
                } else {
                    browser.tabs.create({url: SHOW_TABS_URL});
                }
            });
        });
    });
}

function message_handler(message) {
    switch (message.message) {

        case 'save':
            save_bookmark(ADD_LINK_URL, open_pinboard_form);
            break;

        case 'read_later':
            save_bookmark(READ_LATER_URL, add_read_later);
            break;

        case 'save_tab_set':
            save_tab_set();
            break;

        case 'link_saved':
            browser.windows.remove(pin_window_id).then(function () { pin_window_id = undefined });
            browser.storage.sync.get({'show_notifications': true}).then(function (option) {
                if (option.show_notifications) {
                    show_notification('Link added to Pinboard');
                }
            });
            break;

        case 'toolbar_button_changed':
            change_toolbar_button();
            break;

        case 'context_menu_changed':
            change_context_menu();
            break;

    }
}

// Attach message event handler
browser.runtime.onMessage.addListener(message_handler);

// Toolbar button event handler
browser.browserAction.onClicked.addListener(function () {
    switch (toolbar_button_state) {
        case 'save_dialog':
            var message = 'save';
            break;
        case 'read_later':
            var message = 'read_later';
            break;
    }
    message_handler({'message': message});
});

// Context menu event handler
browser.contextMenus.onClicked.addListener(function (info, tab) {
    var url;
    var title = '';

    if (info.linkUrl) {
        url = info.linkUrl;
        if (info.linkText) {
            title = info.linkText.substr(0, 200);
            if (title.length < info.linkText.length) {
                title += '...';
            }
        }
    } else {
        url = info.pageUrl;
        title = tab.title;
    }

    switch (info.menuItemId) {
        case 'save':
            var pin_url = prepare_pin_url(ADD_LINK_URL, url, title, info.selectionText);
            open_pinboard_form(pin_url);
            break;

        case 'read_later':
            var pin_url = prepare_pin_url(READ_LATER_URL, url, title);
            add_read_later(pin_url);
            break;

        case 'save_tab_set':
            save_tab_set();
            break;
    }
});

// Change toolbar button function according to user preference
change_toolbar_button();

// Add or remove context menus according to user preference
change_context_menu();

<commit_msg>Added default values for optional parameters.<commit_after>const ADD_LINK_URL = 'https://pinboard.in/add?showtags=yes&url={url}&title={title}&description={description}';
const READ_LATER_URL = 'https://pinboard.in/add?later=yes&noui=yes&jump=close&url={url}&title={title}';
const SAVE_TABS_URL = 'https://pinboard.in/tabs/save/';
const SHOW_TABS_URL = 'https://pinboard.in/tabs/show/';

var pin_window_id;
var toolbar_button_state = 'show_menu';

function prepare_pin_url(url_template, url, title = '', description = '') {
    var prepared_url = url_template.replace('{url}', encodeURIComponent(url));
    prepared_url = prepared_url.replace('{title}', encodeURIComponent(title));
    prepared_url = prepared_url.replace('{description}', encodeURIComponent(description));
    return prepared_url;
}

function show_notification(message) {
    browser.notifications.create({
        'type': 'basic',
        'title': 'Pinboard',
        'message': message,
        'iconUrl': 'pinboard_icon_48.png'
    });
}

function change_toolbar_button() {
    browser.storage.sync.get({'toolbar_button': 'show_menu'}).then(function (option) {
        if (option.toolbar_button != toolbar_button_state) {
            switch (option.toolbar_button) {

                case 'show_menu':
                    browser.browserAction.setPopup({popup: 'popup_menu.html'});
                    browser.browserAction.setTitle({title: 'Add to Pinboard'});
                    break;

                case 'save_dialog':
                    browser.browserAction.setPopup({popup: ''});
                    browser.browserAction.setTitle({title: 'Add to Pinboard'});
                    break;

                case 'read_later':
                    browser.browserAction.setPopup({popup: ''});
                    browser.browserAction.setTitle({title: 'Add to Pinboard (read later)'});
                    break;

            }
            toolbar_button_state = option.toolbar_button;
        }
    });
}

function change_context_menu() {
    browser.storage.sync.get({'context_menu_items': true}).then(function (option) {
        if (option.context_menu_items) {
            browser.contextMenus.create({
                id: 'save',
                title: 'Save...',
                contexts: ['link', 'page', 'selection']
            });
            browser.contextMenus.create({
                id: 'read_later',
                title: 'Read later',
                contexts: ['link', 'page', 'selection']
            });
            browser.contextMenus.create({
                id: 'save_tab_set',
                title: 'Save tab set...',
                contexts: ['page', 'selection']
            });
        } else {
            browser.contextMenus.removeAll();
        }
    });
}

function save_bookmark(action_url, action_callback) {
    browser.tabs.executeScript({code: 'getSelection().toString();'}).then(function (selected_text) {
        browser.tabs.query({currentWindow: true, active: true}).then(function (tabs) {
            var pin_url = prepare_pin_url(action_url, tabs[0].url, tabs[0].title, selected_text);
            action_callback(pin_url);
        });
    });
}

function open_pinboard_form(url) {
    browser.windows.getCurrent().then(function (bg_window) {
        browser.windows.create({
            url: url,
            type: 'popup',
            width: 750,
            height: 550,
            incognito: bg_window.incognito
        }).then(function (pin_window) { pin_window_id = pin_window.id; });
    });
}

function add_read_later(url) {

    browser.windows.getCurrent().then(function (bg_window) {

        if (bg_window.incognito) {

            // In private mode we actually have to open a window,
            // because Firefox doesn't support split incognito mode
            // and gets confused about cookie jars.
            open_pinboard_form(url);

        } else {

            fetch(url, {credentials: 'include'}).then(function (response) {
                if (response.redirected && response.url.startsWith('https://pinboard.in/popup_login/')) {
                    open_pinboard_form(response.url);
                } else if (response.status !== 200 || response.ok !== true) {
                    show_notification('FAILED TO ADD LINK. ARE YOU LOGGED-IN?');
                } else {
                    browser.storage.sync.get({show_notifications: true}).then(function (option) {
                        if (option.show_notifications) {
                            show_notification('Saved to read later.');
                        }
                    });
                }
            });
        }

    });

}

function save_tab_set() {
    browser.windows.getCurrent().then(function (bg_window) {
        if (bg_window.incognito) {
            show_notification("Due to a Firefox limitation, saving tab sets does not work in Private mode. Try normal mode!");
            return;
        }

        browser.windows.getAll({populate: true, windowTypes: ['normal']}).then(function (window_info) {
            var windows = [];
            for (var i = 0; i < window_info.length; i++) {
                var current_window_tabs = window_info[i].tabs;
                var tabs = [];
                for (var j = 0; j < current_window_tabs.length; j++) {
                    tabs.push({
                        title: current_window_tabs[j].title,
                        url: current_window_tabs[j].url
                    });
                }
                windows.push(tabs);
            }

            var payload = new FormData();
            payload.append('data', JSON.stringify({browser: 'ffox', windows: windows}));
            fetch(SAVE_TABS_URL, {method: 'POST', body: payload, credentials: 'include'}).then(function (response) {
                if (response.status !== 200 || response.ok !== true) {
                    show_notification('FAILED TO SAVE TAB SET.');
                } else {
                    browser.tabs.create({url: SHOW_TABS_URL});
                }
            });
        });
    });
}

function message_handler(message) {
    switch (message.message) {

        case 'save':
            save_bookmark(ADD_LINK_URL, open_pinboard_form);
            break;

        case 'read_later':
            save_bookmark(READ_LATER_URL, add_read_later);
            break;

        case 'save_tab_set':
            save_tab_set();
            break;

        case 'link_saved':
            browser.windows.remove(pin_window_id).then(function () { pin_window_id = undefined });
            browser.storage.sync.get({'show_notifications': true}).then(function (option) {
                if (option.show_notifications) {
                    show_notification('Link added to Pinboard');
                }
            });
            break;

        case 'toolbar_button_changed':
            change_toolbar_button();
            break;

        case 'context_menu_changed':
            change_context_menu();
            break;

    }
}

// Attach message event handler
browser.runtime.onMessage.addListener(message_handler);

// Toolbar button event handler
browser.browserAction.onClicked.addListener(function () {
    switch (toolbar_button_state) {
        case 'save_dialog':
            var message = 'save';
            break;
        case 'read_later':
            var message = 'read_later';
            break;
    }
    message_handler({'message': message});
});

// Context menu event handler
browser.contextMenus.onClicked.addListener(function (info, tab) {
    var url;
    var title = '';

    if (info.linkUrl) {
        url = info.linkUrl;
        if (info.linkText) {
            title = info.linkText.substr(0, 200);
            if (title.length < info.linkText.length) {
                title += '...';
            }
        }
    } else {
        url = info.pageUrl;
        title = tab.title;
    }

    switch (info.menuItemId) {
        case 'save':
            var pin_url = prepare_pin_url(ADD_LINK_URL, url, title, info.selectionText);
            open_pinboard_form(pin_url);
            break;

        case 'read_later':
            var pin_url = prepare_pin_url(READ_LATER_URL, url, title);
            add_read_later(pin_url);
            break;

        case 'save_tab_set':
            save_tab_set();
            break;
    }
});

// Change toolbar button function according to user preference
change_toolbar_button();

// Add or remove context menus according to user preference
change_context_menu();

<|endoftext|>


<commit_before>/*global exports, require */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx schema helper
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2015 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Alan Plum
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var _ = require('underscore');

function toJSONSchema(id, schema) {
  'use strict';
  var required = [],
    properties = {};

  if (schema) {
    if (
      typeof schema.toJSONSchema === 'function' &&
      schema.toJSONSchema !== toJSONSchema &&
      schema.toJSONSchema !== require('org/arangodb/foxx/model').Model.toJSONSchema
    ) {
      // allow overriding toJSONSchema.
      return schema.toJSONSchema(id);
    }
    if (!schema.isJoi) {
      // assume schema is a Model
      schema = schema.prototype.schema;
    }
    _.each(schema, function (attributeSchema, attributeName) {
      var description = attributeSchema.describe(),
        jsonSchema = {type: description.type},
        rules = description.rules,
        flags = description.flags;

      if (flags && flags.presence === 'required') {
        jsonSchema.required = true;
        required.push(attributeName);
      }

      if (
        jsonSchema.type === 'number' &&
          _.isArray(rules) &&
          _.some(rules, function (rule) {
            return rule.name === 'integer';
          })
      ) {
        jsonSchema.type = 'integer';
      }

      properties[attributeName] = jsonSchema;
    });
  }

  return {
    id: id,
    required: required,
    properties: properties
  };
}

exports.toJSONSchema = toJSONSchema;<commit_msg>Adjust toJSONSchema to better cope with joi schemas.<commit_after>/*global exports, require */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx schema helper
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2015 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Alan Plum
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var _ = require('underscore'),
  joi = require('joi');

function toJSONSchema(id, schema) {
  'use strict';
  var jsonSchema = {
    id: id,
    required: [],
    properties: {}
  };

  if (!schema) {
    return jsonSchema;
  }

  if (
    typeof schema.toJSONSchema === 'function' &&
    schema.toJSONSchema !== toJSONSchema &&
    schema.toJSONSchema !== require('org/arangodb/foxx/model').Model.toJSONSchema
  ) {
    // allow overriding toJSONSchema.
    return schema.toJSONSchema(id);
  }

  if (typeof schema === 'function') {
    // assume schema is a Model
    schema = schema.prototype.schema || {};
  }

  if (!schema.isJoi) {
    schema = joi.object().keys(schema);
  }

  var description = schema.describe();

  if (description.type !== 'object') {
    return jsonSchema;
  }

  _.each(schema.children, function (attributeDescription, attributeName) {
    var attributeSchema = {type: attributeDescription.type},
      rules = attributeDescription.rules,
      flags = attributeDescription.flags;

    if (flags && flags.presence === 'required') {
      attributeSchema.required = true;
      jsonSchema.required.push(attributeName);
    }

    if (
      attributeSchema.type === 'number' &&
        _.isArray(rules) &&
        _.some(rules, function (rule) {
          return rule.name === 'integer';
        })
    ) {
      attributeSchema.type = 'integer';
    }

    jsonSchema.properties[attributeName] = attributeSchema;
  });

  return jsonSchema;
}

exports.toJSONSchema = toJSONSchema;<|endoftext|>


<commit_before>'use strict';

var acadYearStartDates = {
  '16/17' : new Date('August 1, 2016'),
  '15/16' : new Date('August 3, 2015'),
  '14/15' : new Date('August 4, 2014')
};

// Constant variables
var oneWeekTime = 1000 * 60 * 60 * 24 * 7;
var sem1 = 'Semester 1';
var sem2 = 'Semester 2';
var special1 = 'Special Term I';
var special2 = 'Special Term II';

module.exports = {

  currentAcadYear: function (date) {
    var years = Object.keys(acadYearStartDates);
    years.sort().reverse();

    for (var i = 0; i < years.length; i++) {
      var year = years[i];
      if (date >= acadYearStartDates[year]) {
        return {year: year, startDate: acadYearStartDates[year]};
      }
    }
  },

  currentAcadSem: function (acadWeekNumber) {
    if (acadWeekNumber <= 23) {
      return sem1;
    } else if (acadWeekNumber <= 40 || acadWeekNumber === 53) {
      return sem2;
    } else if (acadWeekNumber <= 46) {
      return special1;
    } else {
      // acadWeekNumber <= 52
      return special2;
    }
  },

  /**
   * Compute the current academic week and return in json format
   * @param  {Date} date
   * @return {json} {
                      year: "15/16",
                      sem: 'Semester 1'|'Semester 2'|'Special Sem 1'|'Special Sem 2',
                      type: 'Instructional'|'Reading'|'Examination'|'Recess'|'Vacation'|'Orientation',
                      num: <weekNum>
                    }
   */
  currentAcadWeek: function (date) {
    var currentAcad = this.currentAcadYear(date);
    var acadYear = currentAcad.year;
    var acadYearStartDate = currentAcad.startDate;

    var acadWeekNumber = Math.ceil((date.getTime() - acadYearStartDate.getTime() + 1) / oneWeekTime);
    var semester = this.currentAcadSem(acadWeekNumber);

    var weekType;
    var weekNumber = 0;

    switch (semester) {
      case sem2: // Semester 2 starts 22 weeks after Week 1 of semester 1
        acadWeekNumber -= 22;
      case sem1:
        if (acadWeekNumber === 1) {
          weekType = 'Orientation';
          break;
        }
        if (acadWeekNumber > 18) {
          weekType = 'Vacation';
          weekNumber = acadWeekNumber - 18;
          if (weekNumber > 5) {
            // This means it is the 53th week of the AY, and this week is Vacation.
            // This happens 5 times every 28 years.
            weekNumber = 0;
          }
          break;
        }
        acadWeekNumber -= 1;
        var week = this.acadWeekOfNormalSem(acadWeekNumber);
        weekType = week.weekType;
        weekNumber = week.weekNumber;
        break;
      case special2: // Special Term II starts 6 weeks after Special Term I
        acadWeekNumber -= 6;
      case special1: // Special Term I starts on week 41 of the AY
        acadWeekNumber -= 40;
        weekType = 'Instructional';
        weekNumber = acadWeekNumber;
        break;
    }

    return {
      year: acadYear,
      sem: semester,
      type: weekType,
      num: weekNumber
    };
  },

  acadWeekOfNormalSem: function (acadWeekNumber) {
    switch (acadWeekNumber) {
      case 7:
        return {weekType: 'Recess', weekNumber: 0};
      case 15:
        return {weekType: 'Reading', weekNumber : 0};
      case 16:
      case 17:
        return {weekType: 'Examination', weekNumber: acadWeekNumber - 15};
      default:
        var weekNumber = acadWeekNumber;
        if (weekNumber >= 8) { // For weeks after recess week
          weekNumber--;
        }
        return {weekType: 'Instructional', weekNumber: weekNumber};
    }
  }
};
<commit_msg>Capitalise constants for academicCalendar.js<commit_after>'use strict';

var acadYearStartDates = {
  '16/17' : new Date('August 1, 2016'),
  '15/16' : new Date('August 3, 2015'),
  '14/15' : new Date('August 4, 2014')
};

// Constants
var ONE_WEEK_TIME = 1000 * 60 * 60 * 24 * 7;
var SEM1 = 'Semester 1';
var SEM2 = 'Semester 2';
var SPECIAL1 = 'Special Term I';
var SPECIAL2 = 'Special Term II';

module.exports = {

  currentAcadYear: function (date) {
    var years = Object.keys(acadYearStartDates);
    years.sort().reverse();

    for (var i = 0; i < years.length; i++) {
      var year = years[i];
      if (date >= acadYearStartDates[year]) {
        return {year: year, startDate: acadYearStartDates[year]};
      }
    }
  },

  currentAcadSem: function (acadWeekNumber) {
    if (acadWeekNumber <= 23) {
      return SEM1;
    } else if (acadWeekNumber <= 40 || acadWeekNumber === 53) {
      return SEM2;
    } else if (acadWeekNumber <= 46) {
      return SPECIAL1;
    } else {
      // acadWeekNumber <= 52
      return SPECIAL2;
    }
  },

  /**
   * Compute the current academic week and return in json format
   * @param  {Date} date
   * @return {json} {
                      year: "15/16",
                      sem: 'Semester 1'|'Semester 2'|'Special Sem 1'|'Special Sem 2',
                      type: 'Instructional'|'Reading'|'Examination'|'Recess'|'Vacation'|'Orientation',
                      num: <weekNum>
                    }
   */
  currentAcadWeek: function (date) {
    var currentAcad = this.currentAcadYear(date);
    var acadYear = currentAcad.year;
    var acadYearStartDate = currentAcad.startDate;

    var acadWeekNumber = Math.ceil((date.getTime() - acadYearStartDate.getTime() + 1) / ONE_WEEK_TIME);
    var semester = this.currentAcadSem(acadWeekNumber);

    var weekType;
    var weekNumber = 0;

    switch (semester) {
      case SEM2: // Semester 2 starts 22 weeks after Week 1 of semester 1
        acadWeekNumber -= 22;
      case SEM1:
        if (acadWeekNumber === 1) {
          weekType = 'Orientation';
          break;
        }
        if (acadWeekNumber > 18) {
          weekType = 'Vacation';
          weekNumber = acadWeekNumber - 18;
          if (weekNumber > 5) {
            // This means it is the 53th week of the AY, and this week is Vacation.
            // This happens 5 times every 28 years.
            weekNumber = 0;
          }
          break;
        }
        acadWeekNumber -= 1;
        var week = this.acadWeekOfNormalSem(acadWeekNumber);
        weekType = week.weekType;
        weekNumber = week.weekNumber;
        break;
      case SPECIAL2: // Special Term II starts 6 weeks after Special Term I
        acadWeekNumber -= 6;
      case SPECIAL1: // Special Term I starts on week 41 of the AY
        acadWeekNumber -= 40;
        weekType = 'Instructional';
        weekNumber = acadWeekNumber;
        break;
    }

    return {
      year: acadYear,
      sem: semester,
      type: weekType,
      num: weekNumber
    };
  },

  acadWeekOfNormalSem: function (acadWeekNumber) {
    switch (acadWeekNumber) {
      case 7:
        return {weekType: 'Recess', weekNumber: 0};
      case 15:
        return {weekType: 'Reading', weekNumber : 0};
      case 16:
      case 17:
        return {weekType: 'Examination', weekNumber: acadWeekNumber - 15};
      default:
        var weekNumber = acadWeekNumber;
        if (weekNumber >= 8) { // For weeks after recess week
          weekNumber--;
        }
        return {weekType: 'Instructional', weekNumber: weekNumber};
    }
  }
};
<|endoftext|>


<commit_before>/**
 * @file index.js
 * XSD Schema to HTML5 Web Form
 * @author George Bouris <gb@eworx.gr>
 * @copyright Copyright (C) 2017 EEA, Eworx, George Bouris. All rights reserved.
 */

'use strict';

// import heapdump from 'heapdump';  //debug library
import fs from 'fs';
import path from 'path';
import ncp from 'ncp';
import rimraf from 'rimraf';
import openurl from 'openurl';
import express from 'express';
import uglify from "uglify-js";
import uglifycss from "uglifycss";
import webshot from "webshot";
import XSDWebFormParser from './lib/xsdwebform.parser.js'
import XSDWebFormParserError from './lib/xsdwebform.parser.error.js'
import XSDWebFormParserTest from './lib/xsdwebform.parser.test.js'

/**
 * Class XSDWebForm
 * XSD Schema to HTML5
 */
export default class XSDWebForm {

	/**
	 * Class constructor
	 * Check for arguments
	 */
	constructor(args) {
		return new Promise ( (resolve, reject) => {

			//Version
			this.Vesrion="0.2";

			//logging
			this.showLog = true;
			this.verbose = true;
			this.showXSDLog = true;

			//Test Server
			this.serverPort =3001;

			//Build directory
			this.buildPath = "build/";
			// Input file variable
			var xsdFile = null;
			// HTML Input file variable
			var xmlHtmlFile = null;
			// Open the default browser when build is completed
			this.autoOpenOutput = false;

			// Check for [-f file] [-a | open browser after build] input
			args.forEach(
				(item, index) => {
					if (item === '-f') {
						xsdFile = args[index + 1];
						return;
					}
					if (item === '-ul') {
						this.showLog = false;
						this.verbose = false;
						return;
					}
					if (item === '-l') {
						this.showXSDLog = false;
						return;
					}
					if (item === '-a') {
						this.autoOpenOutput = true;
						return;
					}
				});

			// If not file input
			if (!xsdFile) {
				xsdFile = "./test/test";
			}

			if (!xsdFile.endsWith(".xsd"))
				xsdFile += ".xsd";

			// Lookup for base file name. Needed to check for (formname).form.xml file. Also, if file is named form.xsd then .js,.css filets etc are going to be named form.js form.css
			this.baseFileName = path.basename(xsdFile);
			this.baseFileName = this.baseFileName.substring(0, this.baseFileName.length - 4);
			this.basePath = path.dirname(xsdFile);

			xmlHtmlFile = this.baseFileName + ".form.xml";

			// XSDWebFormParser
			this.parser = new XSDWebFormParser(this.baseFileName, this.showLog, this.verbose, this.showXSDLog);

			// XSDWebFormTest
			this.tester = new XSDWebFormParserTest(this.serverPort, this.baseFileName, this.showLog, this.verbose);

			// Create (/clean) Build directory and move files
			this.prepareJSFiles().then((res) => {
				try {
					// After Build directory preperation, parse the document
					this.parseFiles(xsdFile, xmlHtmlFile, this.basePath).then ( (response) => {
						var app = express();
						var parent = this;
						var filePath = path.join( __dirname.substring(0, __dirname.length - 3), this.buildPath);

						// Start test web server in order to view the HTML5 file result.
						app.use(express.static(filePath))
							.listen(parent.serverPort, function () {
								if (parent.showLog) {
									console.log(`\x1b[1m\x1b[37mTest web server is listening on port ${parent.serverPort}\x1b[0m`);
									console.log(`http://localhost:${parent.serverPort}/${parent.baseFileName}.html\n\n`);
								}
								resolve(parent);
							});
						});
				} catch (err) {
					XSDWebFormParserError.reportError(err);
					reject(this);
				}
			});
		});
	};

	/**
	 * parseFiles - Parse XSD and XML files
	 * Open .xsd and .form.xml files and read the contents
	 * @param xsdFile
	 * @param xmlHtmlFile
	 */
	parseFiles(xsdFile, xmlHtmlFile, filePath) {
		return new Promise ( (resolve, reject) => {
			var xObject = {
				xfile: xsdFile,
				xdata: '',
				hfile: xmlHtmlFile,
				hdata: ''
			};

			this.getFile(xsdFile).then((res) => {
				xObject.xdata = res;
				this.getFile(filePath + "/" + xmlHtmlFile).then((res) => {
					xObject.hdata = res;
					// Parse file content
					this.parser.parse(xObject);

					// Create HTML file
					this.createFile(this.buildPath + this.baseFileName + ".html", this.getHeader() + this.parser.getHTMLOutput() + this.getFooter() ). then ( () => {
						this.getFile(__dirname + "/lng/ct-codelists-en.json").then((langs) => {
							langs = JSON.parse(langs);
							let langData = this.parser.getFullTextContent();
							langs.CTCodelists.Languages.item.forEach((item) => {
								this.createFile(this.buildPath + "lng/" + this.baseFileName + "." + item.code + ".lang.json", langData, false);
							});
							if (this.showLog) {
								this.createFile(this.buildPath + "log/" + this.baseFileName + ".log.html", this.parser.logger.getHtmlLog(), false);
								webshot(`http://localhost:3001/${this.baseFileName}.html`,  this.buildPath + "log/scrnsht.png", {  shotSize : { width: 'all', height: 'all'} }, (res) => { return; });
							}
							this.tester.test().then ((res) => {
								let cres = "\x1b[32m ✓\x1b[2m ";
								let cresPlus = "";
								if (res.status !== 'PASS') {
									cres = "\x1b[31mx ";
									cresPlus += "\n\x1b[37m\x1b[1mErrors: \x1b[2m" + res.errors.map((item) => {
										return `\n\tLine: ${item.line}, Column: ${item.column}\n\t\x1b[31m\x1b[1m${item.message}\n\t\x1b[0m\x1b[37m${item.solution}\n\x1b[2m`
									}).join("");
									cresPlus += "\n\x1b[37m\x1b[1m\nPotential Problems: \x1b[2m" + res.potentialProblems.map((item) => {
										return `\n\tLine: ${item.line}, Column: ${item.column}\n\t\x1b[31m\x1b[1m${item.message}\n\t\x1b[0m\x1b[37m${item.source}\n\x1b[2m`
									}).join("");
								}
								console.log(`\x1b[0m\x1b[37mWCAG 2-AA Accessibility checking: \x1b[1m${cres}${res.status} ${cresPlus}\n`);
							});

							resolve();
						});
					});

					// Create XSLT output
					this.createFile(this.buildPath + "xslt/" + this.baseFileName + ".xslt", this.parser.getXSLTOutput());
					this.createFile(this.buildPath + "xslt/" + this.baseFileName + ".xml", this.parser.getXSLTXMLOutput(), false);

					// Open browser
					if (this.autoOpenOutput)
						openurl.open(`http://localhost:3001/${this.baseFileName}.html`);
				});
			});
		});
	}

	/**
	 * prepareJSFiles - Copy JS folder to build
	 */
	prepareJSFiles() {
		var parent = this;
		return new Promise((resolve, reject) => {
			rimraf(parent.buildPath, fs, function() {
				if (!fs.existsSync(parent.buildPath)) {
					fs.mkdirSync(parent.buildPath);
					fs.mkdirSync(parent.buildPath+"xslt");
					fs.mkdirSync(parent.buildPath+"log");
					ncp(__dirname + "/lng/", parent.buildPath + "lng", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
					});
					ncp(__dirname + "/test/", parent.buildPath + "test", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
					});
					ncp(__dirname + "/assets/", parent.buildPath + "assets", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
						ncp(__dirname + "/webform.js", parent.buildPath + parent.baseFileName + ".webform.js", function(err) {
							parent.getFile(__dirname + "/webform.js").then ( (data) => {
								parent.createFile(parent.buildPath + parent.baseFileName + ".webform.min.js", uglify.minify(data).code, false);
							});
							if (err) {
								console.error(err);
								reject(err);
							}
							ncp(__dirname + "/webform.css", parent. buildPath + parent.baseFileName + ".webform.css", function(err) {
								let uglified = uglifycss.processFiles(
								[ __dirname + "/webform.css" ],
									{ maxLineLen: 500, expandVars: true }
								);
								parent.createFile(parent.buildPath + parent.baseFileName +  ".webform.min.css", uglified, false);
								if (err) {
									console.error(err);
									reject(err);
								}
							resolve();
							});
						});
					});
				}
			});
		});
	}

	/**
	 * setHeaer
	 * @param pageTitle
	 */

	getHeader() {

		return `
<!DOCTYPE html>

<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta name="Publisher" content="EEA, The European Environment Agency" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{'pagetitle' | translate}}</title>

<link rel="stylesheet" type="text/css" href="./assets/css/webform.all.min.css"/>
<link rel="stylesheet" type="text/css" href="./${this.baseFileName}.webform.min.css"/>
<link rel="stylesheet" type="text/css" href="http://www.eionet.europa.eu/styles/eionet2007/print.css" media="print" />
<link rel="stylesheet" type="text/css" href="http://www.eionet.europa.eu/styles/eionet2007/handheld.css" media="handheld" />

<link rel="shortcut icon" type="image/x-icon" href="./assets/img/favicon.ico"/>

<eea-header></eea-header>

EEA

Web Form

	<eea-language scp="this" lang="{{selectedLanguage}}" chooselanguage="{{'chooselanguage' | translate}}"></eea-language>

#

{{'formtitle' | translate}}

	`;
	}

	/**
	 * getFooter
	 */
	getFooter() {

		return `

<eea-toolbar scp="this" off="{{'off' | translate}}" on="{{'on' | translate}}" save="{{'save' | translate}}" printpreview="{{'printpreview' | translate}}" close="{{'close' | translate}}" validation="{{'validation' | translate}}"></eea-toolbar>

		<eea-form-build date="${new Date()}" user="${process.env.USER}"></eea-form-build>

`;
	}

	/**
	 * getFile
	 * @param file
	 */
	getFile(file) {
		return new Promise((resolve, reject) => {
			fs.readFile(file, 'utf8', (err, data) => {
				if (err) {
					XSDWebFormParserError.reportError(`No such file or directory ${err.path}\n`);
					reject(err);
				}
				resolve(data);
			});
		});
	}

	/**
	 * createFile - Save output file
	 * @param filename
	 * @param content
	 * @param log
	 */
	createFile(filename, content, log = true) {
		var parent = this;
		return new Promise((resolve, reject) => {
			fs.writeFile(filename, content, function(err) {
				if (err) {
					console.log(err);
					reject(err);
				} else {
					if (parent.showLog && log)
						console.log(`\x1b[2m\x1b[36mThe file ${filename} was saved\x1b[0m\n`);
					resolve();
				}
			});
		});
	}
}

var xsdWebForm = new XSDWebForm(process.argv);

module.exports.xsdWebForm = xsdWebForm;

// heapdump.writeSnapshot('./' + Date.now() + '.heapsnapshot');<commit_msg>Updated Test script<commit_after>/**
 * @file index.js
 * XSD Schema to HTML5 Web Form
 * @author George Bouris <gb@eworx.gr>
 * @copyright Copyright (C) 2017 EEA, Eworx, George Bouris. All rights reserved.
 */

'use strict';

// import heapdump from 'heapdump';  //debug library
import fs from 'fs';
import path from 'path';
import ncp from 'ncp';
import rimraf from 'rimraf';
import openurl from 'openurl';
import express from 'express';
import uglify from "uglify-js";
import uglifycss from "uglifycss";
import webshot from "webshot";
import XSDWebFormParser from './lib/xsdwebform.parser.js'
import XSDWebFormParserError from './lib/xsdwebform.parser.error.js'
import XSDWebFormParserTest from './lib/xsdwebform.parser.test.js'

/**
 * Class XSDWebForm
 * XSD Schema to HTML5
 */
export default class XSDWebForm {

	/**
	 * Class constructor
	 * Check for arguments
	 */
	constructor(args) {
		return new Promise ( (resolve, reject) => {

			//Version
			this.Vesrion="0.2";

			//logging
			this.showLog = true;
			this.verbose = true;
			this.showXSDLog = true;

			//Test Server
			this.serverPort =3001;

			//Build directory
			this.buildPath = "build/";
			// Input file variable
			var xsdFile = null;
			// HTML Input file variable
			var xmlHtmlFile = null;
			// Open the default browser when build is completed
			this.autoOpenOutput = false;

			// Check for [-f file] [-a | open browser after build] input
			args.forEach(
				(item, index) => {
					if (item === '-f') {
						xsdFile = args[index + 1];
						return;
					}
					if (item === '-ul') {
						this.showLog = false;
						this.verbose = false;
						return;
					}
					if (item === '-l') {
						this.showXSDLog = false;
						return;
					}
					if (item === '-a') {
						this.autoOpenOutput = true;
						return;
					}
				});

			// If not file input
			if (!xsdFile) {
				xsdFile = "./test/test";
			}

			if (!xsdFile.endsWith(".xsd"))
				xsdFile += ".xsd";

			// Lookup for base file name. Needed to check for (formname).form.xml file. Also, if file is named form.xsd then .js,.css filets etc are going to be named form.js form.css
			this.baseFileName = path.basename(xsdFile);
			this.baseFileName = this.baseFileName.substring(0, this.baseFileName.length - 4);
			this.basePath = path.dirname(xsdFile);

			xmlHtmlFile = this.baseFileName + ".form.xml";

			// XSDWebFormParser
			this.parser = new XSDWebFormParser(this.baseFileName, this.showLog, this.verbose, this.showXSDLog);

			// XSDWebFormTest
			this.tester = new XSDWebFormParserTest(this.serverPort, this.baseFileName, this.showLog, this.verbose);

			// Create (/clean) Build directory and move files
			this.prepareJSFiles().then((res) => {
				try {
					// After Build directory preperation, parse the document
					this.parseFiles(xsdFile, xmlHtmlFile, this.basePath).then ( (response) => {
						var app = express();
						var parent = this;
						var filePath = path.join( __dirname.substring(0, __dirname.length - 3), this.buildPath);

						// Start test web server in order to view the HTML5 file result.
						app.use(express.static(filePath))
							.listen(parent.serverPort, function () {
								if (parent.showLog) {
									console.log(`\x1b[1m\x1b[37mTest web server is listening on port ${parent.serverPort}\x1b[0m`);
									console.log(`http://localhost:${parent.serverPort}/${parent.baseFileName}.html\n\n`);
								}
								resolve(parent);
							});
						});
				} catch (err) {
					XSDWebFormParserError.reportError(err);
					reject(this);
				}
			});
		});
	};

	/**
	 * parseFiles - Parse XSD and XML files
	 * Open .xsd and .form.xml files and read the contents
	 * @param xsdFile
	 * @param xmlHtmlFile
	 */
	parseFiles(xsdFile, xmlHtmlFile, filePath) {
		return new Promise ( (resolve, reject) => {
			var xObject = {
				xfile: xsdFile,
				xdata: '',
				hfile: xmlHtmlFile,
				hdata: ''
			};

			this.getFile(xsdFile).then((res) => {
				xObject.xdata = res;
				this.getFile(filePath + "/" + xmlHtmlFile).then((res) => {
					xObject.hdata = res;
					// Parse file content
					this.parser.parse(xObject);

					// Create HTML file
					this.createFile(this.buildPath + this.baseFileName + ".html", this.getHeader() + this.parser.getHTMLOutput() + this.getFooter() ). then ( () => {
						this.getFile(__dirname + "/lng/ct-codelists-en.json").then((langs) => {
							langs = JSON.parse(langs);
							let langData = this.parser.getFullTextContent();
							langs.CTCodelists.Languages.item.forEach((item) => {
								this.createFile(this.buildPath + "lng/" + this.baseFileName + "." + item.code + ".lang.json", langData, false);
							});
							if (this.showLog) {
								this.createFile(this.buildPath + "log/" + this.baseFileName + ".log.html", this.parser.logger.getHtmlLog(), false);
								webshot(`http://localhost:3001/${this.baseFileName}.html`,  this.buildPath + "log/scrnsht.png", { shotSize : { width: 'all', height: 'all'} }, (res) => { return; });
							}
							this.tester.test().then ((res) => {
								let cres = "\x1b[32m ✓\x1b[2m ";
								let cresPlus = "";
								if (res.status !== 'PASS') {
									cres = "\x1b[31mx ";
									cresPlus += "\n\x1b[37m\x1b[1mErrors: \x1b[2m" + res.errors.map((item) => {
										return `\n\tLine: ${item.line}, Column: ${item.column}\n\t\x1b[31m\x1b[1m${item.message}\n\t\x1b[0m\x1b[37m${item.solution}\n\x1b[2m`
									}).join("");
									cresPlus += "\n\x1b[37m\x1b[1m\nPotential Problems: \x1b[2m" + res.potentialProblems.map((item) => {
										return `\n\tLine: ${item.line}, Column: ${item.column}\n\t\x1b[31m\x1b[1m${item.message}\n\t\x1b[0m\x1b[37m${item.source}\n\x1b[2m`
									}).join("");
								}
								console.log(`\x1b[0m\x1b[37mWCAG 2-AA Accessibility checking: \x1b[1m${cres}${res.status} ${cresPlus}\n`);
							});

							resolve();
						});
					});

					// Create XSLT output
					this.createFile(this.buildPath + "xslt/" + this.baseFileName + ".xslt", this.parser.getXSLTOutput());
					this.createFile(this.buildPath + "xslt/" + this.baseFileName + ".xml", this.parser.getXSLTXMLOutput(), false);

					// Open browser
					if (this.autoOpenOutput)
						openurl.open(`http://localhost:3001/${this.baseFileName}.html`);
				});
			});
		});
	}

	/**
	 * prepareJSFiles - Copy JS folder to build
	 */
	prepareJSFiles() {
		var parent = this;
		return new Promise((resolve, reject) => {
			rimraf(parent.buildPath, fs, function() {
				if (!fs.existsSync(parent.buildPath)) {
					fs.mkdirSync(parent.buildPath);
					fs.mkdirSync(parent.buildPath+"xslt");
					fs.mkdirSync(parent.buildPath+"log");
					ncp(__dirname + "/lng/", parent.buildPath + "lng", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
					});
					ncp(__dirname + "/test/", parent.buildPath + "test", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
					});
					ncp(__dirname + "/assets/", parent.buildPath + "assets", function(err) {
						if (err) {
							console.error(err);
							reject(err);
						}
						ncp(__dirname + "/webform.js", parent.buildPath + parent.baseFileName + ".webform.js", function(err) {
							parent.getFile(__dirname + "/webform.js").then ( (data) => {
								parent.createFile(parent.buildPath + parent.baseFileName + ".webform.min.js", uglify.minify(data).code, false);
							});
							if (err) {
								console.error(err);
								reject(err);
							}
							ncp(__dirname + "/webform.css", parent. buildPath + parent.baseFileName + ".webform.css", function(err) {
								let uglified = uglifycss.processFiles(
								[ __dirname + "/webform.css" ],
									{ maxLineLen: 500, expandVars: true }
								);
								parent.createFile(parent.buildPath + parent.baseFileName +  ".webform.min.css", uglified, false);
								if (err) {
									console.error(err);
									reject(err);
								}
							resolve();
							});
						});
					});
				}
			});
		});
	}

	/**
	 * setHeaer
	 * @param pageTitle
	 */

	getHeader() {

		return `
<!DOCTYPE html>

<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta name="Publisher" content="EEA, The European Environment Agency" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{'pagetitle' | translate}}</title>

<link rel="stylesheet" type="text/css" href="./assets/css/webform.all.min.css"/>
<link rel="stylesheet" type="text/css" href="./${this.baseFileName}.webform.min.css"/>
<link rel="stylesheet" type="text/css" href="http://www.eionet.europa.eu/styles/eionet2007/print.css" media="print" />
<link rel="stylesheet" type="text/css" href="http://www.eionet.europa.eu/styles/eionet2007/handheld.css" media="handheld" />

<link rel="shortcut icon" type="image/x-icon" href="./assets/img/favicon.ico"/>

<eea-header></eea-header>

EEA

Web Form

	<eea-language scp="this" lang="{{selectedLanguage}}" chooselanguage="{{'chooselanguage' | translate}}"></eea-language>

#

{{'formtitle' | translate}}

	`;
	}

	/**
	 * getFooter
	 */
	getFooter() {

		return `

<eea-toolbar scp="this" off="{{'off' | translate}}" on="{{'on' | translate}}" save="{{'save' | translate}}" printpreview="{{'printpreview' | translate}}" close="{{'close' | translate}}" validation="{{'validation' | translate}}"></eea-toolbar>

		<eea-form-build date="${new Date()}" user="${process.env.USER}"></eea-form-build>

`;
	}

	/**
	 * getFile
	 * @param file
	 */
	getFile(file) {
		return new Promise((resolve, reject) => {
			fs.readFile(file, 'utf8', (err, data) => {
				if (err) {
					XSDWebFormParserError.reportError(`No such file or directory ${err.path}\n`);
					reject(err);
				}
				resolve(data);
			});
		});
	}

	/**
	 * createFile - Save output file
	 * @param filename
	 * @param content
	 * @param log
	 */
	createFile(filename, content, log = true) {
		var parent = this;
		return new Promise((resolve, reject) => {
			fs.writeFile(filename, content, function(err) {
				if (err) {
					console.log(err);
					reject(err);
				} else {
					if (parent.showLog && log)
						console.log(`\x1b[2m\x1b[36mThe file ${filename} was saved\x1b[0m\n`);
					resolve();
				}
			});
		});
	}
}

var xsdWebForm = new XSDWebForm(process.argv);

module.exports.xsdWebForm = xsdWebForm;

// heapdump.writeSnapshot('./' + Date.now() + '.heapsnapshot');<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

export class RadioGroup extends Component {
  constructor({ children, value }) {
    super();
    const index = children.findIndex(c => c.props.value === value);
    this.state = { checkedIndex: index || 0 };
    this.renderChild = this.renderChild.bind(this);
    this.onCheck = this.onCheck.bind(this);
  }

  get value() {
    const { checkedIndex } = this.state;
    const { children } = this.props;

    const child = children.find(c => c.props.index === checkedIndex);
    return child && child.props.value || '';
  }

  onCheck(index) {
    this.setState({ checkedIndex: index });
  }

  renderChild(child, index, checked) {
    return React.cloneElement(child, {
      index, checked, onCheck: this.onCheck, ...child.props
    });
  }

  render() {
    const { checkedIndex } = this.state;
    const { children, ...props } = this.props;
    return (

        {
          children.map((c, i) => (this.renderChild(c, i, i === checkedIndex)))
        }

    );
  }
}

RadioGroup.propTypes = {
  children: PropTypes.node,
  checkedIndex: PropTypes.integer,
};

export class RadioButton extends Component {
  constructor() {
    super();
    this.getStyles = this.getStyles.bind(this);
    this.onClick = this.onClick.bind(this);
  }

  getStyles() {
    const { padding, rootColor, pointColor } = this.props;

    return {
      root: {
        borderWidth: 1,
        borderStyle: 'solid',
        borderColor: rootColor || '#E0E0E0',
        borderRadius: 1,
        padding: padding || 16,
        marginBottom: padding || 16,
      },
      checked: {
        borderColor: pointColor || '#8CB9FD',
        color: pointColor || '#8CB9FD',
      },
    };
  }

  onClick() {
    const { onCheck, checked, index } = this.props;
    onCheck && onCheck(index);
  }

  render() {
    const { checked, children } = this.props;
    const style = this.getStyles();
    const buttonStyle = Object.assign(style.root, checked ? style.checked : {});
    return (

            { children }

          <RadioIcon checked={ checked } />

    );
  }
}

RadioButton.propTypes = {
  value: PropTypes.string,
  index: PropTypes.number,
  children: PropTypes.node,
  onCheck: PropTypes.func,
};

class RadioIcon extends Component {
  constructor() {
    super();
    this.getStyles = this.getStyles.bind(this);
  }

  getStyles() {
    const { size, rootColor, pointColor } = this.props;

    return {
      root: {
        width: size || 10,
        height: size || 10,
        padding: 3,
        backgroundColor: '#FFF',
        borderWidth: 2,
        borderRadius: '50%',
        borderStyle: 'solid',
        borderColor: rootColor || '#9E9E9E',
      },
      checked: {
        borderColor: pointColor || '#8CB9FD',
      },
      inner: {
        width: size || 10,
        height: size || 10,
        borderRadius: '50%',
        background: pointColor || '#8CB9FD',
      }
    }
  }

  render() {
    const { checked } = this.props;
    const style = this.getStyles();
    const iconStyle = Object.assign(style.root, checked ? style.checked : {});
    return (

        { checked &&
 }

    );
  }
}

RadioIcon.propTypes = {
  size: PropTypes.number,
  rootColor: PropTypes.string,
  pointColor: PropTypes.string,
  checked: PropTypes.boolean,
};
<commit_msg>Call `#onChange` function to use RadioGroup value<commit_after>import React, { Component, PropTypes } from 'react';

export class RadioGroup extends Component {
  constructor({ children, value }) {
    super();
    const index = children.findIndex(c => c.props.value === value);
    this.state = { checkedIndex: index || 0 };
    this.renderChild = this.renderChild.bind(this);
    this.onCheck = this.onCheck.bind(this);
  }

  get value() {
    const { checkedIndex } = this.state;
    const { children } = this.props;

    const child = children.find(c => c.props.index === checkedIndex);
    return child && child.props.value || '';
  }

  onCheck(index) {
    const { onChange, children } = this.props;
    const child = children[index];
    if (!child) return;

    this.setState({ checkedIndex: index });
    onChange && onChange(child.props.value || '');
  }

  renderChild(child, index, checked) {
    return React.cloneElement(child, {
      index, checked, onCheck: this.onCheck, ...child.props
    });
  }

  render() {
    const { checkedIndex } = this.state;
    const { children, ...props } = this.props;
    return (

        {
          children.map((c, i) => (this.renderChild(c, i, i === checkedIndex)))
        }

    );
  }
}

RadioGroup.propTypes = {
  children: PropTypes.node,
  checkedIndex: PropTypes.integer,
  onChange: PropTypes.func,
};

export class RadioButton extends Component {
  constructor() {
    super();
    this.getStyles = this.getStyles.bind(this);
    this.onClick = this.onClick.bind(this);
  }

  getStyles() {
    const { padding, rootColor, pointColor } = this.props;

    return {
      root: {
        borderWidth: 1,
        borderStyle: 'solid',
        borderColor: rootColor || '#E0E0E0',
        borderRadius: 1,
        padding: padding || 16,
        marginBottom: padding || 16,
      },
      checked: {
        borderColor: pointColor || '#8CB9FD',
        color: pointColor || '#8CB9FD',
      },
    };
  }

  onClick() {
    const { onCheck, checked, index } = this.props;
    onCheck && onCheck(index);
  }

  render() {
    const { checked, children } = this.props;
    const style = this.getStyles();
    const buttonStyle = Object.assign(style.root, checked ? style.checked : {});
    return (

            { children }

          <RadioIcon checked={ checked } />

    );
  }
}

RadioButton.propTypes = {
  padding: PropTypes.number,
  rootColor: PropTypes.string,
  pointColor: PropTypes.string,
  value: PropTypes.string,
  index: PropTypes.number,
  checked: PropTypes.boolean,
  children: PropTypes.node,
  onCheck: PropTypes.func,
};

class RadioIcon extends Component {
  constructor() {
    super();
    this.getStyles = this.getStyles.bind(this);
  }

  getStyles() {
    const { size, rootColor, pointColor } = this.props;

    return {
      root: {
        width: size || 10,
        height: size || 10,
        padding: 3,
        backgroundColor: '#FFF',
        borderWidth: 2,
        borderRadius: '50%',
        borderStyle: 'solid',
        borderColor: rootColor || '#9E9E9E',
      },
      checked: {
        borderColor: pointColor || '#8CB9FD',
      },
      inner: {
        width: size || 10,
        height: size || 10,
        borderRadius: '50%',
        background: pointColor || '#8CB9FD',
      }
    }
  }

  render() {
    const { checked } = this.props;
    const style = this.getStyles();
    const iconStyle = Object.assign(style.root, checked ? style.checked : {});
    return (

        { checked &&
 }

    );
  }
}

RadioIcon.propTypes = {
  size: PropTypes.number,
  rootColor: PropTypes.string,
  pointColor: PropTypes.string,
  checked: PropTypes.boolean,
};
<|endoftext|>


<commit_before>import './jspdf';

import './plugins/acroform';
import './plugins/addhtml';
import './plugins/addimage';
import './plugins/annotations';
import './plugins/autoprint';
import './plugins/canvas';
import './plugins/cell';
import './plugins/context2d';
import './plugins/from_html';
import './plugins/javascript';
import './plugins/outline';
import './plugins/png_support';
import './plugins/prevent_scale_to_fit';
import './plugins/split_text_to_size';
import './plugins/standard_fonts_metrics';
import './plugins/svg';
import './plugins/total_pages';
import './plugins/customfonts';
import './plugins/vfs';

import './node_modules/cf-blob.js/Blob.js';
import './node_modules/filesaver.js/FileSaver.js';
import './node_modules/adler32cs/adler32cs.js';
import './libs/css_colors.js';
import './libs/deflate.js';
import './libs/html2canvas/dist/html2canvas.js';
import './libs/png_support/png.js';
import './libs/png_support/zlib.js';
import './libs/polyfill.js';

export default jsPDF;<commit_msg>remove removed plugins from main.js<commit_after>import './jspdf';

import './plugins/acroform';
import './plugins/addhtml';
import './plugins/addimage';
import './plugins/annotations';
import './plugins/autoprint';
import './plugins/canvas';
import './plugins/cell';
import './plugins/context2d';
import './plugins/from_html';
import './plugins/javascript';
import './plugins/outline';
import './plugins/png_support';
import './plugins/prevent_scale_to_fit';
import './plugins/split_text_to_size';
import './plugins/standard_fonts_metrics';
import './plugins/svg';
import './plugins/total_pages';
import './plugins/customfonts';
import './plugins/vfs';

import './node_modules/cf-blob.js/Blob.js';
import './node_modules/filesaver.js/FileSaver.js';
import './node_modules/adler32cs/adler32cs.js';
import './libs/html2canvas/dist/html2canvas.js';
import './libs/png_support/png.js';
import './libs/png_support/zlib.js';
import './libs/polyfill.js';

export default jsPDF;<|endoftext|>


<commit_before>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    getAllUserDataById(gvm.edituserid);

    gvm.rights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(user);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }
}

function initPage() {

}

function getAllUserDataById(edituserid){
    console.log("get " + edituserid);
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        var addedUsername = "";
        $.each(data, function(i, item){
            console.log(item.username);

            var current = item.username;
            $.each(data, function(i, item)
            {
                if(item.username == current){
                    viewModel.updatePermissions(new Permission(item.roleid, item.role))
                    console.log(item.roleid + " " + item.role );
                }
            });

            if (addedUsername != current){
                addedUsername = item.username
                console.log(addedUsername);
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, viewModel.rights()));
            }
        });
    });
}

function Permission(id, permissions) {
    return {
        id: ko.observable(id),
        permissions: ko.observable(permissions)
    };
}

function User(id, username, firstname, lastname, status) {
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else {
                this.status("WAIT_ACTIVATION");
            }
            updateUserStatus(this);
        }
    };
}<commit_msg>Admin edit user<commit_after>function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AdminPage");}, gvm);
    gvm.pageHeaderEditUser = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserEditTitle");}, gvm);

    gvm.edituserid = $("#usereditHeader").data('value');

    gvm.userName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserName");}, gvm);
    gvm.firstName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.userStatus = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("UserStatus");}, gvm);

    gvm.permissionRole = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionRole");}, gvm);
    gvm.permissionDescription = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("PermissionDescription");}, gvm);

    getAllUserDataById(gvm.edituserid);

    gvm.rights = ko.observableArray([]);
    gvm.user = ko.observableArray([]);

    gvm.updateUser = function(user)
    {
        gvm.user.push(user);
    },

    gvm.updatePermissions = function(permission)
    {
        gvm.rights.push(user);
    },

    gvm.removeUser = function(user) {
        gvm.user.remove(user);
        removeUser(user);
    },

    gvm.clearStructure = function() {
        gvm.rights.destroyAll();
        gvm.user.destroyAll();
    }
}

function initPage() {

}

function getAllUserDataById(edituserid){
    console.log("get " + edituserid);
    $.getJSON("/api/edituser/" + edituserid, function(data)
    {
        console.log(data);
        var addedUsername = "";
        $.each(data, function(i, item){
            console.log(item.username);

            var current = item.username;
            $.each(data, function(i, item)
            {
                if(item.username == current){
                    viewModel.updatePermissions(new Permission(item.roleid, item.role))
                    console.log(item.roleid + " " + item.role );
                }
            });

            if (addedUsername != current){
                addedUsername = item.username
                console.log(addedUsername);
                viewModel.updateUser(new User(item.userid, item.username, item.firstname, item.lastname, viewModel.rights()));
            }
        });
    });
}

function Permission(id, permissions) {
    return {
        id: ko.observable(id),
        permissions: ko.observable(permissions)
    };
}

function User(id, username, firstname, lastname, status) {
    return {
        id: ko.observable(id),
        username: ko.observable(username),
        firstname: ko.observable(firstname),
        lastname: ko.observable(lastname),
        status: ko.observable(status),

        removeThisUser: function() {
            if(confirm('Are you sure you want to remove this user?'))
            {
                viewModel.removeUser(this);
            }
        },

        changeStatus: function() {
            if (this.status() == "ACTIVE"){
                this.status("DISABLED");
            } else if (this.status() == "DISABLED") {
                this.status("ACTIVE");
            } else {
                this.status("WAIT_ACTIVATION");
            }
            updateUserStatus(this);
        }
    };
}<|endoftext|>


<commit_before>tm.main(function() {
    var app = tm.hybrid.Application("#canvas2d", "#canvas3d");
    app.resize(640, 960).fitWindow().run();

    app.replaceScene(tm.game.LoadingScene({
        width: 640, height: 960,
        assets: {
            // 拡張子による判別がきかないため、typeパラメータをつける
            kirara: {
                type: "three",
                url: "assets/kirara.json",
            },

            hiyoko: "assets/hiyoco_nomal_full.png",

            gradriel: "assets/gradriel_pose.mqo",
//            test: "assets/geometry.mqo",
        },
        nextScene: KiraraOnStage,
    }));
});

tm.define("KiraraOnStage", {
    superClass: "tm.hybrid.Scene", // tm.app.Sceneの3D向け拡張
    init: function() {
        this.superInit();

        // カメラ調整
        this.camera.setPosition(0, 20, 50);
        this.camera.lookAt(new THREE.Vector3(0, 10, 0));

        // ライトを動かす
        this.directionalLight
            .on("enterframe", function(e) {
                var f = e.app.frame;
                this.x = Math.cos(f * 0.1) * 10;
                this.z = Math.sin(f * 0.1) * 10;
            });

        // メッシュを表示する
        var kirara = tm.hybrid.Mesh("kirara") // Spriteっぽく使える
            .addChildTo(this)
            .on("enterframe", function() {
                if (this.rolling) this.rotationY += 10; // Y軸回転
            });
        kirara.rolling = false;

        // tweenerも使える
        kirara.tweener.clear()
            .to({ scaleY: 0.9 }, 300, "easeInBack")
            .to({ scaleY: 1.0 }, 300, "easeOutBack")
            .setLoop(true);

        // 2Dスプライトとの併用も可能
        var hiyoko = tm.display.Sprite("hiyoko", 32, 32)
            .setScale(4)
            .setFrameIndex(0)
            .addChildTo(this)
            .on("enterframe", function() {
                this.x += this.vx * 10;
                this.y += this.vy * 10;
                if (this.x < 0 || 640 < this.x) this.vx *= -1;
                if (this.y < 0 || 960 < this.y) this.vy *= -1;

                this.frameIndex = (this.frameIndex + 1) % 4;
                this.rotation += 2;
            });
        hiyoko.vx = 1;
        hiyoko.vy = 1;

        tm.ui.FlatButton({ text: "かいてん" })
            .setPosition(320, 100)
            .addChildTo(this)
            .on("push", function() {
                kirara.rolling = !kirara.rolling;
                this.label.text = kirara.rolling ? "とまる" : "かいてん";
            });
    }
});
<commit_msg>add test code<commit_after>tm.main(function() {
    var app = tm.hybrid.Application("#canvas2d", "#canvas3d");
    app.resize(640, 960).fitWindow().run();

    app.replaceScene(tm.game.LoadingScene({
        width: 640, height: 960,
        assets: {
            // 拡張子による判別がきかないため、typeパラメータをつける
            kirara: {
                type: "three",
                url: "assets/kirara.json",
            },

            hiyoko: "assets/hiyoco_nomal_full.png",

            gradriel: "assets/gradriel_pose.mqo",
//            test: "assets/geometry.mqo",
        },
        nextScene: KiraraOnStage,
    }));
});

tm.define("KiraraOnStage", {
    superClass: "tm.hybrid.Scene", // tm.app.Sceneの3D向け拡張
    init: function() {
        this.superInit();

        // カメラ調整
        this.camera.setPosition(0, 20, 50);
        this.camera.lookAt(new THREE.Vector3(0, 10, 0));

        // ライトを動かす
        this.directionalLight
            .on("enterframe", function(e) {
                var f = e.app.frame;
                this.x = Math.cos(f * 0.1) * 10;
                this.z = Math.sin(f * 0.1) * 10;
            });

        // メッシュを表示する
        var kirara = tm.hybrid.Mesh("kirara") // Spriteっぽく使える
            .addChildTo(this)
            .on("enterframe", function() {
                if (this.rolling) this.rotationY += 10; // Y軸回転
            });
        kirara.rolling = false;

        var test = tm.hybrid.Mesh("gradriel").addChildTo(this);

        // tweenerも使える
        kirara.tweener.clear()
            .to({ scaleY: 0.9 }, 300, "easeInBack")
            .to({ scaleY: 1.0 }, 300, "easeOutBack")
            .setLoop(true);

        // 2Dスプライトとの併用も可能
        var hiyoko = tm.display.Sprite("hiyoko", 32, 32)
            .setScale(4)
            .setFrameIndex(0)
            .addChildTo(this)
            .on("enterframe", function() {
                this.x += this.vx * 10;
                this.y += this.vy * 10;
                if (this.x < 0 || 640 < this.x) this.vx *= -1;
                if (this.y < 0 || 960 < this.y) this.vy *= -1;

                this.frameIndex = (this.frameIndex + 1) % 4;
                this.rotation += 2;
            });
        hiyoko.vx = 1;
        hiyoko.vy = 1;

        tm.ui.FlatButton({ text: "かいてん" })
            .setPosition(320, 100)
            .addChildTo(this)
            .on("push", function() {
                kirara.rolling = !kirara.rolling;
                this.label.text = kirara.rolling ? "とまる" : "かいてん";
            });
    }
});
<|endoftext|>


<commit_before>// ES10 - 1: Object - fromEntries
// To do: make all tests pass, leave the assert lines unchanged!
// Follow the hints of the failure messages!

describe('`Object.fromEntries()` converts key-value pairs into an object', () => {
  it('it is a static function defined on `Object`', () => {
    //// const fn = Object.entries;
    const fn = Object.fromEntries;
    assert(Object.is(Object.fromEntries, fn));
  });
  describe('the key-value pairs might be given as', () => {
    it('a simple array, with (at least) two values', () => {
      const keyValuePair = ['one', 'two'];
      assert.deepEqual(Object.fromEntries([keyValuePair]), {one: 'two'});
    });
    it('a simple array, with multiple key-value pairs', () => {
      const keyValuePair1 = ['one', 'two'];
      const keyValuePair2 = ['three', 'four'];
      assert.deepEqual(Object.fromEntries([keyValuePair1, keyValuePair2]), {one: 'two', three: 'four'});
    });
    it('a simple array, with duplicate keys override their predecessor', () => {
      const keyValuePair1 = ['one', 'two'];
      //// const keyValuePair2 = ['ONE', 'four'];
      const keyValuePair2 = ['one', 'four'];
      assert.deepEqual(Object.fromEntries([keyValuePair1, keyValuePair2]), {one: 'four'});
    });
    it('an object, with properties `0` and `1`', () => {
      const keyValuePair = {0: 'key', 1: 'value'};
      assert.deepEqual(Object.fromEntries([keyValuePair]), {key: 'value'});
    });
    it('an object, without a property `0` results in an object using `undefined` as key', () => {
      const keyValuePair = {key: 'key', 1: 'value'};
      assert.deepEqual(Object.fromEntries([keyValuePair]), {[undefined]: 'value'});
    });
    it('many objects, with the same property `0` override each other`s values', () => {
      const pair1 = {0: 'key', 1: 'value 1'};
      //// const pair2 = {0: 'key1', 1: 'value 2'};
      const pair2 = {0: 'key', 1: 'value 2'};
      assert.deepEqual(Object.fromEntries([pair1, pair2]), {key: 'value 2'});
    });
    it('a `Map`, which maps naturally to object key+value', () => {
      const map = new Map([['key', 'value']]);
      map.set('key1', 'value1');
      //// const object = Object.entries(map);
      const object = Object.fromEntries(map);
      assert.deepEqual(object, {key: 'value', key1: 'value1'});
    });
    it('an empty `Map`, results in an empty object', () => {
      //// const object = Object.fromEntries(new Map([[]]));
      const object = Object.fromEntries(new Map());
      assert.deepEqual(object, {});
    });
    it('a `Set`, used with `set.entires()`, returns an object with key=value', () => {
      const set = new Set();
      ////
      set.add('value0');
      set.add('value1');
      assert.deepEqual(Object.fromEntries(set.entries()), {value0: 'value0', value1: 'value1'});
    });
  });
  describe('the 1st parameter', () => {
    describe('must be iterable', () => {
      it('like an array', () => {
        assert.doesNotThrow(() => Object.fromEntries([]));
      });
      it('a self-made iterable', () => {
        let cnt = -1;
        const iterable = {
          [Symbol.iterator]() {
            return {
              next: () => {
                cnt++;
                if (cnt === 0) return {value: ['a', 42], done: false};
                if (cnt === 1) return {done: true};
              }
            }
          }
        };
        assert.deepEqual(Object.fromEntries(iterable), {a: 42});
      });
    });
    describe('each entry must have a property `0` and `1` for key+value', () => {
      it('like an object with these explicit properties', () => {
        assert.deepEqual(Object.fromEntries([{0: 'key', 1: 'value'}]), {key: 'value'});
      });
      it('if any (or both) are missing, `undefined` is used', () => {
        //// const obj = {0: 'key'};
        const obj = {};
        assert.deepEqual(Object.fromEntries([obj]), {[undefined]: undefined});
      });
      it('if an empty array is given, both are undefined too', () => {
        //// const emptyArray = [1, 2];
        const emptyArray = [];
        assert.deepEqual(Object.fromEntries([emptyArray]), {[undefined]: undefined});
      });
    });
    describe('throws a TypeError', () => {
      it('if missing', () => {
        //// const fn = () => Object.fromEntries('');
        const fn = () => Object.fromEntries();
        assert.throws(fn, TypeError);
      });
      it('if `undefined` (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(undefined); }, TypeError);
      });
      it('if `null` (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(undefined); }, TypeError);
      });
      it('if boolean (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(true); }, TypeError);
      });
      it('if a Symbol (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(Symbol.for('some')); }, TypeError);
      });
    });
  });
  describe('more exotic use cases, are', () => {
    it('an empty string, returns an empty object', () => {
      assert.deepEqual(Object.fromEntries(''), {});
    });
    it('a single-space string, throws', () => {
      assert.throws(() => Object.fromEntries(' '), TypeError);
    });
  });

  describe('requires an argument that can be converted to an object', () => {
    it('an empty string does NOT throw', () => {
      assert.doesNotThrow(() => { Object.fromEntries(''); });
    });
    it('an non-empty string does throw', () => {
      assert.throws(() => { Object.fromEntries(' '); });
    });
  });

  describe('works', () => {
    it('empty string', () => {
      assert.doesNotThrow(() => { Object.fromEntries(''); });
      assert.deepEqual(Object.fromEntries([]), {});
    });
    it('empty array', () => {
      assert.doesNotThrow(() => { Object.fromEntries([]); });
      assert.deepEqual(Object.fromEntries([]), {});
    });
    it('array of arrays', () => {
      assert.doesNotThrow(() => { Object.fromEntries([[]]); });
      assert.deepEqual(Object.fromEntries([[], []]), {undefined: undefined});
    });
    it('array of arrays #2', () => {
      assert.doesNotThrow(() => { Object.fromEntries([[], []]); });
      assert.deepEqual(Object.fromEntries([[], []]), {undefined: undefined});
    });
    it('array of arrays #3', () => {
      assert.doesNotThrow(() => { Object.fromEntries([[], []]); });
      assert.deepEqual(Object.fromEntries([[1,2], [3,4]]), {1:2, 3:4});
    });
    it('toString-ables can be keys', () => {
      const s = new class { toString() { return 'key'; }  };
      assert.deepEqual(Object.fromEntries([[s, 42]]), {key: 42});
    });
    it('keys 0 and 1 must be given', () => {
      assert.deepEqual(Object.fromEntries([{1: null}]), {[undefined]: null});
      assert.deepEqual(Object.fromEntries([{0: 0, 1: 1}]), {0: 1});
      assert.deepEqual(Object.fromEntries([{10: 0, 20: 1}]), {[undefined]: undefined});
      assert.deepEqual(Object.fromEntries([[0, 1]]), {0: 1});
      assert.deepEqual(Object.fromEntries([Object('')]), {[undefined]: undefined});
      assert.deepEqual(Object.fromEntries([Object('12')]), {1: '2'});
      assert.throws(() => Object.fromEntries(['12']));

      // key+value are accessible via prop 0+1, they are not iterated over!!!!
      const map = new Map([['key', 'value']]);
      assert.deepEqual(Object.fromEntries([map]), {[undefined]: undefined});
      map[0] = 23;
      assert.deepEqual(Object.fromEntries([map]), {23: undefined});
      assert.deepEqual(Object.fromEntries([['key', 'value']]), {key: 'value'});

      // custom iterator
      let cnt = 0;
      const iterable = {
        [Symbol.iterator]() {
          return {next: () => ([{value: ['a', 42], done: false}, {done: true}][cnt++])};
        }
      };
      assert.deepEqual(Object.fromEntries(iterable), {a: 42});
      assert.deepEqual(Object.fromEntries([['a', 42]]), {a: 42});
    });
  });

  describe('use cases', () => {
    it('from JSON to object', () => {
      // the
    });
    it('mapping data', () => {
      const people = [{name: 'Alex', age: 21}, {name: 'Anna', age: 21}];
      const peoplesAge = Object.fromEntries(people.map(({name, age}) => [name, age]));
      assert.deepEqual({Alex: 21, Anna:21}, peoplesAge);
    });
  });
  describe('not symetric to `Object.entries()`', () => {
    it('is almost the reverse of Object.entries()', () => {

    });
    it('allows Symbols as keys, while `Object.entries()` does not report them', () => {
      const sym = Symbol();
      const fromEntries = Object.fromEntries([[sym, 42]]);
      assert.deepEqual(fromEntries, {[sym]: 42});
      // while
      assert.deepEqual(Object.entries(fromEntries), []);
    });
  });
});
<commit_msg>All cases for the kata done. Now left to make it a kata.<commit_after>// ES10 - 1: Object - fromEntries
// To do: make all tests pass, leave the assert lines unchanged!
// Follow the hints of the failure messages!

describe('`Object.fromEntries()` converts key-value pairs into an object', () => {
  it('it is a static function defined on `Object`', () => {
    //// const fn = Object.entries;
    const fn = Object.fromEntries;
    assert(Object.is(Object.fromEntries, fn));
  });
  describe('the key-value pairs might be given as', () => {
    it('a simple array, with (at least) two values', () => {
      const keyValuePair = ['one', 'two'];
      assert.deepEqual(Object.fromEntries([keyValuePair]), {one: 'two'});
    });
    it('a simple array, with multiple key-value pairs', () => {
      const keyValuePair1 = ['one', 'two'];
      const keyValuePair2 = ['three', 'four'];
      assert.deepEqual(Object.fromEntries([keyValuePair1, keyValuePair2]), {one: 'two', three: 'four'});
    });
    it('a simple array, with duplicate keys override their predecessor', () => {
      const keyValuePair1 = ['one', 'two'];
      //// const keyValuePair2 = ['ONE', 'four'];
      const keyValuePair2 = ['one', 'four'];
      assert.deepEqual(Object.fromEntries([keyValuePair1, keyValuePair2]), {one: 'four'});
    });
    it('an object, with properties `0` and `1`', () => {
      const keyValuePair = {0: 'key', 1: 'value'};
      assert.deepEqual(Object.fromEntries([keyValuePair]), {key: 'value'});
    });
    it('an object, without a property `0` results in an object using `undefined` as key', () => {
      const keyValuePair = {key: 'key', 1: 'value'};
      assert.deepEqual(Object.fromEntries([keyValuePair]), {[undefined]: 'value'});
    });
    it('many objects, with the same property `0` override each other`s values', () => {
      const pair1 = {0: 'key', 1: 'value 1'};
      //// const pair2 = {0: 'key1', 1: 'value 2'};
      const pair2 = {0: 'key', 1: 'value 2'};
      assert.deepEqual(Object.fromEntries([pair1, pair2]), {key: 'value 2'});
    });
    it('a `Map`, which maps naturally to object key+value', () => {
      const map = new Map([['key', 'value']]);
      map.set('key1', 'value1');
      //// const object = Object.entries(map);
      const object = Object.fromEntries(map);
      assert.deepEqual(object, {key: 'value', key1: 'value1'});
    });
    it('an empty `Map`, results in an empty object', () => {
      //// const object = Object.fromEntries(new Map([[]]));
      const object = Object.fromEntries(new Map());
      assert.deepEqual(object, {});
    });
    it('a `Set`, used with `set.entires()`, returns an object with key=value', () => {
      const set = new Set();
      ////
      set.add('value0');
      set.add('value1');
      assert.deepEqual(Object.fromEntries(set.entries()), {value0: 'value0', value1: 'value1'});
    });
  });
  describe('the 1st parameter', () => {
    describe('must be iterable', () => {
      it('like an array', () => {
        assert.doesNotThrow(() => Object.fromEntries([]));
      });
      it('a self-made iterable', () => {
        let cnt = -1;
        const iterable = {
          [Symbol.iterator]() {
            return {
              next: () => {
                cnt++;
                if (cnt === 0) return {value: ['a', 42], done: false};
                if (cnt === 1) return {done: true};
              }
            }
          }
        };
        assert.deepEqual(Object.fromEntries(iterable), {a: 42});
      });
    });
    describe('each entry must have a property `0` and `1` for key+value', () => {
      it('like an object with these explicit properties', () => {
        assert.deepEqual(Object.fromEntries([{0: 'key', 1: 'value'}]), {key: 'value'});
      });
      it('if any (or both) are missing, `undefined` is used', () => {
        //// const obj = {0: 'key', 10: 'no key', 20: 'no value'};
        const obj = {};
        assert.deepEqual(Object.fromEntries([obj]), {[undefined]: undefined});
      });
      it('if an empty array is given, both are undefined too', () => {
        //// const emptyArray = [1, 2];
        const emptyArray = [];
        assert.deepEqual(Object.fromEntries([emptyArray]), {[undefined]: undefined});
      });
      it('toString-ables can be keys', () => {
        //// const s = new class { toString() { return 'value'; }  };
        const s = new class { toString() { return 'key'; }  };
        assert.deepEqual(Object.fromEntries([[s, 42]]), {key: 42});
      });
      it('iterables (like a `Map`) are NOT expected, and not used', () => {
        const map = new Map([['key', 'value']]);
        assert.deepEqual(Object.fromEntries([map]), {[undefined]: undefined});
        //// map.key = 23;
        map[0] = 23;
        assert.deepEqual(Object.fromEntries([map]), {23: undefined});
      });
    });
    describe('throws a TypeError', () => {
      it('if missing', () => {
        //// const fn = () => Object.fromEntries('');
        const fn = () => Object.fromEntries();
        assert.throws(fn, TypeError);
      });
      it('if `undefined` (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(undefined); }, TypeError);
      });
      it('if `null` (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(undefined); }, TypeError);
      });
      it('if boolean (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(true); }, TypeError);
      });
      it('if a Symbol (which is not an iterable)', () => {
        assert.throws(() => { Object.fromEntries(Symbol.for('some')); }, TypeError);
      });
    });
  });
  describe('more use cases/learnings, are', () => {
    it('can be used to map data', () => {
      const people = [{name: 'Alex', age: 21}, {name: 'Anna', age: 21}];
      //// const peoplesAge = Object.entries(people.map(({name, age}) => [name, age]));
      const peoplesAge = Object.fromEntries(people.map(({name, age}) => [name, age]));
      assert.deepEqual({Alex: 21, Anna:21}, peoplesAge);
    });
    it('an empty string, returns an empty object', () => {
      //// const emptyString = ' ';
      const emptyString = '';
      assert.deepEqual(Object.fromEntries(emptyString), {});
    });
    it('a single-space string, throws', () => {
      assert.throws(() => Object.fromEntries(' '), TypeError);
    });
    describe('not symetric to `Object.entries()`', () => {
      it('allows Symbols as keys, while `Object.entries()` does not report them', () => {
        const sym = Symbol();
        const fromEntries = Object.fromEntries([[sym, 42]]);
        assert.deepEqual(fromEntries, {[sym]: 42});
        // while
        assert.deepEqual(Object.entries(fromEntries), []);
      });
    });
  });
});
<|endoftext|>


<commit_before>/*!
 * to-clipboard <https://github.com/jonschlinkert/to-clipboard>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var cp = require('child_process');

var program = {
  darwin: {
    name: 'pbcopy',
    args: []
  },
  win32: {
    name: 'clip',
    args: [],
  },
  linux: {
    name: 'xsel',
    args: ['-bi']
  }
}[process.platform];

function toClipboard(args, cb) {
  var proc = cp.spawn(program.name, program.args, {
    stdio: ['pipe', 'ignore', 'ignore']
  });
  if (cb) {
    proc.on('error', cb);
    proc.on('exit', function() {
      cb(null);
    });
  }
  proc.stdin.write(args);
  proc.stdin.end();
}

toClipboard.sync = function toClipboardSync(args) {
  cp.execSync(program.name + ' ' + program.args.join(' '), {
    input: args
  });
};

/**
 * Expose `toClipboard`
 */

module.exports = toClipboard;
<commit_msg>Use spawnSync instead of execSync: more consistent<commit_after>/*!
 * to-clipboard <https://github.com/jonschlinkert/to-clipboard>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var cp = require('child_process');

var program = {
  darwin: {
    name: 'pbcopy',
    args: []
  },
  win32: {
    name: 'clip',
    args: [],
  },
  linux: {
    name: 'xsel',
    args: ['-bi']
  }
}[process.platform];

function toClipboard(args, cb) {
  var proc = cp.spawn(program.name, program.args, {
    stdio: ['pipe', 'ignore', 'ignore']
  });
  if (cb) {
    proc.on('error', cb);
    proc.on('exit', function() {
      cb(null);
    });
  }
  proc.stdin.write(args);
  proc.stdin.end();
}

toClipboard.sync = function toClipboardSync(args) {
  cp.spawnSync(program.name, program.args, {input: args});
};

/**
 * Expose `toClipboard`
 */

module.exports = toClipboard;
<|endoftext|>


<commit_before>var LABEL_WIDTH = 200,
	GRAPH_WIDTH = 400, // Horizontal distance between centers of vertices on opposite sides
	VTX_RAD = 4,
	VTX_DIST = 40, // Distance between centers of two consecutive vertices
	LABEL_OFFSET = 10, // Distance between label and center of vertex
	MARGIN = {top: VTX_RAD, bottom: VTX_RAD, left: 0, right: 0};

// Overall width of the graphics
var WIDTH = GRAPH_WIDTH + 2 * (LABEL_WIDTH + LABEL_OFFSET);

// Overall height of the graphics
var HEIGHT = 2 * VTX_RAD + MARGIN.top + MARGIN.bottom + VTX_DIST * (Math.max(tac_chars.length, asoiaf_chars.length));

// x-coordinates of vertices in left and right parts of the graph
var LEFT_X = MARGIN.left + LABEL_WIDTH + LABEL_OFFSET,
	RIGHT_X = LEFT_X + GRAPH_WIDTH;

var svg = d3.select("svg");

svg.attr("width", WIDTH)
	.attr("height", HEIGHT);

//////////// Draw the vertices

// TAC vertices
var tac_vertex = svg.selectAll("dummy")
	.data(tac_chars)
  .enter().append("g")
	.attr("transform", function(d, i) {

			// Store each vertex's vertical position
			char_dict[d].y = VTX_RAD + MARGIN.top + i * VTX_DIST;
			// Translate to vertical position of the vertex's center
			return "translate(" + MARGIN.left + "," + char_dict[d].y + ")";
		});

tac_vertex.append("circle")
	.attr("cx", LABEL_WIDTH + LABEL_OFFSET)
	.attr("cy", 0)
	.attr("r", VTX_RAD);

// Label each vertex with the character's full name
tac_vertex.append("text")
	.text(function(d) {return char_dict[d].name;})
	.attr("text-anchor", "end")
	.attr("x", LABEL_WIDTH)
	.attr("y", VTX_RAD);

// ASOIAF vertices
var asoiaf_vertex = svg.selectAll("dummy") // So that we get an empty selection
	.data(asoiaf_chars)
  .enter().append("g")
	.attr("transform", function(d, i) {
			char_dict[d].y = VTX_RAD + MARGIN.top + i * VTX_DIST;
			return "translate(" + RIGHT_X + "," + char_dict[d].y + ")";
		});

asoiaf_vertex.append("circle")
	.attr("cx", 0)
	.attr("cy", 0)
	.attr("r", VTX_RAD);

// Labels
asoiaf_vertex.append("text")
	.text(function(d) {return char_dict[d].name;})
	.attr("text-anchor", "start")
	.attr("x", LABEL_OFFSET)
	.attr("y", VTX_RAD);
<commit_msg>Draw edges<commit_after>var LABEL_WIDTH = 200,
	GRAPH_WIDTH = 400, // Horizontal distance between centers of vertices on opposite sides
	VTX_RAD = 4,
	VTX_DIST = 40, // Distance between centers of two consecutive vertices
	LABEL_OFFSET = 10, // Distance between label and center of vertex
	MARGIN = {top: VTX_RAD, bottom: VTX_RAD, left: 0, right: 0};

// Overall width of the graphics
var WIDTH = GRAPH_WIDTH + 2 * (LABEL_WIDTH + LABEL_OFFSET);

// Overall height of the graphics
var HEIGHT = 2 * VTX_RAD + MARGIN.top + MARGIN.bottom + VTX_DIST * (Math.max(tac_chars.length, asoiaf_chars.length));

// x-coordinates of vertices in left and right parts of the graph
var LEFT_X = MARGIN.left + LABEL_WIDTH + LABEL_OFFSET,
	RIGHT_X = LEFT_X + GRAPH_WIDTH;

var svg = d3.select("svg");

svg.attr("width", WIDTH)
	.attr("height", HEIGHT);

//////////// Draw the vertices

// TAC vertices
var tac_vertex = svg.selectAll("dummy")
	.data(tac_chars)
  .enter().append("g")
	.attr("transform", function(d, i) {

			// Store each vertex's vertical position
			char_dict[d].y = VTX_RAD + MARGIN.top + i * VTX_DIST;
			// Translate to vertical position of the vertex's center
			return "translate(" + MARGIN.left + "," + char_dict[d].y + ")";
		});

tac_vertex.append("circle")
	.attr("cx", LABEL_WIDTH + LABEL_OFFSET)
	.attr("cy", 0)
	.attr("r", VTX_RAD);

// Label each vertex with the character's full name
tac_vertex.append("text")
	.text(function(d) {return char_dict[d].name;})
	.attr("text-anchor", "end")
	.attr("x", LABEL_WIDTH)
	.attr("y", VTX_RAD);

// ASOIAF vertices
var asoiaf_vertex = svg.selectAll("dummy") // So that we get an empty selection
	.data(asoiaf_chars)
  .enter().append("g")
	.attr("transform", function(d, i) {
			char_dict[d].y = VTX_RAD + MARGIN.top + i * VTX_DIST;
			return "translate(" + RIGHT_X + "," + char_dict[d].y + ")";
		});

asoiaf_vertex.append("circle")
	.attr("cx", 0)
	.attr("cy", 0)
	.attr("r", VTX_RAD);

// Labels
asoiaf_vertex.append("text")
	.text(function(d) {return char_dict[d].name;})
	.attr("text-anchor", "start")
	.attr("x", LABEL_OFFSET)
	.attr("y", VTX_RAD);

// Draw edges
svg.selectAll("dummy")
	.data(edges)
  .enter().append("line")
	.attr("x1", LEFT_X)
	.attr("y1", function(d) {return char_dict[d.l].y;})
	.attr("x2", RIGHT_X)
	.attr("y2", function(d) {return char_dict[d.r].y;})
	.style({stroke: "black", "stroke-width": "2px"});
<|endoftext|>