<commit_before>var WinJS = require('winjs'),
  ioc = require('../ioc'),
  config = require('../config'),
  base = require('./base'),
  log = require('../log'),
  util = require("util");

var _constructor = function(options) {
  base.call(this, arguments);
  this._onNavigatingBinding = this._onNavigating.bind(this);
  this._onNavigatedBinding = this._onNavigated.bind(this);
  this._onNavigateBackMessageBinding = this._onNavigateBackMessage.bind(this);
  this._onBeforeNavigateBinding = this._onBeforeNavigate.bind(this);
  this._onResizedBinding = this._onResized.bind(this);
  this._onPopStateBinding = this._onPopState.bind(this);
  this._onNavigateToMessageBinding = this._onNavigateToMessage.bind(this);
  this._lastNavigationPromise = WinJS.Promise.as();
  this.MessageService = ioc.getService("message");
  this._element = document.createElement("div");
};

var instanceMembers = {
  start: function() {
    var that = this;
    return base.prototype.start.apply(this, arguments).then(function() {
      WinJS.Navigation.addEventListener("navigating",
        that._onNavigatingBinding);
      WinJS.Navigation.addEventListener("navigated",
        that._onNavigatedBinding);
      WinJS.Navigation.addEventListener("beforenavigate",
        that._onBeforeNavigateBinding);
      that.MessageService.register("navigateToMessage", that._onNavigateToMessageBinding);
      that.MessageService.register("navigateBackMessage", that._onNavigateBackMessageBinding);
      window.addEventListener("resize", that._onResizedBinding);
      window.addEventListener("popstate", that._onPopStateBinding);
    });
  },

  _onPopState: function(event) {
    this.MessageService.send("navigateBackMessage");
  },

  _onNavigateBackMessage: function(type, args) {
    args = args || {};
    var steps = args.steps || 1;
    return WinJS.Navigation.back(steps);
  },

  _onNavigateToMessage: function(type, args) {
    var viewKey = args.viewKey;
    var state = args.state;
    var viewTemplateUri = config.get("ui:view:template-uri");
    if (viewTemplateUri) {
      var actualViewTemplateUri = util.format(viewTemplateUri, viewKey);
      var viewClassDef = ioc.getViewDef(viewKey);

      var existingBaseClass = WinJS.UI.Pages.define(actualViewTemplateUri);
      if (existingBaseClass != viewClassDef) {
        var extendedClassDef = WinJS.UI.Pages.define(actualViewTemplateUri, {}, viewClassDef);
        ioc.override(viewKey, extendedClassDef);
      }

      var vmInstance = ioc.getViewModel(viewKey);
      vmInstance.setKey(viewKey);
      vmInstance.setData(args.state);

      if(this.getViewModel())
        this.getViewModel().onNavigateFrom();

      history.pushState({
        context: state,
        key: viewKey
      }, viewKey, "#" + viewKey);

      WinJS.Navigation.navigate(actualViewTemplateUri, vmInstance);
    }
  },

  _onBeforeNavigate: function(args) {
    if (this.getViewModel() && this.getViewModel().getBackNavigationDisabled()) {
      log.info("NavigationService: back navigation cancelled based on current vm getBackNavigationDisabled value");
      args.preventDefault();
    }
  },

  _onNavigating: function(args) {
    var that = this;
    var newElement = this.createDefaultPageElement();
    this._element.appendChild(newElement);
    this._lastNavigationPromise.cancel();

    function cleanup() {
      if (that._element.childElementCount > 1) {
        var oldElement = that._element.firstElementChild;
        // Cleanup and remove previous element
        if (oldElement.winControl) {

          if (oldElement.winControl.unload) {
            oldElement.winControl.unload();
          }
          oldElement.winControl.dispose();
        }
        oldElement.parentNode.removeChild(oldElement);
        oldElement.innerText = "";
      }
    }

    // TODO: archive the old view/viewModel
    this._lastNavigationPromise = WinJS.Promise.as().then(cleanup, cleanup).then(function() {
      that.MessageService.send("navigatingMessage", args);
      return WinJS.UI.Pages.render(args.detail.location,
        newElement,
        args.detail.state,
        new WinJS.Promise(function(completed){
            that.MessageService.send("viewEarlyRenderMessage");
            return completed();
        }));
    });
    args.detail.setPromise(this._lastNavigationPromise);
  },

  _onNavigated: function() {
    this.MessageService.send("navigatedMessage");
    this.getViewModel().onNavigateTo();
  },

  _onResized: function() {
    var view = this.getView();
    if (view && view.updateLayout)
      view.updateLayout();
  },

  getRootElement: function() {
    return this._element;
  },

  setRootElement: function(val) {
    this._element = val;
  },

  createDefaultPageElement: function() {
    var element = document.createElement("div");
    element.setAttribute("dir", window.getComputedStyle(this._element, null).direction);
    element.style.position = "absolute";
    element.style.width = "100%";
    element.style.height = "100%";
    return element;
  },

  getView: function() {
    var viewElem = this.getViewElement();
    if (viewElem && viewElem.winControl)
      return viewElem.winControl
    return false;
  },

  getViewElement: function() {
    return this._element.firstElementChild;
  },

  getViewModel: function() {
    var view = this.getView();
    if (view) {
      var viewModel = view.getViewModel();
      if (viewModel)
        return viewModel;
    }
    return null;
  },

  stop: function() {
    var that = this;
    return base.prototype.start.apply(this, arguments)
      .then(function() {
        WinJS.Navigation.removeEventListener("navigating",
          that._onNavigatingBinding);
        WinJS.Navigation.removeEventListener("navigated",
          that._onNavigatedBinding);
        WinJS.Navigation.removeEventListener("beforenavigate",
          that._onBeforeNavigateBinding);
        that.MessageService.unregister("navigateToMessage", that._onNavigateToMessageBinding);
        that.MessageService.unregister("navigateBackMessage", that._onNavigateBackMessageBinding);
        window.removeEventListener("resize", that._onResizedBinding);
        window.removeEventListener("popstate", that._onPopStateBinding)

        if (this._element)
          WinJS.Utilities.disposeSubTree(this._element);
      });
  }
};

var staticMembers = {

};

module.exports = WinJS.Class.derive(base, _constructor,
  instanceMembers, staticMembers);
<commit_msg>Update navigation.js<commit_after>var WinJS = require('winjs'),
  ioc = require('../ioc'),
  config = require('../config'),
  base = require('./base'),
  log = require('../log'),
  util = require("util");

var _constructor = function(options) {
  base.call(this, arguments);
  this._onNavigatingBinding = this._onNavigating.bind(this);
  this._onNavigatedBinding = this._onNavigated.bind(this);
  this._onNavigateBackMessageBinding = this._onNavigateBackMessage.bind(this);
  this._onBeforeNavigateBinding = this._onBeforeNavigate.bind(this);
  this._onResizedBinding = this._onResized.bind(this);
  this._onPopStateBinding = this._onPopState.bind(this);
  this._onNavigateToMessageBinding = this._onNavigateToMessage.bind(this);
  this._lastNavigationPromise = WinJS.Promise.as();
  this.MessageService = ioc.getService("message");
  this._element = document.createElement("div");
};

var instanceMembers = {
  start: function() {
    var that = this;
    return base.prototype.start.apply(this, arguments).then(function() {
      WinJS.Navigation.addEventListener("navigating",
        that._onNavigatingBinding);
      WinJS.Navigation.addEventListener("navigated",
        that._onNavigatedBinding);
      WinJS.Navigation.addEventListener("beforenavigate",
        that._onBeforeNavigateBinding);
      that.MessageService.register("navigateToMessage", that._onNavigateToMessageBinding);
      that.MessageService.register("navigateBackMessage", that._onNavigateBackMessageBinding);
      window.addEventListener("resize", that._onResizedBinding);
      window.addEventListener("popstate", that._onPopStateBinding);
    });
  },

  _onPopState: function(event) {
    this.MessageService.send("navigateBackMessage");
  },

  _onNavigateBackMessage: function(type, args) {
    args = args || {};
    var steps = args.steps || 1;
    return WinJS.Navigation.back(steps);
  },

  _onNavigateToMessage: function(type, args) {
    var viewKey = args.viewKey;
    var state = args.state;
    var viewTemplateUri = config.get("ui:view:template-uri");
    if (viewTemplateUri) {
      var actualViewTemplateUri = util.format(viewTemplateUri, viewKey);
      var viewClassDef = ioc.getViewDef(viewKey);

      var existingBaseClass = WinJS.UI.Pages.define(actualViewTemplateUri);
      if (existingBaseClass != viewClassDef) {
        var extendedClassDef = WinJS.UI.Pages.define(actualViewTemplateUri, {}, viewClassDef);
        ioc.override(viewKey, extendedClassDef);
      }

      var vmInstance = ioc.getViewModel(viewKey);
      vmInstance.setKey(viewKey);
      vmInstance.setData(args.state);

      if(this.getViewModel())
        this.getViewModel().onNavigateFrom();

      history.pushState({
        context: state,
        key: viewKey
      }, viewKey, "#" + viewKey);

      WinJS.Navigation.navigate(actualViewTemplateUri, vmInstance);
    }
  },

  _onBeforeNavigate: function(args) {
    if (this.getViewModel() && this.getViewModel().getBackNavigationDisabled()) {
      log.info("NavigationService: back navigation cancelled based on current vm getBackNavigationDisabled value");
      args.preventDefault();
    }
  },

  _onNavigating: function(args) {
    var that = this;
    var newElement = this.createDefaultPageElement();
    this._element.appendChild(newElement);
    this._lastNavigationPromise.cancel();

    function cleanup() {
      if (that._element.childElementCount > 1) {
        var oldElement = that._element.firstElementChild;
        // Cleanup and remove previous element
        if (oldElement.winControl) {

          if (oldElement.winControl.unload) {
            oldElement.winControl.unload();
          }
          oldElement.winControl.dispose();
        }
        oldElement.parentNode.removeChild(oldElement);
        oldElement.innerText = "";
      }
    }

    // TODO: archive the old view/viewModel
    this._lastNavigationPromise = WinJS.Promise.as().then(cleanup, cleanup).then(function() {
      that.MessageService.send("navigatingMessage", args);
      return WinJS.UI.Pages.render(args.detail.location,
        newElement,
        args.detail.state);
    });
    args.detail.setPromise(this._lastNavigationPromise);
  },

  _onNavigated: function() {
    this.MessageService.send("navigatedMessage");
    this.getViewModel().onNavigateTo();
  },

  _onResized: function() {
    var view = this.getView();
    if (view && view.updateLayout)
      view.updateLayout();
  },

  getRootElement: function() {
    return this._element;
  },

  setRootElement: function(val) {
    this._element = val;
  },

  createDefaultPageElement: function() {
    var element = document.createElement("div");
    element.setAttribute("dir", window.getComputedStyle(this._element, null).direction);
    element.style.position = "absolute";
    element.style.width = "100%";
    element.style.height = "100%";
    return element;
  },

  getView: function() {
    var viewElem = this.getViewElement();
    if (viewElem && viewElem.winControl)
      return viewElem.winControl
    return false;
  },

  getViewElement: function() {
    return this._element.firstElementChild;
  },

  getViewModel: function() {
    var view = this.getView();
    if (view) {
      var viewModel = view.getViewModel();
      if (viewModel)
        return viewModel;
    }
    return null;
  },

  stop: function() {
    var that = this;
    return base.prototype.start.apply(this, arguments)
      .then(function() {
        WinJS.Navigation.removeEventListener("navigating",
          that._onNavigatingBinding);
        WinJS.Navigation.removeEventListener("navigated",
          that._onNavigatedBinding);
        WinJS.Navigation.removeEventListener("beforenavigate",
          that._onBeforeNavigateBinding);
        that.MessageService.unregister("navigateToMessage", that._onNavigateToMessageBinding);
        that.MessageService.unregister("navigateBackMessage", that._onNavigateBackMessageBinding);
        window.removeEventListener("resize", that._onResizedBinding);
        window.removeEventListener("popstate", that._onPopStateBinding)

        if (this._element)
          WinJS.Utilities.disposeSubTree(this._element);
      });
  }
};

var staticMembers = {

};

module.exports = WinJS.Class.derive(base, _constructor,
  instanceMembers, staticMembers);
<|endoftext|>


<commit_before>import { createSelector } from 'reselect';
import {
  isDataSelectionPage,
  isDatasetPage,
  isDatasetDetailPage,
  isPanoPage,
  isDataPage
} from '../../../store/redux-first-router/selectors';
import paramsRegistry from '../../../store/params-registry';

const REDUCER_KEY = 'ui';
export { REDUCER_KEY as UI };
export const HIDE_EMBED_PREVIEW = `${REDUCER_KEY}/HIDE_EMBED_PREVIEW`;
export const HIDE_PRINT = `${REDUCER_KEY}/HIDE_PRINT`;
export const SHOW_EMBED_PREVIEW = `${REDUCER_KEY}/SHOW_EMBED_PREVIEW`;
export const SHOW_PRINT = `${REDUCER_KEY}/SHOW_PRINT`;
export const TOGGLE_MAP_PANEL_HANDLE = `${REDUCER_KEY}/TOGGLE_MAP_PANEL_HANDLE`;
export const SET_VIEW_MODE = `${REDUCER_KEY}/SET_VIEW_MODE`;

export const VIEW_MODE = {
  MAP: 'kaart',
  SPLIT: 'gesplitst',
  FULL: 'volledig'
};

export const initialState = {
  isMapPanelHandleVisible: true,
  isEmbedPreview: false,
  isEmbed: false,
  isPrintMode: false,
  viewMode: VIEW_MODE.SPLIT
};

export default function UiReducer(state = initialState, action) {
  const enrichedState = {
    ...state,
    ...paramsRegistry.getStateFromQueries(REDUCER_KEY, action)
  };

  switch (action.type) {
    case HIDE_EMBED_PREVIEW:
      return {
        ...enrichedState,
        isEmbedPreview: false,
        isEmbed: false
      };

    case HIDE_PRINT:
      return {
        ...enrichedState,
        isPrintMode: false
      };

    case SHOW_EMBED_PREVIEW:
      return {
        ...enrichedState,
        isEmbedPreview: true
      };

    case SHOW_PRINT:
      return {
        ...enrichedState,
        isPrintMode: true
      };

    case SET_VIEW_MODE:
      return {
        ...enrichedState,
        viewMode: action.payload
      };

    case TOGGLE_MAP_PANEL_HANDLE:
      return {
        ...enrichedState,
        isMapPanelHandleVisible: !enrichedState.isMapPanelHandleVisible
      };

    default:
      return enrichedState;
  }
}

// Todo: wire these actions properly when ui reducer is obsolete
export const showEmbedPreview = () => ({
  type: SHOW_EMBED_PREVIEW,
  meta: {
    tracking: true
  }
});
export const showPrintMode = () => ({
  type: SHOW_PRINT,
  meta: {
    tracking: true
  }
});
export const setViewMode = (payload, tracking = true) => ({
  type: SET_VIEW_MODE,
  payload,
  meta: { tracking }
});
export const hidePrintMode = () => ({
  type: HIDE_PRINT,
  meta: {
    tracking: true
  }
});
export const hideEmbedMode = () => ({
  type: HIDE_EMBED_PREVIEW,
  meta: {
    tracking: true
  }
});
export const toggleMapPanelHandle = () => ({ type: TOGGLE_MAP_PANEL_HANDLE });

// Selectors
const getUIState = (state) => state[REDUCER_KEY];
export const isEmbedded = createSelector(getUIState, (ui) => ui.isEmbed);
export const isEmbedPreview = createSelector(getUIState, (ui) => ui.isEmbedPreview);
export const isPrintMode = createSelector(getUIState, (ui) => ui.isPrintMode);
export const getViewMode = createSelector(getUIState, (ui) => ui.viewMode);
export const isPrintOrEmbedMode = createSelector(
  isEmbedded,
  isPrintMode,
  isEmbedPreview,
  (embedded, print, preview) =>
    Boolean(embedded || print || preview));
export const isMapLayersVisible = createSelector(getUIState, (ui) => ui.isMapLayersVisible);
export const isMapPanelHandleVisible =
  createSelector(getUIState, (ui) => ui.isMapPanelHandleVisible);

export const isMapPage = createSelector(isDataPage, getViewMode, (dataPage, viewMode) => (
  dataPage && viewMode === VIEW_MODE.MAP
));
export const isMapActive = createSelector(
  getViewMode, isMapPage,
  (viewMode, isMapPageActive) => viewMode === VIEW_MODE.MAP || isMapPageActive
);
export const hasPrintMode = createSelector(
  isDataSelectionPage,
  isDatasetPage,
  isDatasetDetailPage,
  isDataPage,
  isMapActive,
  getViewMode,
  (
    dataSelectionPage,
    datasetPage,
    datasetDetailPage,
    dataPage,
    mapActive,
    viewMode
  ) =>
    (!dataSelectionPage || viewMode === VIEW_MODE.SPLIT || viewMode === VIEW_MODE.MAP) &&
    (!datasetPage || datasetDetailPage) &&
    (dataPage || mapActive || viewMode === VIEW_MODE.SPLIT)
);
export const isPrintModeLandscape = createSelector(
  isPrintMode,
  isPanoPage,
  isMapPage,
  getViewMode,
  (printMode, panoPageActive, mapPageActive, viewMode) =>
    (printMode &&
      (panoPageActive || mapPageActive || (viewMode === VIEW_MODE.MAP))
    )
);
<commit_msg>DP-6765 enable print in full screen pano<commit_after>import { createSelector } from 'reselect';
import {
  isDataSelectionPage,
  isDatasetPage,
  isDatasetDetailPage,
  isPanoPage,
  isDataPage
} from '../../../store/redux-first-router/selectors';
import paramsRegistry from '../../../store/params-registry';

const REDUCER_KEY = 'ui';
export { REDUCER_KEY as UI };
export const HIDE_EMBED_PREVIEW = `${REDUCER_KEY}/HIDE_EMBED_PREVIEW`;
export const HIDE_PRINT = `${REDUCER_KEY}/HIDE_PRINT`;
export const SHOW_EMBED_PREVIEW = `${REDUCER_KEY}/SHOW_EMBED_PREVIEW`;
export const SHOW_PRINT = `${REDUCER_KEY}/SHOW_PRINT`;
export const TOGGLE_MAP_PANEL_HANDLE = `${REDUCER_KEY}/TOGGLE_MAP_PANEL_HANDLE`;
export const SET_VIEW_MODE = `${REDUCER_KEY}/SET_VIEW_MODE`;

export const VIEW_MODE = {
  MAP: 'kaart',
  SPLIT: 'gesplitst',
  FULL: 'volledig'
};

export const initialState = {
  isMapPanelHandleVisible: true,
  isEmbedPreview: false,
  isEmbed: false,
  isPrintMode: false,
  viewMode: VIEW_MODE.SPLIT
};

export default function UiReducer(state = initialState, action) {
  const enrichedState = {
    ...state,
    ...paramsRegistry.getStateFromQueries(REDUCER_KEY, action)
  };

  switch (action.type) {
    case HIDE_EMBED_PREVIEW:
      return {
        ...enrichedState,
        isEmbedPreview: false,
        isEmbed: false
      };

    case HIDE_PRINT:
      return {
        ...enrichedState,
        isPrintMode: false
      };

    case SHOW_EMBED_PREVIEW:
      return {
        ...enrichedState,
        isEmbedPreview: true
      };

    case SHOW_PRINT:
      return {
        ...enrichedState,
        isPrintMode: true
      };

    case SET_VIEW_MODE:
      return {
        ...enrichedState,
        viewMode: action.payload
      };

    case TOGGLE_MAP_PANEL_HANDLE:
      return {
        ...enrichedState,
        isMapPanelHandleVisible: !enrichedState.isMapPanelHandleVisible
      };

    default:
      return enrichedState;
  }
}

// Todo: wire these actions properly when ui reducer is obsolete
export const showEmbedPreview = () => ({
  type: SHOW_EMBED_PREVIEW,
  meta: {
    tracking: true
  }
});
export const showPrintMode = () => ({
  type: SHOW_PRINT,
  meta: {
    tracking: true
  }
});
export const setViewMode = (payload, tracking = true) => ({
  type: SET_VIEW_MODE,
  payload,
  meta: { tracking }
});
export const hidePrintMode = () => ({
  type: HIDE_PRINT,
  meta: {
    tracking: true
  }
});
export const hideEmbedMode = () => ({
  type: HIDE_EMBED_PREVIEW,
  meta: {
    tracking: true
  }
});
export const toggleMapPanelHandle = () => ({ type: TOGGLE_MAP_PANEL_HANDLE });

// Selectors
const getUIState = (state) => state[REDUCER_KEY];
export const isEmbedded = createSelector(getUIState, (ui) => ui.isEmbed);
export const isEmbedPreview = createSelector(getUIState, (ui) => ui.isEmbedPreview);
export const isPrintMode = createSelector(getUIState, (ui) => ui.isPrintMode);
export const getViewMode = createSelector(getUIState, (ui) => ui.viewMode);
export const isPrintOrEmbedMode = createSelector(
  isEmbedded,
  isPrintMode,
  isEmbedPreview,
  (embedded, print, preview) =>
    Boolean(embedded || print || preview));
export const isMapLayersVisible = createSelector(getUIState, (ui) => ui.isMapLayersVisible);
export const isMapPanelHandleVisible =
  createSelector(getUIState, (ui) => ui.isMapPanelHandleVisible);

export const isMapPage = createSelector(isDataPage, getViewMode, (dataPage, viewMode) => (
  dataPage && viewMode === VIEW_MODE.MAP
));
export const isMapActive = createSelector(
  getViewMode, isMapPage,
  (viewMode, isMapPageActive) => viewMode === VIEW_MODE.MAP || isMapPageActive
);
export const hasPrintMode = createSelector(
  isDataSelectionPage,
  isDatasetPage,
  isDatasetDetailPage,
  isDataPage,
  isMapActive,
  isPanoPage,
  getViewMode,
  (
    dataSelectionPage,
    datasetPage,
    datasetDetailPage,
    dataPage,
    mapActive,
    panoPageActive,
    viewMode
  ) =>
    ((!dataSelectionPage || viewMode === VIEW_MODE.SPLIT || viewMode === VIEW_MODE.MAP) &&
    (!datasetPage || datasetDetailPage) &&
    (dataPage || mapActive || viewMode === VIEW_MODE.SPLIT)) ||
    panoPageActive
);

export const isPrintModeLandscape = createSelector(
  isPrintMode,
  isPanoPage,
  isMapPage,
  getViewMode,
  (printMode, panoPageActive, mapPageActive, viewMode) =>
    (printMode &&
      (panoPageActive || mapPageActive || (viewMode === VIEW_MODE.MAP))
    )
);
<|endoftext|>


<commit_before>import _ from 'lodash';
import { Client } from 'node-rest-client';
import { promisifyNodeClient, link } from '../utils';
import { outputLog } from '../log.js';
import config from '../config';

const API_CHAMPIONGG = 'api.champion.gg';

const PROD = config.env === 'production';

const getDatas = () => new Promise(async (resolve, reject) => {

  if (!config.key.championgg) {
    console.log('No championgg key defined.');
    throw new Error('No championgg key defined.');
  }

  if (!PROD) {
    outputLog('[ChampionGG] Init REST client ...');
  }
  // Init client and GET methods
  const client = new Client();
  client.on('error', (err) => {
    reject(err);
  });
  try {
    client.registerMethod('getPatch', link('http', API_CHAMPIONGG, '/stats/overall'), 'GET');
    client.registerMethod('getChampions', link('http', API_CHAMPIONGG, '/champion'), 'GET');
    client.registerMethod('getChampionDatas', link('http', API_CHAMPIONGG, '/champion/${name}'), 'GET');
    // Promisify all the registered methods
    promisifyNodeClient(client);
  } catch (e) {
    reject(e);
  }
  if (!PROD) {
    outputLog('[ChampionGG] Init REST client : done !');
  }

  // Get the patch version
  outputLog('[ChampionGG] Retrieving the patch version ...');
  let patchVersion;
  try {
    const patchVersionRequest = await client.methods.getPatchAsync({ parameters: { api_key: config.key.championgg } });
    if (patchVersionRequest.error) {
      throw new Error(patchVersionRequest.error);
    }
    patchVersion = patchVersionRequest.patch;
  } catch (e) {
    reject(e);
  }
  outputLog(`[ChampionGG] Retrieving the patch version : done ! (${patchVersion})`);

  // Get the champions
  outputLog('[ChampionGG] Retrieving the champions list ...');
  let champs;
  try {
    const patchVersionRequest = await client.methods.getChampionsAsync({ parameters: { api_key: config.key.championgg } });
    if (patchVersionRequest.error) {
      throw new Error(patchVersionRequest.error);
    }
    champs = champsSets;
  } catch (e) {
    reject(e);
  }
  outputLog('[ChampionGG] Retrieving the champions list : done !');

  champs = _.sortBy(champs, c => c.key);

  if (config.env === 'test') {
    champs = [champs[0]];
  }

  // Get the champions data
  outputLog('[ChampionGG] Retrieving the champions datas ...');
  let champsSets = [];
  for (let champ of champs) {
    let champData;
    try {
      if (!PROD) {
        outputLog(`[ChampionGG] Getting ${champ.key} ...`);
      }
      const champDataRequest = await client.methods.getChampionDatasAsync({ path: { name: champ.key }, parameters: { api_key: config.key.championgg } });
      if (champDataRequest.error) {
        throw new Error(`${champ.key} : ${champDataRequest.error}`);
      }
      champData = champDataRequest;
      for (let roleData of champData) {
        if (!PROD) {
          outputLog(`[ChampionGG] ${champ.key}/${roleData.role} : ok.`);
        }
        champsSets.push({
          key: champ.key,
          role: roleData.role,
          name: champ.name,
          items: roleData.items,
          firstItems: roleData.firstItems,
          skills: roleData.skills,
          trinkets: roleData.trinkets,
        });
      }
    } catch (e) {
      reject(e);
    }
  }
  outputLog('[ChampionGG] Retrieving the champions datas : done !');

  const datas = {
    sets: champsSets,
    patch: patchVersion
  };

  resolve(datas);

});

export default getDatas;
<commit_msg>Fix champions not being imported.<commit_after>import _ from 'lodash';
import { Client } from 'node-rest-client';
import { promisifyNodeClient, link } from '../utils';
import { outputLog } from '../log.js';
import config from '../config';

const API_CHAMPIONGG = 'api.champion.gg';

const PROD = config.env === 'production';

const getDatas = () => new Promise(async (resolve, reject) => {

  if (!config.key.championgg) {
    console.log('No championgg key defined.');
    throw new Error('No championgg key defined.');
  }

  if (!PROD) {
    outputLog('[ChampionGG] Init REST client ...');
  }
  // Init client and GET methods
  const client = new Client();
  client.on('error', (err) => {
    reject(err);
  });
  try {
    client.registerMethod('getPatch', link('http', API_CHAMPIONGG, '/stats/overall'), 'GET');
    client.registerMethod('getChampions', link('http', API_CHAMPIONGG, '/champion'), 'GET');
    client.registerMethod('getChampionDatas', link('http', API_CHAMPIONGG, '/champion/${name}'), 'GET');
    // Promisify all the registered methods
    promisifyNodeClient(client);
  } catch (e) {
    reject(e);
  }
  if (!PROD) {
    outputLog('[ChampionGG] Init REST client : done !');
  }

  // Get the patch version
  outputLog('[ChampionGG] Retrieving the patch version ...');
  let patchVersion;
  try {
    const patchVersionRequest = await client.methods.getPatchAsync({ parameters: { api_key: config.key.championgg } });
    if (patchVersionRequest.error) {
      throw new Error(patchVersionRequest.error);
    }
    patchVersion = patchVersionRequest.patch;
  } catch (e) {
    reject(e);
  }
  outputLog(`[ChampionGG] Retrieving the patch version : done ! (${patchVersion})`);

  // Get the champions
  outputLog('[ChampionGG] Retrieving the champions list ...');
  let champs;
  try {
    const champsSetsRequest = await client.methods.getChampionsAsync({ parameters: { api_key: config.key.championgg } });
    if (champsSetsRequest.error) {
      throw new Error(champsSetsRequest.error);
    }
    champs = champsSetsRequest;
  } catch (e) {
    reject(e);
  }
  outputLog('[ChampionGG] Retrieving the champions list : done !');

  champs = _.sortBy(champs, c => c.key);

  if (config.env === 'test') {
    champs = [champs[0]];
  }

  // Get the champions data
  outputLog('[ChampionGG] Retrieving the champions datas ...');
  let champsSets = [];
  for (let champ of champs) {
    let champData;
    try {
      if (!PROD) {
        outputLog(`[ChampionGG] Getting ${champ.key} ...`);
      }
      const champDataRequest = await client.methods.getChampionDatasAsync({ path: { name: champ.key }, parameters: { api_key: config.key.championgg } });
      if (champDataRequest.error) {
        throw new Error(`${champ.key} : ${champDataRequest.error}`);
      }
      champData = champDataRequest;
      for (let roleData of champData) {
        if (!PROD) {
          outputLog(`[ChampionGG] ${champ.key}/${roleData.role} : ok.`);
        }
        champsSets.push({
          key: champ.key,
          role: roleData.role,
          name: champ.name,
          items: roleData.items,
          firstItems: roleData.firstItems,
          skills: roleData.skills,
          trinkets: roleData.trinkets,
        });
      }
    } catch (e) {
      reject(e);
    }
  }
  outputLog('[ChampionGG] Retrieving the champions datas : done !');

  const datas = {
    sets: champsSets,
    patch: patchVersion
  };

  resolve(datas);

});

export default getDatas;
<|endoftext|>


<commit_before>import {SitemapTransformer} from './sitemap_transformer';
import {Url} from '../url';
import {config} from '../config';
import {extend} from 'underscore';
const libxml = require('libxmljs');

const DEFAULT_OPTIONS = {
  urlTag: 'url',
  urlAttributes: {
    'lastmod': 'lastModified',
    'changefreq': 'changeFrequency',
    'priority': 'priority',
    'loc': 'url'
  }
};
export class XmlSource extends SitemapTransformer {
  constructor(options) {
    super(options);
    let myConfig = extend({}, DEFAULT_OPTIONS, options.options);
    this.parser = new libxml.SaxPushParser();
    this.parser.on("startElementNS", (element) => {
      if (element === myConfig.urlTag) {
        this.url = {};
      } else if (this.url) {
        this.url.nextAttribute = element;
      }
    }).on("endElementNS", (element) => {
      if (element === myConfig.urlTag) {
        try {
          delete this.url.nextAttribute;
          if (this.url.lastModified) {
            //config.log.trace(`PARSING ${this.url.lastModified} as a date`);
            this.url.lastModified = Date.parse(this.url.lastModified);
          }
          if (this.url.priority) {
            config.log.trace(`PARSING ${this.url.priority} as a float`);
            this.url.priority = parseFloat(this.url.priority);
          }
          let url = this._decorateUrl(new Url(this.url));
          if (url) {
            this.push(url);
          }
        } catch (err) {
          this.emit("error", err);
        }
        this.url = null;
      }
    }).on("characters", (text) => {
      if (this.url && this.url.nextAttribute) {
        let urlAttr = myConfig.urlAttributes[this.url.nextAttribute];
        if (urlAttr) {
          this.url[urlAttr] = `${this.url[urlAttr] || ''}${text}`.trim();
        }
      }
    }).on("error", (err) => {
      this.emit("error", err);
    });
  }
  _transform(chunk, encoding, callback) {
    this.parser.push(chunk);
    callback();
  }
  open() {
    super.open();
    if (this.inputStream) {
      this.inputStream.pipe(this);
    }
  }
}
<commit_msg>fix: remove chatty trace logging<commit_after>import {SitemapTransformer} from './sitemap_transformer';
import {Url} from '../url';
import {config} from '../config';
import {extend} from 'underscore';
const libxml = require('libxmljs');

const DEFAULT_OPTIONS = {
  urlTag: 'url',
  urlAttributes: {
    'lastmod': 'lastModified',
    'changefreq': 'changeFrequency',
    'priority': 'priority',
    'loc': 'url'
  }
};
export class XmlSource extends SitemapTransformer {
  constructor(options) {
    super(options);
    let myConfig = extend({}, DEFAULT_OPTIONS, options.options);
    this.parser = new libxml.SaxPushParser();
    this.parser.on("startElementNS", (element) => {
      if (element === myConfig.urlTag) {
        this.url = {};
      } else if (this.url) {
        this.url.nextAttribute = element;
      }
    }).on("endElementNS", (element) => {
      if (element === myConfig.urlTag) {
        try {
          delete this.url.nextAttribute;
          if (this.url.lastModified) {
            //config.log.trace(`PARSING ${this.url.lastModified} as a date`);
            this.url.lastModified = Date.parse(this.url.lastModified);
          }
          if (this.url.priority) {
            //config.log.trace(`PARSING ${this.url.priority} as a float`);
            this.url.priority = parseFloat(this.url.priority);
          }
          let url = this._decorateUrl(new Url(this.url));
          if (url) {
            this.push(url);
          }
        } catch (err) {
          this.emit("error", err);
        }
        this.url = null;
      }
    }).on("characters", (text) => {
      if (this.url && this.url.nextAttribute) {
        let urlAttr = myConfig.urlAttributes[this.url.nextAttribute];
        if (urlAttr) {
          this.url[urlAttr] = `${this.url[urlAttr] || ''}${text}`.trim();
        }
      }
    }).on("error", (err) => {
      this.emit("error", err);
    });
  }
  _transform(chunk, encoding, callback) {
    this.parser.push(chunk);
    callback();
  }
  open() {
    super.open();
    if (this.inputStream) {
      this.inputStream.pipe(this);
    }
  }
}
<|endoftext|>


<commit_before>const ArgumentDefault = require('../enums/ArgumentDefault.js');
const CooldownResult = require('../results/CooldownResult.js');
const ExceptionResult = require('../results/ExceptionResult.js');
const Constants = require('../utility/Constants.js');

/**
 * The command handler.
 * @prop {Registry} registry The registry used to instantiate the command handler.
 */
class Handler {
  /**
   * @param {Registry} registry The registry used to handle the commands.
   */
  constructor(registry) {
    this.registry = registry;
  }

  /**
   * Attempts to execute a command.
   * @param {Message} message The received message.
   * @param {string} prefix The prefix to use when handling the command.
   * @param {*} custom Any custom parameters to be passed into all preconditions, commands, and type readers.
   * @returns {Promise<Result>|Promise<CooldownResult>|Promise<TypeReaderResult>|Promise<PreconditionResult>|Promise<ExceptionResult>} The result of the command execution.
   */
  async run(message, prefix, ...custom) {
    try {
      const split = message.content.slice(prefix.length).match(Constants.regexes.argument);

      const commandName = split.shift().toLowerCase();

      var command = this.registry.commands.find((x) => x.names.some((y) => y === commandName));

      if (command === undefined) {
        return Constants.results.commandNotFound(commandName);
      }

      if (message.guild !== null) {
        if (command.dmOnly === true) {
          return Constants.results.dmOnly(command);
        }

        const result = this.registry.libraryHandler.validatePermissions(command, message);

        if (result !== undefined) {
          return result;
        }
      } else if (command.guildOnly === true) {
        return Constants.results.guildOnly(command);
      }

      for (let i = 0; i < command.preconditions.length; i++) {
        const result = await command.preconditions[i].run(command, message, command.preconditionOptions[i], ...custom);

        if (result.success === false) {
          return result;
        }
      }

      for (let i = 0; i < command.group.preconditions.length; i++) {
        const result = await command.group.preconditions[i].run(command, message, command.group.preconditionOptions[i], ...custom);

        if (result.success === false) {
          return result;
        }
      }

      if (command.hasCooldown === true) {
        const cooldown = command.cooldowns[message.author.id + (message.guild !== null ? '-' + message.guild.id : '')];

        if (cooldown !== undefined) {
          const difference = cooldown - Date.now();

          if (difference > 0) {
            return CooldownResult.fromError(command, difference);
          }
        }
      }

      const args = {};

      for (let i = 0; i < command.args.length; i++) {
        let value = [];
        let defaultValue = false;

        if (command.args[i].infinite === true) {
          if (split.length === 0) {
            if (command.args[i].optional === true) {
              value = this.defaultValue(command.args[i], message);
              defaultValue = true;
            } else {
              return Constants.results.invalidArgCount(command);
            }
          } else {
            for (let j = 0; j < split.length; j++) {
              if (Constants.regexes.quotesMatch.test(split[j]) === true) {
                split[j] = split[j].replace(Constants.regexes.quotes, '');
              }

              const typeReaderResult = await command.args[i].typeReader.read(command, message, command.args[i], args, split[j], ...custom);

              if (typeReaderResult.success === false) {
                return typeReaderResult;
              }

              value.push(typeReaderResult.value);
            }
          }
        } else {
          let input = command.args[i].remainder === true ? split.join(' ') : split.shift();

          if (Constants.regexes.quotesMatch.test(input) === true) {
            input = input.replace(Constants.regexes.quotes, '');
          }

          if (input === undefined || input === '') {
            if (command.args[i].optional === false) {
              return Constants.results.invalidArgCount(command);
            }

            value = this.defaultValue(command.args[i], message);
            defaultValue = true;
          } else {
            const typeReaderResult = await command.args[i].typeReader.read(command, message, command.args[i], args, input, ...custom);

            if (typeReaderResult.success === false) {
              return typeReaderResult;
            }

            value = typeReaderResult.value;
          }
        }

        if (defaultValue === false) {
          for (let j = 0; j < command.args[i].preconditions.length; j++) {
            const preconditionResult = await command.args[i].preconditions[j].run(command, message, command.args[i], args, value, command.args[i].preconditionOptions[j], ...custom);

            if (preconditionResult.success === false) {
              return preconditionResult;
            }
          }
        }

        args[command.args[i].key] = value;
      }

      await command.run(message, args, ...custom);

      if (command.hasCooldown === true) {
        command.cooldowns[message.author.id + (message.guild !== null ? '-' + message.guild.id : '')] = Date.now() + command.cooldown;
      }

      return Constants.results.success(command);
    } catch (err) {
      return ExceptionResult.fromError(command, err);
    }
  }

  /**
   * The default value of an argument based off a command message.
   * @param {Argument} argument The argument being parsed.
   * @param {Message} message The received message.
   * @returns {*} The default value of the argument.
   * @private
   */
  defaultValue(argument, message) {
    switch (argument.defaultValue) {
      case ArgumentDefault.Author:
        return message.author;
      case ArgumentDefault.Message:
        return message;
      case ArgumentDefault.Member:
        return message.member;
      case ArgumentDefault.Channel:
        return message.channel;
      case ArgumentDefault.Guild:
        return message.guild;
      case ArgumentDefault.HighestRole:
        return message.member.highestRole;
      default:
        return argument.defaultValue;
    }
  }
}

module.exports = Handler;
<commit_msg>run preconditions on default values<commit_after>const ArgumentDefault = require('../enums/ArgumentDefault.js');
const CooldownResult = require('../results/CooldownResult.js');
const ExceptionResult = require('../results/ExceptionResult.js');
const Constants = require('../utility/Constants.js');

/**
 * The command handler.
 * @prop {Registry} registry The registry used to instantiate the command handler.
 */
class Handler {
  /**
   * @param {Registry} registry The registry used to handle the commands.
   */
  constructor(registry) {
    this.registry = registry;
  }

  /**
   * Attempts to execute a command.
   * @param {Message} message The received message.
   * @param {string} prefix The prefix to use when handling the command.
   * @param {*} custom Any custom parameters to be passed into all preconditions, commands, and type readers.
   * @returns {Promise<Result>|Promise<CooldownResult>|Promise<TypeReaderResult>|Promise<PreconditionResult>|Promise<ExceptionResult>} The result of the command execution.
   */
  async run(message, prefix, ...custom) {
    try {
      const split = message.content.slice(prefix.length).match(Constants.regexes.argument);

      const commandName = split.shift().toLowerCase();

      var command = this.registry.commands.find((x) => x.names.some((y) => y === commandName));

      if (command === undefined) {
        return Constants.results.commandNotFound(commandName);
      }

      if (message.guild !== null) {
        if (command.dmOnly === true) {
          return Constants.results.dmOnly(command);
        }

        const result = this.registry.libraryHandler.validatePermissions(command, message);

        if (result !== undefined) {
          return result;
        }
      } else if (command.guildOnly === true) {
        return Constants.results.guildOnly(command);
      }

      for (let i = 0; i < command.preconditions.length; i++) {
        const result = await command.preconditions[i].run(command, message, command.preconditionOptions[i], ...custom);

        if (result.success === false) {
          return result;
        }
      }

      for (let i = 0; i < command.group.preconditions.length; i++) {
        const result = await command.group.preconditions[i].run(command, message, command.group.preconditionOptions[i], ...custom);

        if (result.success === false) {
          return result;
        }
      }

      if (command.hasCooldown === true) {
        const cooldown = command.cooldowns[message.author.id + (message.guild !== null ? '-' + message.guild.id : '')];

        if (cooldown !== undefined) {
          const difference = cooldown - Date.now();

          if (difference > 0) {
            return CooldownResult.fromError(command, difference);
          }
        }
      }

      const args = {};

      for (let i = 0; i < command.args.length; i++) {
        let value = [];

        if (command.args[i].infinite === true) {
          if (split.length === 0) {
            if (command.args[i].optional === true) {
              value = this.defaultValue(command.args[i], message);
            } else {
              return Constants.results.invalidArgCount(command);
            }
          } else {
            for (let j = 0; j < split.length; j++) {
              if (Constants.regexes.quotesMatch.test(split[j]) === true) {
                split[j] = split[j].replace(Constants.regexes.quotes, '');
              }

              const typeReaderResult = await command.args[i].typeReader.read(command, message, command.args[i], args, split[j], ...custom);

              if (typeReaderResult.success === false) {
                return typeReaderResult;
              }

              value.push(typeReaderResult.value);
            }
          }
        } else {
          let input = command.args[i].remainder === true ? split.join(' ') : split.shift();

          if (Constants.regexes.quotesMatch.test(input) === true) {
            input = input.replace(Constants.regexes.quotes, '');
          }

          if (input === undefined || input === '') {
            if (command.args[i].optional === false) {
              return Constants.results.invalidArgCount(command);
            }

            value = this.defaultValue(command.args[i], message);
          } else {
            const typeReaderResult = await command.args[i].typeReader.read(command, message, command.args[i], args, input, ...custom);

            if (typeReaderResult.success === false) {
              return typeReaderResult;
            }

            value = typeReaderResult.value;
          }
        }

        for (let j = 0; j < command.args[i].preconditions.length; j++) {
          const preconditionResult = await command.args[i].preconditions[j].run(command, message, command.args[i], args, value, command.args[i].preconditionOptions[j], ...custom);

          if (preconditionResult.success === false) {
            return preconditionResult;
          }
        }

        args[command.args[i].key] = value;
      }

      await command.run(message, args, ...custom);

      if (command.hasCooldown === true) {
        command.cooldowns[message.author.id + (message.guild !== null ? '-' + message.guild.id : '')] = Date.now() + command.cooldown;
      }

      return Constants.results.success(command);
    } catch (err) {
      return ExceptionResult.fromError(command, err);
    }
  }

  /**
   * The default value of an argument based off a command message.
   * @param {Argument} argument The argument being parsed.
   * @param {Message} message The received message.
   * @returns {*} The default value of the argument.
   * @private
   */
  defaultValue(argument, message) {
    switch (argument.defaultValue) {
      case ArgumentDefault.Author:
        return message.author;
      case ArgumentDefault.Message:
        return message;
      case ArgumentDefault.Member:
        return message.member;
      case ArgumentDefault.Channel:
        return message.channel;
      case ArgumentDefault.Guild:
        return message.guild;
      case ArgumentDefault.HighestRole:
        return message.member.highestRole;
      default:
        return argument.defaultValue;
    }
  }
}

module.exports = Handler;
<|endoftext|>


<commit_before>// This script is deverable

"use strict";
window.addEventListener('load', function(e) {
	function element(id) {
		return document.getElementById(id);
	}

	var errors = [];
	var BrowserPlatform = jsx.Platform.extend({
		load: function (name) {
			var src = element(name);
			if(src != null) {
				return src.value;
			}

			// synchronous XHR
			var xhr = new XMLHttpRequest();
			xhr.open("GET", name, false);
			xhr.send(null);
			return xhr.responseText;
		},

		error: function (s) {
			console.error(s);
			errors.push(s);
		}
	});
	var platform = new BrowserPlatform();

	var list   = element('source-list');

	var input  = element('input');
	var output = element('output');

	var saved = sessionStorage.getItem("source");
	if(saved != null) {
		input.value = saved;
	}

	function compile(options) {
		console.log('compile with ' + JSON.stringify(options));

		sessionStorage.setItem("source", input.value);

		output.value = '';

		var c = new jsx.Compiler(platform);
		switch(options.mode) {
		case "compile":
			c.setMode(jsx.Compiler.MODE_COMPILE);
			break;
		case "parse":
			c.setMode(jsx.Compiler.MODE_PARSE);
			  break;
		 default:
			alert("unknown mode: " + options.mode);
			return;
		}

		c.addSourceFile('input');

		var success = c.compile();
		console.log(c);

		if (success) {
			output.style.color = "black";
			output.value = c.getOutput();
		}
		else if(errors.length !== 0){
			output.style.color = "red";
			output.value = "ERROR!\n\n" + errors.join("\n");
		}
	}

	function forEach(collection, block) {
		for(var i = 0; i < collection.length; ++i) {
			block(collection[i]);
		}
	}

	// set up example souce files
	forEach(list.children, function(li) {
		if(li.className !== "source-file") return;

		var a = li.children[0];
		a.addEventListener('click', function(event) {
			var xhr = new XMLHttpRequest();
			xhr.onreadystatechange = function() {
				if(xhr.readyState !== 4)   return;
				if(xhr.status     !== 200) return;

				input.value = xhr.responseText;

				forEach(list.children, function(li) {
					li.className = "";
				});
				li.className = "active";

				setTimeout(function() {
					compile({ mode: "compile" });
				}, 0);
			};
			xhr.open("GET", "example/" + a.innerHTML);
			xhr.send(null);
		});
	});

	// hack to input TAB by the tab key
	input.addEventListener('keydown', function(event) {
		var TAB = "\t"
		if(event.keyCode === TAB.charCodeAt(0)) {
			event.stopPropagation();
			event.preventDefault();
			var s = input.selectionStart;
			var c = input.value;

			input.value = c.substring(0, s) +
						  TAB +
						  c.substring(s, c.length);
			var pos = s + TAB.length;
			input.setSelectionRange(pos, pos);
		}
	});

	element('compile').addEventListener('click',
			function(e) { compile({mode: 'compile'}) });
	element('parse').addEventListener('click',
			function(e) { compile({mode: 'parse'}) });
});
<commit_msg>Improve the web: support ^C for compile and ^P for parse<commit_after>// This script is deverable

"use strict";
window.addEventListener('load', function(e) {
	function element(id) {
		return document.getElementById(id);
	}

	var errors = [];
	var BrowserPlatform = jsx.Platform.extend({
		load: function (name) {
			var src = element(name);
			if(src != null) {
				return src.value;
			}

			// synchronous XHR
			var xhr = new XMLHttpRequest();
			xhr.open("GET", name, false);
			xhr.send(null);
			return xhr.responseText;
		},

		error: function (s) {
			console.error(s);
			errors.push(s);
		}
	});
	var platform = new BrowserPlatform();

	var list   = element('source-list');

	var input  = element('input');
	var output = element('output');

	function saveInput(input) {
			var s = input.selectionStart;
		var session = {
			source:         input.value,
			selectionStart: input.selectionStart,
			selectionEnd:   input.selectionEnd
		};

		sessionStorage.setItem("jsx.session", JSON.stringify(session));
	}

	function retrieveInput(input) {
		var serializedSession = sessionStorage.getItem("jsx.session");
		if(serializedSession) {
			var session = JSON.parse(serializedSession);

			input.value = session.source;
			input.setSelectionRange(session.selectionStart,
									session.selectionEnd);

			compile({ mode: 'compile' });
		}
	}

	function compile(options) {
		console.log('compile with ' + JSON.stringify(options));

		saveInput(input);

		output.value = '';

		var c = new jsx.Compiler(platform);
		switch(options.mode) {
		case "compile":
			c.setMode(jsx.Compiler.MODE_COMPILE);
			break;
		case "parse":
			c.setMode(jsx.Compiler.MODE_PARSE);
			  break;
		 default:
			alert("unknown mode: " + options.mode);
			return;
		}

		c.addSourceFile('input');

		var success = c.compile();
		console.log(c);

		if (success) {
			output.style.color = "black";
			output.value = c.getOutput();
		}
		else if(errors.length !== 0){
			output.style.color = "red";
			output.value = "ERROR!\n\n" + errors.join("\n");
		}
	}

	function forEach(collection, block) {
		for(var i = 0; i < collection.length; ++i) {
			block(collection[i]);
		}
	}

	// set up example souce files
	forEach(list.children, function(li) {
		if(li.className !== "source-file") return;

		var a = li.children[0];
		a.addEventListener('click', function(event) {
			var xhr = new XMLHttpRequest();
			xhr.onreadystatechange = function() {
				if(xhr.readyState !== 4)   return;
				if(xhr.status     !== 200) return;

				input.value = xhr.responseText;

				forEach(list.children, function(li) {
					li.className = "";
				});
				li.className = "active";

				setTimeout(function() {
					compile({ mode: "compile" });
				}, 0);
			};
			xhr.open("GET", "example/" + a.innerHTML);
			xhr.send(null);
		});
	});

	// hack to input TAB by the tab key
	input.addEventListener('keydown', function(event) {
		var TAB = "\t"
		if(event.keyCode === TAB.charCodeAt(0)) {
			event.stopPropagation();
			event.preventDefault();
			var s = input.selectionStart;
			var c = input.value;

			input.value = c.substring(0, s) +
						  TAB +
						  c.substring(s, c.length);
			var pos = s + TAB.length;
			input.setSelectionRange(pos, pos);
		}
	});

	window.addEventListener('keyup', function(event) {
		if(event.ctrlKey) {
			var COMPILE_KEY = "C".charCodeAt(0);
			var PARSE_KEY   = "P".charCodeAt(0);;

			if(event.keyCode === COMPILE_KEY) {
				compile({ mode: 'compile' });
			}
			else if(event.keyCode === PARSE_KEY) {
				compile({ mode: 'parse' });
			}
		}
	});

	element('compile').addEventListener('click',
			function(e) { compile({mode: 'compile'}) });
	element('parse').addEventListener('click',
			function(e) { compile({mode: 'parse'}) });

	retrieveInput(input);

	input.focus();
});
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
 *
 * 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.
 */

'use strict';

// Checking if the typed arrays are supported
(function checkTypedArrayCompatibility() {
  if (typeof Uint8Array !== 'undefined') {
    // some mobile versions do not support subarray (e.g. safari 5 / iOS)
    if (typeof Uint8Array.prototype.subarray === 'undefined') {
        Uint8Array.prototype.subarray = function subarray(start, end) {
          return new Uint8Array(this.slice(start, end));
        };
        Float32Array.prototype.subarray = function subarray(start, end) {
          return new Float32Array(this.slice(start, end));
        };
    }

    // some mobile version might not support Float64Array
    if (typeof Float64Array === 'undefined')
      window.Float64Array = Float32Array;

    return;
  }

  function subarray(start, end) {
    return new TypedArray(this.slice(start, end));
  }

  function setArrayOffset(array, offset) {
    if (arguments.length < 2)
      offset = 0;
    for (var i = 0, n = array.length; i < n; ++i, ++offset)
      this[offset] = array[i] & 0xFF;
  }

  function TypedArray(arg1) {
    var result;
    if (typeof arg1 === 'number') {
      result = [];
      for (var i = 0; i < arg1; ++i)
        result[i] = 0;
    } else
      result = arg1.slice(0);

    result.subarray = subarray;
    result.buffer = result;
    result.byteLength = result.length;
    result.set = setArrayOffset;

    if (typeof arg1 === 'object' && arg1.buffer)
      result.buffer = arg1.buffer;

    return result;
  }

  window.Uint8Array = TypedArray;

  // we don't need support for set, byteLength for 32-bit array
  // so we can use the TypedArray as well
  window.Uint32Array = TypedArray;
  window.Int32Array = TypedArray;
  window.Uint16Array = TypedArray;
  window.Float32Array = TypedArray;
  window.Float64Array = TypedArray;
})();

// Object.create() ?
(function checkObjectCreateCompatibility() {
  if (typeof Object.create !== 'undefined')
    return;

  Object.create = function objectCreate(proto) {
    var constructor = function objectCreateConstructor() {};
    constructor.prototype = proto;
    return new constructor();
  };
})();

// Object.defineProperty() ?
(function checkObjectDefinePropertyCompatibility() {
  if (typeof Object.defineProperty !== 'undefined') {
    // some browsers (e.g. safari) cannot use defineProperty() on DOM objects
    // and thus the native version is not sufficient
    var definePropertyPossible = true;
    try {
      Object.defineProperty(new Image(), 'id', { value: 'test' });
    } catch (e) {
      definePropertyPossible = false;
    }
    if (definePropertyPossible) return;
  }

  Object.defineProperty = function objectDefineProperty(obj, name, def) {
    delete obj[name];
    if ('get' in def)
      obj.__defineGetter__(name, def['get']);
    if ('set' in def)
      obj.__defineSetter__(name, def['set']);
    if ('value' in def) {
      obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
        this.__defineGetter__(name, function objectDefinePropertyGetter() {
          return value;
        });
        return value;
      });
      obj[name] = def.value;
    }
  };
})();

// Object.keys() ?
(function checkObjectKeysCompatibility() {
  if (typeof Object.keys !== 'undefined')
    return;

  Object.keys = function objectKeys(obj) {
    var result = [];
    for (var i in obj) {
      if (obj.hasOwnProperty(i))
        result.push(i);
    }
    return result;
  };
})();

// No readAsArrayBuffer ?
(function checkFileReaderReadAsArrayBuffer() {
  if (typeof FileReader === 'undefined')
    return; // FileReader is not implemented
  var frPrototype = FileReader.prototype;
  // Older versions of Firefox might not have readAsArrayBuffer
  if ('readAsArrayBuffer' in frPrototype)
    return; // readAsArrayBuffer is implemented
  Object.defineProperty(frPrototype, 'readAsArrayBuffer', {
    value: function fileReaderReadAsArrayBuffer(blob) {
      var fileReader = new FileReader();
      var originalReader = this;
      fileReader.onload = function fileReaderOnload(evt) {
        var data = evt.target.result;
        var buffer = new ArrayBuffer(data.length);
        var uint8Array = new Uint8Array(buffer);

        for (var i = 0, ii = data.length; i < ii; i++)
          uint8Array[i] = data.charCodeAt(i);

        Object.defineProperty(originalReader, 'result', {
          value: buffer,
          enumerable: true,
          writable: false,
          configurable: true
        });

        var event = document.createEvent('HTMLEvents');
        event.initEvent('load', false, false);
        originalReader.dispatchEvent(event);
      };
      fileReader.readAsBinaryString(blob);
    }
  });
})();

// No XMLHttpRequest.response ?
(function checkXMLHttpRequestResponseCompatibility() {
  var xhrPrototype = XMLHttpRequest.prototype;
  if (!('overrideMimeType' in xhrPrototype)) {
    // IE10 might have response, but not overrideMimeType
    Object.defineProperty(xhrPrototype, 'overrideMimeType', {
      value: function xmlHttpRequestOverrideMimeType(mimeType) {}
    });
  }
  if ('response' in xhrPrototype ||
      'mozResponseArrayBuffer' in xhrPrototype ||
      'mozResponse' in xhrPrototype ||
      'responseArrayBuffer' in xhrPrototype)
    return;
  // IE9 ?
  if (typeof VBArray !== 'undefined') {
    Object.defineProperty(xhrPrototype, 'response', {
      get: function xmlHttpRequestResponseGet() {
        return new Uint8Array(new VBArray(this.responseBody).toArray());
      }
    });
    return;
  }

  // other browsers
  function responseTypeSetter() {
    // will be only called to set "arraybuffer"
    this.overrideMimeType('text/plain; charset=x-user-defined');
  }
  if (typeof xhrPrototype.overrideMimeType === 'function') {
    Object.defineProperty(xhrPrototype, 'responseType',
                          { set: responseTypeSetter });
  }
  function responseGetter() {
    var text = this.responseText;
    var i, n = text.length;
    var result = new Uint8Array(n);
    for (i = 0; i < n; ++i)
      result[i] = text.charCodeAt(i) & 0xFF;
    return result;
  }
  Object.defineProperty(xhrPrototype, 'response', { get: responseGetter });
})();

// window.btoa (base64 encode function) ?
(function checkWindowBtoaCompatibility() {
  if ('btoa' in window)
    return;

  var digits =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

  window.btoa = function windowBtoa(chars) {
    var buffer = '';
    var i, n;
    for (i = 0, n = chars.length; i < n; i += 3) {
      var b1 = chars.charCodeAt(i) & 0xFF;
      var b2 = chars.charCodeAt(i + 1) & 0xFF;
      var b3 = chars.charCodeAt(i + 2) & 0xFF;
      var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
      var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
      var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
      buffer += (digits.charAt(d1) + digits.charAt(d2) +
                 digits.charAt(d3) + digits.charAt(d4));
    }
    return buffer;
  };
})();

// Function.prototype.bind ?
(function checkFunctionPrototypeBindCompatibility() {
  if (typeof Function.prototype.bind !== 'undefined')
    return;

  Function.prototype.bind = function functionPrototypeBind(obj) {
    var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
    var bound = function functionPrototypeBindBound() {
      var args = Array.prototype.concat.apply(headArgs, arguments);
      return fn.apply(obj, args);
    };
    return bound;
  };
})();

// IE9/10 text/html data URI
(function checkDataURICompatibility() {
  if (!('documentMode' in document) ||
      document.documentMode !== 9 && document.documentMode !== 10)
    return;
  // overriding the src property
  var originalSrcDescriptor = Object.getOwnPropertyDescriptor(
    HTMLIFrameElement.prototype, 'src');
  Object.defineProperty(HTMLIFrameElement.prototype, 'src', {
    get: function htmlIFrameElementPrototypeSrcGet() { return this.$src; },
    set: function htmlIFrameElementPrototypeSrcSet(src) {
      this.$src = src;
      if (src.substr(0, 14) != 'data:text/html') {
        originalSrcDescriptor.set.call(this, src);
        return;
      }
      // for text/html, using blank document and then
      // document's open, write, and close operations
      originalSrcDescriptor.set.call(this, 'about:blank');
      setTimeout((function htmlIFrameElementPrototypeSrcOpenWriteClose() {
        var doc = this.contentDocument;
        doc.open('text/html');
        doc.write(src.substr(src.indexOf(',') + 1));
        doc.close();
      }).bind(this), 0);
    },
    enumerable: true
  });
})();

// HTMLElement dataset property
(function checkDatasetProperty() {
  var div = document.createElement('div');
  if ('dataset' in div)
    return; // dataset property exists

  Object.defineProperty(HTMLElement.prototype, 'dataset', {
    get: function() {
      if (this._dataset)
        return this._dataset;

      var dataset = {};
      for (var j = 0, jj = this.attributes.length; j < jj; j++) {
        var attribute = this.attributes[j];
        if (attribute.name.substring(0, 5) != 'data-')
          continue;
        var key = attribute.name.substring(5).replace(/\-([a-z])/g,
          function(all, ch) { return ch.toUpperCase(); });
        dataset[key] = attribute.value;
      }

      Object.defineProperty(this, '_dataset', {
        value: dataset,
        writable: false,
        enumerable: false
      });
      return dataset;
    },
    enumerable: true
  });
})();

// HTMLElement classList property
(function checkClassListProperty() {
  var div = document.createElement('div');
  if ('classList' in div)
    return; // classList property exists

  function changeList(element, itemName, add, remove) {
    var s = element.className || '';
    var list = s.split(/\s+/g);
    if (list[0] == '') list.shift();
    var index = list.indexOf(itemName);
    if (index < 0 && add)
      list.push(itemName);
    if (index >= 0 && remove)
      list.splice(index, 1);
    element.className = list.join(' ');
  }

  var classListPrototype = {
    add: function(name) {
      changeList(this.element, name, true, false);
    },
    remove: function(name) {
      changeList(this.element, name, false, true);
    },
    toggle: function(name) {
      changeList(this.element, name, true, true);
    }
  };

  Object.defineProperty(HTMLElement.prototype, 'classList', {
    get: function() {
      if (this._classList)
        return this._classList;

      var classList = Object.create(classListPrototype, {
        element: {
          value: this,
          writable: false,
          enumerable: true
        }
      });
      Object.defineProperty(this, '_classList', {
        value: classList,
        writable: false,
        enumerable: false
      });
      return classList;
    },
    enumerable: true
  });
})();

// Check console compatability
(function checkConsoleCompatibility() {
  if (typeof console == 'undefined') {
    console = {log: function() {}};
  }
})();

// Check onclick compatibility in Opera
(function checkOnClickCompatibility() {
  // workaround for reported Opera bug DSK-354448:
  // onclick fires on disabled buttons with opaque content
  function ignoreIfTargetDisabled(event) {
    if (isDisabled(event.target)) {
      event.stopPropagation();
    }
  }
  function isDisabled(node) {
    return node.disabled || (node.parentNode && isDisabled(node.parentNode));
  }
  if (navigator.userAgent.indexOf('Opera') != -1) {
    // use browser detection since we cannot feature-check this bug
    document.addEventListener('click', ignoreIfTargetDisabled, true);
  }
})();

// Checks if navigator.language is supported
(function checkNavigatorLanguage() {
  if ('language' in navigator)
    return;
  Object.defineProperty(navigator, 'language', {
    get: function navigatorLanguage() {
      var language = navigator.userLanguage || 'en-US';
      return language.substring(0, 2).toLowerCase() +
        language.substring(2).toUpperCase();
    },
    enumerable: true
  });
})();
<commit_msg>Fixes console log methods for IE9<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2012 Mozilla Foundation
 *
 * 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.
 */

'use strict';

// Checking if the typed arrays are supported
(function checkTypedArrayCompatibility() {
  if (typeof Uint8Array !== 'undefined') {
    // some mobile versions do not support subarray (e.g. safari 5 / iOS)
    if (typeof Uint8Array.prototype.subarray === 'undefined') {
        Uint8Array.prototype.subarray = function subarray(start, end) {
          return new Uint8Array(this.slice(start, end));
        };
        Float32Array.prototype.subarray = function subarray(start, end) {
          return new Float32Array(this.slice(start, end));
        };
    }

    // some mobile version might not support Float64Array
    if (typeof Float64Array === 'undefined')
      window.Float64Array = Float32Array;

    return;
  }

  function subarray(start, end) {
    return new TypedArray(this.slice(start, end));
  }

  function setArrayOffset(array, offset) {
    if (arguments.length < 2)
      offset = 0;
    for (var i = 0, n = array.length; i < n; ++i, ++offset)
      this[offset] = array[i] & 0xFF;
  }

  function TypedArray(arg1) {
    var result;
    if (typeof arg1 === 'number') {
      result = [];
      for (var i = 0; i < arg1; ++i)
        result[i] = 0;
    } else
      result = arg1.slice(0);

    result.subarray = subarray;
    result.buffer = result;
    result.byteLength = result.length;
    result.set = setArrayOffset;

    if (typeof arg1 === 'object' && arg1.buffer)
      result.buffer = arg1.buffer;

    return result;
  }

  window.Uint8Array = TypedArray;

  // we don't need support for set, byteLength for 32-bit array
  // so we can use the TypedArray as well
  window.Uint32Array = TypedArray;
  window.Int32Array = TypedArray;
  window.Uint16Array = TypedArray;
  window.Float32Array = TypedArray;
  window.Float64Array = TypedArray;
})();

// Object.create() ?
(function checkObjectCreateCompatibility() {
  if (typeof Object.create !== 'undefined')
    return;

  Object.create = function objectCreate(proto) {
    var constructor = function objectCreateConstructor() {};
    constructor.prototype = proto;
    return new constructor();
  };
})();

// Object.defineProperty() ?
(function checkObjectDefinePropertyCompatibility() {
  if (typeof Object.defineProperty !== 'undefined') {
    // some browsers (e.g. safari) cannot use defineProperty() on DOM objects
    // and thus the native version is not sufficient
    var definePropertyPossible = true;
    try {
      Object.defineProperty(new Image(), 'id', { value: 'test' });
    } catch (e) {
      definePropertyPossible = false;
    }
    if (definePropertyPossible) return;
  }

  Object.defineProperty = function objectDefineProperty(obj, name, def) {
    delete obj[name];
    if ('get' in def)
      obj.__defineGetter__(name, def['get']);
    if ('set' in def)
      obj.__defineSetter__(name, def['set']);
    if ('value' in def) {
      obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
        this.__defineGetter__(name, function objectDefinePropertyGetter() {
          return value;
        });
        return value;
      });
      obj[name] = def.value;
    }
  };
})();

// Object.keys() ?
(function checkObjectKeysCompatibility() {
  if (typeof Object.keys !== 'undefined')
    return;

  Object.keys = function objectKeys(obj) {
    var result = [];
    for (var i in obj) {
      if (obj.hasOwnProperty(i))
        result.push(i);
    }
    return result;
  };
})();

// No readAsArrayBuffer ?
(function checkFileReaderReadAsArrayBuffer() {
  if (typeof FileReader === 'undefined')
    return; // FileReader is not implemented
  var frPrototype = FileReader.prototype;
  // Older versions of Firefox might not have readAsArrayBuffer
  if ('readAsArrayBuffer' in frPrototype)
    return; // readAsArrayBuffer is implemented
  Object.defineProperty(frPrototype, 'readAsArrayBuffer', {
    value: function fileReaderReadAsArrayBuffer(blob) {
      var fileReader = new FileReader();
      var originalReader = this;
      fileReader.onload = function fileReaderOnload(evt) {
        var data = evt.target.result;
        var buffer = new ArrayBuffer(data.length);
        var uint8Array = new Uint8Array(buffer);

        for (var i = 0, ii = data.length; i < ii; i++)
          uint8Array[i] = data.charCodeAt(i);

        Object.defineProperty(originalReader, 'result', {
          value: buffer,
          enumerable: true,
          writable: false,
          configurable: true
        });

        var event = document.createEvent('HTMLEvents');
        event.initEvent('load', false, false);
        originalReader.dispatchEvent(event);
      };
      fileReader.readAsBinaryString(blob);
    }
  });
})();

// No XMLHttpRequest.response ?
(function checkXMLHttpRequestResponseCompatibility() {
  var xhrPrototype = XMLHttpRequest.prototype;
  if (!('overrideMimeType' in xhrPrototype)) {
    // IE10 might have response, but not overrideMimeType
    Object.defineProperty(xhrPrototype, 'overrideMimeType', {
      value: function xmlHttpRequestOverrideMimeType(mimeType) {}
    });
  }
  if ('response' in xhrPrototype ||
      'mozResponseArrayBuffer' in xhrPrototype ||
      'mozResponse' in xhrPrototype ||
      'responseArrayBuffer' in xhrPrototype)
    return;
  // IE9 ?
  if (typeof VBArray !== 'undefined') {
    Object.defineProperty(xhrPrototype, 'response', {
      get: function xmlHttpRequestResponseGet() {
        return new Uint8Array(new VBArray(this.responseBody).toArray());
      }
    });
    return;
  }

  // other browsers
  function responseTypeSetter() {
    // will be only called to set "arraybuffer"
    this.overrideMimeType('text/plain; charset=x-user-defined');
  }
  if (typeof xhrPrototype.overrideMimeType === 'function') {
    Object.defineProperty(xhrPrototype, 'responseType',
                          { set: responseTypeSetter });
  }
  function responseGetter() {
    var text = this.responseText;
    var i, n = text.length;
    var result = new Uint8Array(n);
    for (i = 0; i < n; ++i)
      result[i] = text.charCodeAt(i) & 0xFF;
    return result;
  }
  Object.defineProperty(xhrPrototype, 'response', { get: responseGetter });
})();

// window.btoa (base64 encode function) ?
(function checkWindowBtoaCompatibility() {
  if ('btoa' in window)
    return;

  var digits =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

  window.btoa = function windowBtoa(chars) {
    var buffer = '';
    var i, n;
    for (i = 0, n = chars.length; i < n; i += 3) {
      var b1 = chars.charCodeAt(i) & 0xFF;
      var b2 = chars.charCodeAt(i + 1) & 0xFF;
      var b3 = chars.charCodeAt(i + 2) & 0xFF;
      var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
      var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
      var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
      buffer += (digits.charAt(d1) + digits.charAt(d2) +
                 digits.charAt(d3) + digits.charAt(d4));
    }
    return buffer;
  };
})();

// Function.prototype.bind ?
(function checkFunctionPrototypeBindCompatibility() {
  if (typeof Function.prototype.bind !== 'undefined')
    return;

  Function.prototype.bind = function functionPrototypeBind(obj) {
    var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
    var bound = function functionPrototypeBindBound() {
      var args = Array.prototype.concat.apply(headArgs, arguments);
      return fn.apply(obj, args);
    };
    return bound;
  };
})();

// IE9/10 text/html data URI
(function checkDataURICompatibility() {
  if (!('documentMode' in document) ||
      document.documentMode !== 9 && document.documentMode !== 10)
    return;
  // overriding the src property
  var originalSrcDescriptor = Object.getOwnPropertyDescriptor(
    HTMLIFrameElement.prototype, 'src');
  Object.defineProperty(HTMLIFrameElement.prototype, 'src', {
    get: function htmlIFrameElementPrototypeSrcGet() { return this.$src; },
    set: function htmlIFrameElementPrototypeSrcSet(src) {
      this.$src = src;
      if (src.substr(0, 14) != 'data:text/html') {
        originalSrcDescriptor.set.call(this, src);
        return;
      }
      // for text/html, using blank document and then
      // document's open, write, and close operations
      originalSrcDescriptor.set.call(this, 'about:blank');
      setTimeout((function htmlIFrameElementPrototypeSrcOpenWriteClose() {
        var doc = this.contentDocument;
        doc.open('text/html');
        doc.write(src.substr(src.indexOf(',') + 1));
        doc.close();
      }).bind(this), 0);
    },
    enumerable: true
  });
})();

// HTMLElement dataset property
(function checkDatasetProperty() {
  var div = document.createElement('div');
  if ('dataset' in div)
    return; // dataset property exists

  Object.defineProperty(HTMLElement.prototype, 'dataset', {
    get: function() {
      if (this._dataset)
        return this._dataset;

      var dataset = {};
      for (var j = 0, jj = this.attributes.length; j < jj; j++) {
        var attribute = this.attributes[j];
        if (attribute.name.substring(0, 5) != 'data-')
          continue;
        var key = attribute.name.substring(5).replace(/\-([a-z])/g,
          function(all, ch) { return ch.toUpperCase(); });
        dataset[key] = attribute.value;
      }

      Object.defineProperty(this, '_dataset', {
        value: dataset,
        writable: false,
        enumerable: false
      });
      return dataset;
    },
    enumerable: true
  });
})();

// HTMLElement classList property
(function checkClassListProperty() {
  var div = document.createElement('div');
  if ('classList' in div)
    return; // classList property exists

  function changeList(element, itemName, add, remove) {
    var s = element.className || '';
    var list = s.split(/\s+/g);
    if (list[0] == '') list.shift();
    var index = list.indexOf(itemName);
    if (index < 0 && add)
      list.push(itemName);
    if (index >= 0 && remove)
      list.splice(index, 1);
    element.className = list.join(' ');
  }

  var classListPrototype = {
    add: function(name) {
      changeList(this.element, name, true, false);
    },
    remove: function(name) {
      changeList(this.element, name, false, true);
    },
    toggle: function(name) {
      changeList(this.element, name, true, true);
    }
  };

  Object.defineProperty(HTMLElement.prototype, 'classList', {
    get: function() {
      if (this._classList)
        return this._classList;

      var classList = Object.create(classListPrototype, {
        element: {
          value: this,
          writable: false,
          enumerable: true
        }
      });
      Object.defineProperty(this, '_classList', {
        value: classList,
        writable: false,
        enumerable: false
      });
      return classList;
    },
    enumerable: true
  });
})();

// Check console compatability
(function checkConsoleCompatibility() {
  if (typeof console == 'undefined') {
    console = {
      log: function() {},
      error: function() {}
    };
  } else if (!('bind' in console.log)) {
    // native functions in IE9 might not have bind
    console.log = (function(fn) {
      return function(msg) { return fn(msg); }
    })(console.log);
    console.error = (function(fn) {
      return function(msg) { return fn(msg); }
    })(console.error);
  }
})();

// Check onclick compatibility in Opera
(function checkOnClickCompatibility() {
  // workaround for reported Opera bug DSK-354448:
  // onclick fires on disabled buttons with opaque content
  function ignoreIfTargetDisabled(event) {
    if (isDisabled(event.target)) {
      event.stopPropagation();
    }
  }
  function isDisabled(node) {
    return node.disabled || (node.parentNode && isDisabled(node.parentNode));
  }
  if (navigator.userAgent.indexOf('Opera') != -1) {
    // use browser detection since we cannot feature-check this bug
    document.addEventListener('click', ignoreIfTargetDisabled, true);
  }
})();

// Checks if navigator.language is supported
(function checkNavigatorLanguage() {
  if ('language' in navigator)
    return;
  Object.defineProperty(navigator, 'language', {
    get: function navigatorLanguage() {
      var language = navigator.userLanguage || 'en-US';
      return language.substring(0, 2).toLowerCase() +
        language.substring(2).toUpperCase();
    },
    enumerable: true
  });
})();
<|endoftext|>