text:
/* global React, Blockly */

/* //eslint no-unused-vars: "off" */

import $ from 'jquery';
import Blockly from '../blockly';
import React from 'react';
import ReactDOM from 'react-dom';
import {singleton as studioApp} from '../StudioApp';
import applabMsg from '../locale';
import * as codegen from '../codegen';
import apiBlockly from './apiBlockly';
import AppLabView from './AppLabView';
import codeWorkspaceEjs from '../templates/codeWorkspace.html.ejs';
import visualizationColumnEjs from '../templates/visualizationColumn.html.ejs';
import * as dom from '../dom';
import * as utils from '../utils';
import * as dropletConfig from './dropletConfig';
import AppStorage from './appStorage';
import * as apiTimeoutList from '../timeoutList';
import DesignMode from './designMode';
import applabTurtle from './applabTurtle';
import applabCommands from './commands';
import JSInterpreter from '../JSInterpreter';
import JsInterpreterLogger from '../JsInterpreterLogger';
import JsDebuggerUi from '../JsDebuggerUi';
import * as elementUtils from './designElements/elementUtils';
import VisualizationOverlay from './VisualizationOverlay';
import ShareWarningsDialog from '../templates/ShareWarningsDialog';
import logToCloud from '../logToCloud';
import DialogButtons from '../templates/DialogButtons';
import executionLog from '../executionLog';
import annotationList from '../acemode/annotationList';
import createStore from '../redux';
import {Provider} from 'react-redux';
import {rootReducer} from './reducers';
import * as actions from './actions';
var setInitialLevelProps = actions.setInitialLevelProps;
var changeInterfaceMode = actions.changeInterfaceMode;

import applabConstants from './constants';
import * as appConstants from '../constants';
import consoleApi from '../consoleApi';

var ResultType = studioApp.ResultType;
var TestResults = studioApp.TestResults;
var ApplabInterfaceMode = applabConstants.ApplabInterfaceMode;
var KeyCodes = appConstants.KeyCodes;

/**
 * Create a namespace for the application.
 */
const Applab = {};
export default Applab;

/**
 * @type {JsInterpreterLogger} observes the interpreter and logs to console
 */
var jsInterpreterLogger = null;

/**
 * @type {JsDebuggerUi} Controller for JS debug buttons and console area
 */
var debuggerUi = null;

/**
 * Redux Store holding application state, transformable by actions.
 * @type {Store}
 * @see http://redux.js.org/docs/basics/Store.html
 */
Applab.reduxStore = createStore(rootReducer);

/**
 * Temporary: Some code depends on global access to logging, but only Applab
 * knows about the debugger UI where logging should occur.
 * Eventually, I'd like to replace this with window events that the debugger
 * UI listens to, so that the Applab global is not involved.
 * @param {*} object
 */
Applab.log = function (object) {
  if (jsInterpreterLogger) {
    jsInterpreterLogger.log(object);
  }

  if (debuggerUi) {
    debuggerUi.log(object);
  }
};
consoleApi.setLogMethod(Applab.log);

import errorHandler from '../errorHandler';
errorHandler.setLogMethod(Applab.log);
var outputError = errorHandler.outputError;
var ErrorLevel = errorHandler.ErrorLevel;

var level;
var skin;
var copyrightStrings;

// TODO: Make configurable.
studioApp.setCheckForEmptyBlocks(true);

var MAX_INTERPRETER_STEPS_PER_TICK = 10000;

// For proxying non-https assets
// var MEDIA_PROXY = '//' + window.location.host + '/media?u=';

// Default Scalings
Applab.scale = {
  'snapRadius': 1,
  'stepSpeed': 0
};

var twitterOptions = {
  text: applabMsg.shareApplabTwitter(),
  hashtag: 'ApplabCode'
};

// The unscaled dimensions of the visualization area
var vizAppWidth = 400;
var VIZ_APP_HEIGHT = 400;

var hasSeenRateLimitAlert = false;

var designMode = DesignMode(Applab);

function loadLevel() {
  Applab.timeoutFailureTick = level.timeoutFailureTick || Infinity;
  Applab.minWorkspaceHeight = level.minWorkspaceHeight;
  Applab.softButtons_ = level.softButtons || {};

  // Historically, appWidth and appHeight were customizable on a per level basis.
  // This led to lots of hackery in the code to properly scale the visualization
  // area. Width/height are now constant, but much of the hackery still remains
  // since I don't understand it well enough.
  Applab.appWidth = applabConstants.APP_WIDTH;
  Applab.appHeight = applabConstants.APP_HEIGHT;
  Applab.makerlabEnabled = level.makerlabEnabled;

  // In share mode we need to reserve some number of pixels for our in-app
  // footer. We do that by making the play space slightly smaller elsewhere.
  // Applab.appHeight represents the height of the entire app (footer + other)
  // Applab.footerlessAppHeight represents the height of only the "other"
  Applab.footerlessAppHeight = applabConstants.APP_HEIGHT - applabConstants.FOOTER_HEIGHT;

  // Override scalars.
  for (var key in level.scale) {
    Applab.scale[key] = level.scale[key];
  }

  /*
  if (Applab.makerlabEnabled) {
    Applab.makerlabController = new BoardController();
  }
  */
}

//
// Adjust a media height rule (if needed). This is called by adjustAppSizeStyles
// for all media rules. We look for a specific set of rules that should be in
// the stylesheet and swap out the defaultHeightRules with the newHeightRules
//

function adjustMediaHeightRule(mediaList, defaultHeightRules, newHeightRules) {
  // The media rules we are looking for always have two components. The first
  // component is for screen width, which we ignore. The second is for screen
  // height, which we want to modify:
  if (mediaList.length === 2) {
    var lastHeightRuleIndex = defaultHeightRules.length - 1;
    for (var i = 0; i <= lastHeightRuleIndex; i++) {
      if (mediaList.item(1).indexOf('(min-height: ' +
          (defaultHeightRules[i] + 1) + 'px)') !== -1) {
        if (i === 0) {
          // Matched the first rule (no max height)
          mediaList.mediaText = mediaList.item(0) +
              ', screen and (min-height: ' + (newHeightRules[i] + 1) + 'px)';
        } else {
          // Matched one of the middle rules with a min and a max height
          mediaList.mediaText = mediaList.item(0) +
              ', screen and (min-height: ' + (newHeightRules[i] + 1) + 'px)' +
              ' and (max-height: ' + newHeightRules[i - 1] + 'px)';
        }
        break;
      } else if (mediaList.item(1) === 'screen and (max-height: ' +
                 defaultHeightRules[lastHeightRuleIndex] + 'px)') {
        // Matched the last rule (no min height)
        mediaList.mediaText = mediaList.item(0) +
            ', screen and (max-height: ' +
            newHeightRules[lastHeightRuleIndex] + 'px)';
        break;
      }
    }
  }
}

//
// The visualization area adjusts its size using a series of CSS rules that are
// tuned to make adjustments assuming a 400x400 visualization. Since applab
// allows its visualization size to be set on a per-level basis, the function
// below modifies the CSS rules to account for the per-level coordinates
//
// It also adjusts the height rules based on the adjusted visualization size
// and the offset where the app has been embedded in the page
//
// The visualization column will remain at 400 pixels wide in the max-width
// case and scale downward from there. The visualization height will be set
// to preserve the proper aspect ratio with respect to the current width.
//
// The visualization coordinate space will be Applab.appWidth by Applab.appHeight.
// The scale values are then adjusted such that the max-width case may result
// in a scaled-up version of the visualization area and the min-width case will
// typically result in a scaled-down version of the visualization area.
//
// @returns {Array.<number>} Array of scale factors which will be used
//     on the applab app area at the following screen widths, respectively:
//     1151px+; 1101-1150px; 1051-1100px; 1001-1050px; 0-1000px.
//

function adjustAppSizeStyles(container) {
  var vizScale = 1;
  // We assume these are listed in this order:
  var defaultScaleFactors = [1.0, 0.875, 0.75, 0.625, 0.5];
  var scaleFactors = defaultScaleFactors.slice(0);
  if (vizAppWidth !== Applab.appWidth) {
    vizScale = vizAppWidth / Applab.appWidth;
    for (var ind = 0; ind < scaleFactors.length; ind++) {
      scaleFactors[ind] *= vizScale;
    }
  }
  var targetVizAppHeight = Applab.footerlessAppHeight * vizScale;

  // Compute new height rules:
  // (1) defaults are scaleFactors * VIZ_APP_HEIGHT + 200 (belowViz estimate)
  // (2) we adjust the height rules to take into account where the codeApp
  // div is anchored on the page. If this changes after this function is called,
  // the media rules for height are no longer valid.
  // (3) we assume that there is nothing below codeApp on the page that also
  // needs to be included in the height rules
  // (4) there is no 5th height rule in the array because the 5th rule in the
  // stylesheet has no minimum specified. It just uses the max-height from the
  // 4th item in the array.
  var defaultHeightRules = [600, 550, 500, 450];
  var newHeightRules = defaultHeightRules.slice(0);
  for (var z = 0; z < newHeightRules.length; z++) {
    newHeightRules[z] += container.offsetTop +
        (targetVizAppHeight - VIZ_APP_HEIGHT) * defaultScaleFactors[z];
  }

  if (!utils.browserSupportsCssMedia()) {
    return;
  }

  var ss = document.styleSheets;
  // Match applab.css or (for production) applab-{hex-fingerprint}.css
  var applabStyleSheetRegex = /\/applab-?[0-9a-f]*\.css$/i;
  for (var i = 0; i < ss.length; i++) {
    if (ss[i].href && (applabStyleSheetRegex.test(ss[i].href))) {
      // We found our applab specific stylesheet:
      var rules = ss[i].cssRules || ss[i].rules;
      var changedRules = 0;
      var curScaleIndex = 0;
      // Change the width/height plus a set of rules for each scale factor:
      var totalRules = 1 + scaleFactors.length;
      for (var j = 0; j < rules.length && changedRules < totalRules; j++) {
        var childRules = rules[j].cssRules || rules[j].rules;
        if (rules[j].selectorText === 'div#visualization') {
          // set the 'normal' width/height for the visualization itself
          rules[j].style.cssText = 'height: ' + targetVizAppHeight +
                                   'px; width: ' + vizAppWidth + 'px;';
          changedRules++;
        } else if (rules[j].media && childRules) {
          adjustMediaHeightRule(rules[j].media, defaultHeightRules, newHeightRules);

          // NOTE: selectorText can appear in two different forms when styles and IDs
          // are both present. IE places the styles before the IDs, so we match both forms:
          var changedChildRules = 0;
          var maxChangedRules = 8;
          var scale = scaleFactors[curScaleIndex];
          for (var k = 0; k < childRules.length && changedChildRules < maxChangedRules; k++) {
            if (childRules[k].selectorText === 'div#visualization.responsive' ||
                childRules[k].selectorText === 'div.responsive#visualization') {
              // For this scale factor...
              // set the max-height and max-width for the visualization
              childRules[k].style.cssText = 'max-height: ' +
                  Applab.footerlessAppHeight * scale + 'px; max-width: ' +
                  Applab.appWidth * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'div#visualizationColumn.responsive' ||
                       childRules[k].selectorText === 'div.responsive#visualizationColumn') {
              // set the max-width for the parent visualizationColumn
              childRules[k].style.cssText = 'max-width: ' +
                  Applab.appWidth * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'div#visualizationColumn.responsive.with_padding' ||
                       childRules[k].selectorText === 'div.with_padding.responsive#visualizationColumn') {
              // set the max-width for the parent visualizationColumn (with_padding)
              childRules[k].style.cssText = 'max-width: ' +
                  (Applab.appWidth * scale + 2) + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'div.workspace-right') {
              // set the left for the codeWorkspace
              childRules[k].style.cssText = 'left: ' +
                  Applab.appWidth * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'div#visualizationResizeBar') {
              // set the left for the visualizationResizeBar
              childRules[k].style.cssText = 'left: ' +
                  Applab.appWidth * scale + 'px; line-height: ' +
              Applab.footerlessAppHeight * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'html[dir=\'rtl\'] div.workspace-right') {
              // set the right for the codeWorkspace (RTL mode)
              childRules[k].style.cssText = 'right: ' +
                  Applab.appWidth * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'html[dir=\'rtl\'] div#visualizationResizeBar') {
              // set the right for the visualizationResizeBar (RTL mode)
              childRules[k].style.cssText = 'right: ' +
                  Applab.appWidth * scale + 'px;';
              changedChildRules++;
            } else if (childRules[k].selectorText === 'div#visualization.responsive > *' ||
                       childRules[k].selectorText === 'div.responsive#visualization > *') {
              // and set the scale factor for all children of the visualization
              // (importantly, the divApplab and designModeViz elements)
              childRules[k].style.cssText = '-webkit-transform: scale(' + scale +
                  ');-ms-transform: scale(' + scale +
                  ');transform: scale(' + scale + ');';
              changedChildRules++;
            }
          }
          if (changedChildRules) {
            curScaleIndex++;
            changedRules++;
          }
        }
      }
      // After processing the applab.css, stop looking for stylesheets:
      break;
    }
  }
}

var drawDiv = function () {
  ['divApplab', 'visualizationOverlay', 'designModeViz'].forEach(function (divId) {
    var div = document.getElementById(divId);
    div.style.width = Applab.appWidth + 'px';
    div.style.height = Applab.footerlessAppHeight + 'px';
  });

  if (shouldRenderFooter()) {
    renderFooterInSharedGame();
  }
};

function shouldRenderFooter() {
  return studioApp.share;
}

function renderFooterInSharedGame() {
  var divApplab = document.getElementById('divApplab');
  var footerDiv = document.createElement('div');
  footerDiv.setAttribute('id', 'footerDiv');
  divApplab.parentNode.insertBefore(footerDiv, divApplab.nextSibling);

  var menuItems = [
    {
      text: applabMsg.reportAbuse(),
      link: '/report_abuse',
      newWindow: true
    },
    {
      text: applabMsg.makeMyOwnApp(),
      link: '/projects/applab/new',
      hideOnMobile: true
    },
    {
      text: applabMsg.openWorkspace(),
      link: window.location.href + '/view'
    },
    {
      text: applabMsg.copyright(),
      link: '#',
      copyright: true
    },
    {
      text: applabMsg.privacyPolicy(),
      link: 'https://code.org/privacy',
      newWindow: true
    }
  ];
  if (dom.isMobile()) {
    menuItems = menuItems.filter(function (item) {
      return !item.hideOnMobile;
    });
  }

  ReactDOM.render(React.createElement(window.dashboard.SmallFooter, {
    i18nDropdown: '',
    copyrightInBase: false,
    copyrightStrings: copyrightStrings,
    baseMoreMenuString: applabMsg.builtOnCodeStudio(),
    rowHeight: applabConstants.FOOTER_HEIGHT,
    style: {
      fontSize: 18
    },
    baseStyle: {
      width: $('#divApplab').width(),
      paddingLeft: 0
    },
    className: 'dark',
    menuItems: menuItems,
    phoneFooter: true
  }), footerDiv);
}

/**
 * @param {string} code The code to search for Data Storage APIs
 * @return {boolean} True if the code uses any data storage APIs
 */
Applab.hasDataStoreAPIs = function (code) {
  return /createRecord/.test(code) || /updateRecord/.test(code) ||
    /setKeyValue/.test(code);
};

/**
 * Set the current interpreter step speed as a value from 0 (stopped)
 * to 1 (full speed).
 * @param {!number} speed - range 0..1
 */
Applab.setStepSpeed = function (speed) {
  if (debuggerUi) {
    debuggerUi.setStepSpeed(speed);
  }
  Applab.scale.stepSpeed = JsDebuggerUi.stepDelayFromStepSpeed(speed);
};

function getCurrentTickLength() {
  var debugStepDelay;
  if (debuggerUi) {
    // debugStepDelay will be undefined if no speed slider is present
    debugStepDelay = debuggerUi.getStepDelay();
  }
  return debugStepDelay !== undefined ? debugStepDelay : Applab.scale.stepSpeed;
}

function queueOnTick() {
  window.setTimeout(Applab.onTick, getCurrentTickLength());
}

function handleExecutionError(err, lineNumber) {
  outputError(String(err), ErrorLevel.ERROR, lineNumber);
  Applab.executionError = { err: err, lineNumber: lineNumber };

  // complete puzzle, which will prevent further execution
  Applab.onPuzzleComplete();
}

Applab.getCode = function () {
  return studioApp.getCode();
};

Applab.getHtml = function () {
  // This method is called on autosave. If we're about to autosave, let's update
  // levelHtml to include our current state.
  if ($('#designModeViz').is(':visible')) {
    designMode.serializeToLevelHtml();
  }
  return Applab.levelHtml;
};

/**
 * Sets Applab.levelHtml as well as #designModeViz contents.
 * designModeViz is the source of truth for the app's HTML.
 * levelHtml can be lazily updated from designModeViz via serializeToLevelHtml.
 * @param html
 */
Applab.setLevelHtml = function (html) {
  if (html === '') {
    Applab.levelHtml = '';
  } else {
    Applab.levelHtml = designMode.addScreenIfNecessary(html);
  }
  var designModeViz = document.getElementById('designModeViz');
  designMode.parseFromLevelHtml(designModeViz, true, applabConstants.DESIGN_ELEMENT_ID_PREFIX);

  // Make sure at least one screen exists, and that the first
  // screen is visible.
  designMode.loadDefaultScreen();
  designMode.serializeToLevelHtml();
};

Applab.onTick = function () {
  if (!Applab.running) {
    return;
  }

  Applab.tickCount++;
  queueOnTick();

  if (Applab.JSInterpreter) {
    Applab.JSInterpreter.executeInterpreter(Applab.tickCount === 1);
  } else {
    Applab.executeNativeJS();
  }

  if (checkFinished()) {
    Applab.onPuzzleFinish();
  }
};

Applab.executeNativeJS = function () {
  if (Applab.tickCount === 1) {
    try { Applab.whenRunFunc(studioApp, apiBlockly, Applab.Globals); } catch (e) { }
  }
};

/**
 * Initialize Blockly and Applab for read-only (blocks feedback).
 * Called on iframe load for read-only.
 */
Applab.initReadonly = function (config) {
  // Do some minimal level loading so that
  // we can ensure that the blocks are appropriately modified for this level
  skin = config.skin;
  level = config.level;
  copyrightStrings = config.copyrightStrings;
  config.appMsg = applabMsg;
  loadLevel();

  // Applab.initMinimal();

  studioApp.initReadonly(config);
};

function hasSeenDataAlert(channelId) {
  var dataAlerts = window.localStorage.getItem('dataAlerts');
  if (!dataAlerts) {
    return false;
  }
  var channelIds = JSON.parse(dataAlerts);
  return channelIds.indexOf(channelId) !== -1;
}

function markSeenDataAlert(channelId) {
  var dataAlerts = window.localStorage.getItem('dataAlerts');
  if (!dataAlerts) {
    dataAlerts = '[]';
  }
  var channelIds = JSON.parse(dataAlerts);
  channelIds.push(channelId);
  window.localStorage.setItem('dataAlerts', JSON.stringify(channelIds));
}

function onCloseShareWarnings(showStoreDataAlert) {
  // we closed the dialog without hitting too_young
  // Only want to ask about age once across apps
  if (!Applab.user.isSignedIn) {
    utils.trySetLocalStorage('is13Plus', 'true');
  }
  // Only want to ask about storing data once per app.
  if (showStoreDataAlert) {
    markSeenDataAlert(Applab.channelId);
  }
  window.setTimeout(Applab.runButtonClick.bind(studioApp), 0);
}

function handleShareWarningsTooYoung() {
  utils.trySetLocalStorage('is13Plus', 'false');
  window.location.href = '/too_young';
}

/**
 * Starts the app after (potentially) Showing a modal warning about data sharing
 * (if appropriate) and determining user is old enough
 */
Applab.startSharedAppAfterWarnings = function () {
  // dashboard will redirect young signed in users
  var is13Plus = Applab.user.isSignedIn || window.localStorage.getItem('is13Plus') === 'true';
  var _handleClose = onCloseShareWarnings.bind(null, showStoreDataAlert);
  var showStoreDataAlert = Applab.hasDataStoreAPIs(Applab.getCode()) &&
    !hasSeenDataAlert(Applab.channelId);

  var modal = document.createElement('div');
  document.body.appendChild(modal);

  return ReactDOM.render(<ShareWarningsDialog
    showStoreDataAlert={showStoreDataAlert}
    is13Plus={is13Plus}
    handleClose={_handleClose}
    handleTooYoung={handleShareWarningsTooYoung} />, modal);
};

/**
 * Look at localStorage to see if we want to show instructions in the top pane.
 */
function showInstructionsInTopPane() {
  // enable instructions in top pane based on query param
  if (/topInstructions=true/.test(window.location.search)) {
    window.localStorage.setItem('showInstructionsInTopPane', true);
  }
  // disable instructions in top pane based on query param
  if (/topInstructions=false/.test(window.location.search)) {
    window.localStorage.removeItem('showInstructionsInTopPane');
  }
  return !!window.localStorage.getItem('showInstructionsInTopPane');
}

import controls from './controls.html.ejs';
import visualization from './visualization.html.ejs';

/**
 * Initialize Blockly and the Applab app.  Called on page load.
 */
Applab.init = function (config) {
  console.debug('Initializing App Lab with config:', config);
  // Gross, but necessary for tests, until we can instantiate AppLab and make
  // this a member variable: Reset this thing until we're ready to create it!
  jsInterpreterLogger = null;
  debuggerUi = null;

  // replace studioApp methods with our own
  studioApp.reset = this.reset.bind(this);
  studioApp.runButtonClick = this.runButtonClick.bind(this);

  Applab.channelId = config.channel;
  // inlcude channel id in any new relic actions we generate
  logToCloud.setCustomAttribute('channelId', Applab.channelId);

  config.usesAssets = true;

  Applab.clearEventHandlersKillTickLoop();
  skin = config.skin;
  skin.smallStaticAvatar = null;
  skin.staticAvatar = null;
  skin.winAvatar = null;
  skin.failureAvatar = null;
  level = config.level;
  copyrightStrings = config.copyrightStrings;
  Applab.user = {
    applabUserId: config.applabUserId,
    isAdmin: (config.isAdmin === true),
    isSignedIn: config.isSignedIn
  };
  Applab.isReadOnlyView = config.readonlyWorkspace;

  loadLevel();

  if (studioApp.hideSource) {
    // always run at max speed if source is hidden
    config.level.sliderSpeed = 1.0;
  }

  // If we are in mobile sharing mode, allow the viewport to handle scaling
  // and override our default width target in vizAppWidth with the actual width
  if (dom.isMobile() && config.hideSource) {
    vizAppWidth = Applab.appWidth;
  }

  adjustAppSizeStyles(document.getElementById(config.containerId));

  var showSlider = !config.hideSource && config.level.editCode;
  var showDebugButtons = (!config.hideSource &&
                          config.level.editCode &&
                          !config.level.debuggerDisabled);
  var breakpointsEnabled = !config.level.debuggerDisabled;
  var showDebugConsole = !config.hideSource && config.level.editCode;
  var firstControlsRow = controls({
    assetUrl: studioApp.assetUrl,
    showSlider: showSlider,
    finishButton: (!level.isProjectLevel && !level.submittable),
    submitButton: level.submittable && !level.submitted,
    unsubmitButton: level.submittable && level.submitted
  });
  var extraControlRows = '';

  // Construct a logging observer for interpreter events
  if (!config.hideSource) {
    jsInterpreterLogger = new JsInterpreterLogger(window.console);
  }

  if (showDebugButtons || showDebugConsole) {
    debuggerUi = new JsDebuggerUi(Applab.runButtonClick);
    extraControlRows = debuggerUi.getMarkup(studioApp.assetUrl, {
      showButtons: showDebugButtons,
      showConsole: showDebugConsole
    });
  }

  config.loadAudio = function () {
    studioApp.loadAudio(skin.failureSound, 'failure');
  };

  config.afterInject = function () {
    if (studioApp.isUsingBlockly()) {
      /**
       * The richness of block colours, regardless of the hue.
       * MOOC blocks should be brighter (target audience is younger).
       * Must be in the range of 0 (inclusive) to 1 (exclusive).
       * Blockly's default is 0.45.
       */
      Blockly.HSV_SATURATION = 0.6;

      Blockly.SNAP_RADIUS *= Applab.scale.snapRadius;
    }
    drawDiv();

    // Ignore the user's levelHtml for levels without design mode. levelHtml
    // should never be present on such levels, however some levels do
    // have levelHtml stored due to a previous bug. HTML set by levelbuilder
    // is stored in startHtml, not levelHtml.
    if (Applab.reduxStore.getState().level.isDesignModeHidden) {
      config.level.levelHtml = '';
    }

    // Set designModeViz contents after it is created in configureDom()
    // and sized in drawDiv().
    Applab.setLevelHtml(level.levelHtml || level.startHtml || '');

    if (config.level.projectTemplateLevelName) {
      studioApp.displayWorkspaceAlert('warning', <div>{applabMsg.projectWarning()}</div>);
    }

    studioApp.alertIfAbusiveProject('#codeWorkspace');

    // IE9 doesnt support the way we handle responsiveness. Instead, explicitly
    // resize our visualization (user can still resize with grippy)
    if (!utils.browserSupportsCssMedia()) {
      studioApp.resizeVisualization(300);
    }

    if (studioApp.share) {
      Applab.startSharedAppAfterWarnings();
    }
  };

  config.afterEditorReady = function () {
    if (breakpointsEnabled) {
      studioApp.enableBreakpoints();
    }
  };

  config.afterClearPuzzle = function () {
    designMode.resetIds();
    Applab.setLevelHtml(config.level.startHtml || '');
    AppStorage.populateTable(level.dataTables, true); // overwrite = true
    AppStorage.populateKeyValue(level.dataProperties, true); // overwrite = true
    studioApp.resetButtonClick();
  };

  // arrangeStartBlocks(config);

  config.twitter = twitterOptions;

  // hide makeYourOwn on the share page
  config.makeYourOwn = false;

  config.varsInGlobals = true;

  config.dropletConfig = dropletConfig;

  config.pinWorkspaceToBottom = true;

  config.vizAspectRatio = Applab.appWidth / Applab.footerlessAppHeight;
  config.nativeVizWidth = Applab.appWidth;

  config.appMsg = applabMsg;

  config.mobileNoPaddingShareWidth = applabConstants.APP_WIDTH;

  config.enableShowLinesCount = false;

  // In Applab, we want our embedded levels to look the same as regular levels,
  // just without the editor
  config.centerEmbedded = false;
  config.wireframeShare = true;

  // Provide a way for us to have top pane instructions disabled by default, but
  // able to turn them on.
  config.showInstructionsInTopPane = showInstructionsInTopPane();

  // Applab.initMinimal();

  AppStorage.populateTable(level.dataTables, false); // overwrite = false
  AppStorage.populateKeyValue(level.dataProperties, false); // overwrite = false

  var generateCodeWorkspaceHtmlFromEjs = function () {
    return codeWorkspaceEjs({
      assetUrl: studioApp.assetUrl,
      data: {
        localeDirection: studioApp.localeDirection(),
        extraControlRows: extraControlRows,
        blockUsed: undefined,
        idealBlockNumber: undefined,
        editCode: level.editCode,
        blockCounterClass: 'block-counter-default',
        pinWorkspaceToBottom: true,
        readonlyWorkspace: Applab.reduxStore.getState().level.isReadOnlyWorkspace
      }
    });
  };

  var generateVisualizationColumnHtmlFromEjs = function () {
    return visualizationColumnEjs({
      assetUrl: studioApp.assetUrl,
      data: {
        visualization: visualization({
          appWidth: Applab.appWidth,
          appHeight: Applab.footerlessAppHeight
        }),
        controls: firstControlsRow
      }
    });
  };

  var onMount = function () {
    studioApp.init(config);

    var viz = document.getElementById('visualization');
    var vizCol = document.getElementById('visualizationColumn');

    if (!config.noPadding) {
      viz.className += ' with_padding';
      vizCol.className += ' with_padding';
    }

    if (Applab.reduxStore.getState().level.isEmbedView || config.hideSource) {
      // no responsive styles active in embed or hideSource mode, so set sizes:
      viz.style.width = Applab.appWidth + 'px';
      viz.style.height = (shouldRenderFooter() ? Applab.appHeight : Applab.footerlessAppHeight) + 'px';
      // Use offsetWidth of viz so we can include any possible border width:
      vizCol.style.maxWidth = viz.offsetWidth + 'px';
    }

    if (debuggerUi) {
      debuggerUi.initializeAfterDomCreated({
        defaultStepSpeed: config.level.sliderSpeed
      });
    }

    window.addEventListener('resize', Applab.renderVisualizationOverlay);

    var finishButton = document.getElementById('finishButton');
    if (finishButton) {
      dom.addClickTouchEvent(finishButton, Applab.onPuzzleFinish);
    }

    var submitButton = document.getElementById('submitButton');
    if (submitButton) {
      dom.addClickTouchEvent(submitButton, Applab.onPuzzleSubmit);
    }

    var unsubmitButton = document.getElementById('unsubmitButton');
    if (unsubmitButton) {
      dom.addClickTouchEvent(unsubmitButton, Applab.onPuzzleUnsubmit);
    }

    if (level.editCode) {
      // Prevent the backspace key from navigating back. Make sure it's still
      // allowed on other elements.
      // Based on http://stackoverflow.com/a/2768256/2506748
      $(document).on('keydown', function (event) {
        var doPrevent = false;
        if (event.keyCode !== KeyCodes.BACKSPACE) {
          return;
        }
        var d = event.srcElement || event.target;
        if ((d.tagName.toUpperCase() === 'INPUT' && (
            d.type.toUpperCase() === 'TEXT' ||
            d.type.toUpperCase() === 'PASSWORD' ||
            d.type.toUpperCase() === 'FILE' ||
            d.type.toUpperCase() === 'EMAIL' ||
            d.type.toUpperCase() === 'SEARCH' ||
            d.type.toUpperCase() === 'NUMBER' ||
            d.type.toUpperCase() === 'DATE')) ||
            d.tagName.toUpperCase() === 'TEXTAREA') {
          doPrevent = d.readOnly || d.disabled;
        } else {
          doPrevent = !d.isContentEditable;
        }

        if (doPrevent) {
          event.preventDefault();
        }
      });

      setupReduxSubscribers(Applab.reduxStore);

      designMode.addKeyboardHandlers();

      designMode.renderDesignWorkspace();

      designMode.loadDefaultScreen();

      designMode.toggleDesignMode(Applab.startInDesignMode());

      designMode.configureDragAndDrop();

      var designModeViz = document.getElementById('designModeViz');
      designModeViz.addEventListener('click', designMode.onDesignModeVizClick);
    }
  };

  // Push initial level properties into the Redux store
  Applab.reduxStore.dispatch(setInitialLevelProps({
    assetUrl: studioApp.assetUrl,
    isDesignModeHidden: !!config.level.hideDesignMode,
    isEmbedView: !!config.embed,
    isReadOnlyWorkspace: !!config.readonlyWorkspace,
    isShareView: !!config.share,
    isViewDataButtonHidden: !!config.level.hideViewDataButton,
    instructionsMarkdown: config.level.markdownInstructions,
    instructionsInTopPane: config.showInstructionsInTopPane,
    puzzleNumber: config.level.puzzle_number,
    stageTotal: config.level.stage_total
  }));

  Applab.reduxStore.dispatch(changeInterfaceMode(
    Applab.startInDesignMode() ? ApplabInterfaceMode.DESIGN : ApplabInterfaceMode.CODE));

  Applab.reactInitialProps_ = {
    generateCodeWorkspaceHtml: generateCodeWorkspaceHtmlFromEjs,
    generateVisualizationColumnHtml: generateVisualizationColumnHtmlFromEjs,
    onMount: onMount
  };

  Applab.reactMountPoint_ = document.getElementById(config.containerId);

  Applab.render();
};

/**
 * Subscribe to state changes on the store.
 * @param {!Store} store
 */
function setupReduxSubscribers(store) {
  designMode.setupReduxSubscribers(store);

  var state = {};
  store.subscribe(function () {
    var lastState = state;
    state = store.getState();

    if (state.interfaceMode !== lastState.interfaceMode) {
      onInterfaceModeChange(state.interfaceMode);
    }
  });
}

/**
 * Cache of props, established during init, to use when re-rendering top-level
 * view.  Eventually, it would be best to replace these with a Redux store.
 * @type {Object}
 */
Applab.reactInitialProps_ = {};

/**
 * Element on which to mount the top-level React view.
 * @type {Element}
 * @private
 */
Applab.reactMountPoint_ = null;

/**
 * Trigger a top-level React render
 */
Applab.render = function () {
  var nextProps = $.extend({}, Applab.reactInitialProps_, {
    isEditingProject: window.dashboard && window.dashboard.project && window.dashboard.project.isEditing(),
    screenIds: designMode.getAllScreenIds(),
    onViewDataButton: Applab.onViewData,
    onScreenCreate: designMode.createScreen
  });
  ReactDOM.render(
    <Provider store={Applab.reduxStore}>
      <AppLabView {...nextProps} />
    </Provider>,
    Applab.reactMountPoint_);
};

/**
 * @param {string} newCode Code to append to the end of the editor
 */
Applab.appendToEditor = function (newCode) {
  var code = studioApp.editor.addEmptyLine(studioApp.editor.getValue()) + newCode;
  studioApp.editor.setValue(code);
};

Applab.scrollToEnd = function () {
  studioApp.editor.scrollCursorToEndOfDocument();
};

/**
 * Clear the event handlers and stop the onTick timer.
 */
Applab.clearEventHandlersKillTickLoop = function () {
  Applab.whenRunFunc = null;
  Applab.running = false;
  $('#headers').removeClass('dimmed');
  $('#codeWorkspace').removeClass('dimmed');
  Applab.tickCount = 0;
};

/**
 * @returns {boolean}
 */
Applab.isRunning = function () {
  // We are _always_ running in share mode.
  // TODO: (bbuchanan) Needs a better condition. Tracked in bug:
  //      https://www.pivotaltracker.com/story/show/105022102
  return !!($('#resetButton').is(':visible') || studioApp.share);
};

/**
 * Toggle whether divApplab or designModeViz is visible.
 * @param isVisible whether divApplab should be visible.
 */
Applab.toggleDivApplab = function (isVisible) {
  if (isVisible) {
    $('#divApplab').show();
    $('#designModeViz').hide();
  } else {
    $('#divApplab').hide();
    $('#designModeViz').show();
  }
};

/**
 * Reset the app to the start position and kill any pending animation tasks.
 * @param {boolean} first True if an opening animation is to be played.
 */
Applab.reset = function (first) {
  var i;
  Applab.clearEventHandlersKillTickLoop();

  // Soft buttons
  var softButtonCount = 0;
  for (i = 0; i < Applab.softButtons_.length; i++) {
    document.getElementById(Applab.softButtons_[i]).style.display = 'inline';
    softButtonCount++;
  }
  if (softButtonCount) {
    var softButtonsCell = document.getElementById('soft-buttons');
    softButtonsCell.className = 'soft-buttons-' + softButtonCount;
  }

  // Reset configurable variables
  Applab.message = null;
  delete Applab.activeCanvas;
  Applab.turtle = {};
  Applab.turtle.heading = 0;
  Applab.turtle.x = Applab.appWidth / 2;
  Applab.turtle.y = Applab.appHeight / 2;
  apiTimeoutList.clearTimeouts();
  apiTimeoutList.clearIntervals();

  var divApplab = document.getElementById('divApplab');
  while (divApplab.firstChild) {
    divApplab.removeChild(divApplab.firstChild);
  }

  // Clone and replace divApplab (this removes all attached event listeners):
  var newDivApplab = divApplab.cloneNode(true);
  divApplab.parentNode.replaceChild(newDivApplab, divApplab);

  $('#divApplab').toggleClass('running', Applab.isRunning());
  $('#divApplab').toggleClass('notRunning', !Applab.isRunning());

  var isDesigning = Applab.isInDesignMode() && !Applab.isRunning();
  Applab.toggleDivApplab(!isDesigning);
  designMode.parseFromLevelHtml(newDivApplab, false);
  if (Applab.isInDesignMode()) {
    designMode.resetElementTray(isDesigning);
    designMode.resetPropertyTab();
  }

  if (Applab.makerlabController) {
    Applab.makerlabController.reset();
  }

  if (level.showTurtleBeforeRun) {
    applabTurtle.turtleSetVisibility(true);
  }

  Applab.renderVisualizationOverlay();

  // Reset goal successState:
  if (level.goal) {
    level.goal.successState = {};
  }

  if (debuggerUi) {
    debuggerUi.detach();
  }

  if (jsInterpreterLogger) {
    jsInterpreterLogger.detach();
  }

  AppStorage.resetRecordListener();

  // Reset the Globals object used to contain program variables:
  Applab.Globals = {};
  Applab.executionError = null;
  if (Applab.JSInterpreter) {
    Applab.JSInterpreter.deinitialize();
    Applab.JSInterpreter = null;
  }
};

/**
 * Manually re-render visualization SVG overlay.
 * Should call whenever its state/props would change.
 */
Applab.renderVisualizationOverlay = function () {
  var divApplab = document.getElementById('divApplab');
  var designModeViz = document.getElementById('designModeViz');
  var visualizationOverlay = document.getElementById('visualizationOverlay');
  if (!divApplab || !designModeViz || !visualizationOverlay) {
    return;
  }

  // Enable crosshair cursor for divApplab and designModeViz
  $(divApplab).toggleClass('withCrosshair', Applab.isCrosshairAllowed());
  $(designModeViz).toggleClass('withCrosshair', true);

  if (!Applab.visualizationOverlay_) {
    Applab.visualizationOverlay_ = new VisualizationOverlay();
  }

  // Calculate current visualization scale to pass to the overlay component.
  var unscaledWidth = parseInt(visualizationOverlay.getAttribute('width'));
  var scaledWidth = visualizationOverlay.getBoundingClientRect().width;

  Applab.visualizationOverlay_.render(visualizationOverlay, {
    isCrosshairAllowed: Applab.isCrosshairAllowed(),
    scale: scaledWidth / unscaledWidth,
    isInDesignMode: Applab.isInDesignMode()
  });
};

/**
 * Save the app state and trigger any callouts, then call the callback.
 * @param callback {Function}
 */
studioApp.runButtonClickWrapper = function (callback) {
  $(window).trigger('run_button_pressed');
  Applab.serializeAndSave(callback);
};

/**
 * We also want to serialize in save in some other cases (i.e. entering code
 * mode from design mode).
 */
Applab.serializeAndSave = function (callback) {
  designMode.serializeToLevelHtml();
  $(window).trigger('appModeChanged');
  if (callback) {
    callback();
  }
};

/**
 * Click the run button.  Start the program.
 */
// XXX This is the only method used by the templates!
Applab.runButtonClick = function () {
  var runButton = document.getElementById('runButton');
  var resetButton = document.getElementById('resetButton');
  // Ensure that Reset button is at least as wide as Run button.
  if (!resetButton.style.minWidth) {
    resetButton.style.minWidth = runButton.offsetWidth + 'px';
  }
  studioApp.toggleRunReset('reset');
  if (studioApp.isUsingBlockly()) {
    Blockly.mainBlockSpace.traceOn(true);
  }
  Applab.execute();

  // Re-render overlay to update cursor rules.
  Applab.renderVisualizationOverlay();

  // Enable the Finish button if is present:
  var shareCell = document.getElementById('share-cell');
  if (shareCell) {
    shareCell.className = 'share-cell-enabled';
  }

  if (studioApp.editor) {
    logToCloud.addPageAction(logToCloud.PageAction.RunButtonClick, {
      usingBlocks: studioApp.editor.currentlyUsingBlocks,
      app: 'applab'
    }, 1 / 100);
  }
};

/**
 * App specific displayFeedback function that calls into
 * studioApp.displayFeedback when appropriate
 */
var displayFeedback = function () {
  if (!Applab.waitingForReport) {
    studioApp.displayFeedback({
      app: 'applab', // XXX
      skin: skin.id,
      feedbackType: Applab.testResults,
      executionError: Applab.executionError,
      response: Applab.response,
      level: level,
      showingSharing: level.freePlay,
      tryAgainText: applabMsg.tryAgainText(),
      feedbackImage: Applab.feedbackImage,
      twitter: twitterOptions,
      // allow users to save freeplay levels to their gallery (impressive non-freeplay levels are autosaved)
      saveToGalleryUrl: level.freePlay && Applab.response && Applab.response.save_to_gallery_url,
      message: Applab.message,
      appStrings: {
        reinfFeedbackMsg: applabMsg.reinfFeedbackMsg(),
        sharingText: applabMsg.shareGame()
      }
    });
  }
};

Applab.onSubmitComplete = function (response) {
  window.location.href = response.redirect;
};

/**
 * Function to be called when the service report call is complete
 * @param {object} JSON response (if available)
 */
Applab.onReportComplete = function (response) {
  Applab.response = response;
  Applab.waitingForReport = false;
  studioApp.onReportComplete(response);
  displayFeedback();
};

//
// Generates code with user-generated function definitions and evals that code
// so these can be called from event handlers. This should be called for each
// block type that defines functions.
//

var defineProcedures = function (blockType) {
  var code = Blockly.Generator.blockSpaceToCode('JavaScript', blockType);
  // TODO: handle editCode JS interpreter
  try {
    codegen.evalWith(code, {
      studioApp: studioApp,
      Applab: apiBlockly,
      Globals: Applab.Globals
    });
  } catch (e) { }
};

/**
 * Execute the app
 */
Applab.execute = function () {
  Applab.result = ResultType.UNSET;
  Applab.testResults = TestResults.NO_TESTS_RUN;
  Applab.waitingForReport = false;
  Applab.response = null;

  studioApp.reset(false);
  studioApp.clearAndAttachRuntimeAnnotations();
  studioApp.attempts++;

  // Set event handlers and start the onTick timer

  var codeWhenRun;
  if (level.editCode) {
    codeWhenRun = studioApp.getCode();
  } else {
    // Define any top-level procedures the user may have created
    // (must be after reset(), which resets the Applab.Globals namespace)
    defineProcedures('procedures_defreturn');
    defineProcedures('procedures_defnoreturn');

    var blocks = Blockly.mainBlockSpace.getTopBlocks();
    for (var x = 0; blocks[x]; x++) {
      var block = blocks[x];
      if (block.type === 'when_run') {
        codeWhenRun = Blockly.Generator.blocksToCode('JavaScript', [block]);
        break;
      }
    }
  }
  if (codeWhenRun) {
    if (level.editCode) {
      // Create a new interpreter for this run
      Applab.JSInterpreter = new JSInterpreter({
        studioApp: studioApp,
        logExecution: !!level.logConditions,
        shouldRunAtMaxSpeed: function () { return getCurrentTickLength() === 0; },
        maxInterpreterStepsPerTick: MAX_INTERPRETER_STEPS_PER_TICK
      });

      // Register to handle interpreter events
      Applab.JSInterpreter.onExecutionError.register(handleExecutionError);
      if (jsInterpreterLogger) {
        jsInterpreterLogger.attachTo(Applab.JSInterpreter);
      }
      if (debuggerUi) {
        debuggerUi.attachTo(Applab.JSInterpreter);
      }

      // Initialize the interpreter and parse the student code
      Applab.JSInterpreter.parse({
        code: codeWhenRun,
        blocks: dropletConfig.blocks,
        blockFilter: level.executePaletteApisOnly && level.codeFunctions,
        enableEvents: true
      });
      // Maintain a reference here so we can still examine this after we
      // discard the JSInterpreter instance during reset
      Applab.currentExecutionLog = Applab.JSInterpreter.executionLog;
      if (!Applab.JSInterpreter.initialized()) {
        return;
      }
    } else {
      Applab.whenRunFunc = codegen.functionFromCode(codeWhenRun, {
        StudioApp: studioApp,
        Applab: apiBlockly,
        Globals: Applab.Globals
      });
    }
  }

  if (Applab.makerlabController) {
    Applab.makerlabController
        .connectAndInitialize(codegen, Applab.JSInterpreter)
        .then(Applab.beginVisualizationRun);
  } else {
    Applab.beginVisualizationRun();
  }
};

Applab.beginVisualizationRun = function () {
  // Set focus on the default screen so key events can be handled
  // right from the start without requiring the user to adjust focus.
  Applab.loadDefaultScreen();

  Applab.running = true;
  $('#headers').addClass('dimmed');
  $('#codeWorkspace').addClass('dimmed');
  designMode.renderDesignWorkspace();
  queueOnTick();
};

Applab.feedbackImage = '';
Applab.encodedFeedbackImage = '';

Applab.onViewData = function () {
  window.open(
    '//' + utils.getPegasusHost() + '/v3/edit-csp-app/' + Applab.channelId,
    '_blank');
};

/**
 * Handle code/design mode change.
 * @param {ApplabInterfaceMode} mode
 */
function onInterfaceModeChange(mode) {
  if (mode === ApplabInterfaceMode.DESIGN) {
    studioApp.resetButtonClick();
  } else if (mode === ApplabInterfaceMode.CODE) {
    utils.fireResizeEvent();
    if (!Applab.isRunning()) {
      Applab.serializeAndSave();
      var divApplab = document.getElementById('divApplab');
      designMode.parseFromLevelHtml(divApplab, false);
      Applab.changeScreen(Applab.reduxStore.getState().currentScreenId);
    } else {
      Applab.activeScreen().focus();
    }
  }
}

/**
 * Show a modal dialog with a title, text, and OK and Cancel buttons
 * @param {title}
 * @param {text}
 * @param {callback} [onConfirm] what to do when the user clicks OK
 * @param {string} [filterSelector] Optional selector to filter for.
 */

Applab.showConfirmationDialog = function (config) {
  config.text = config.text || '';
  config.title = config.title || '';

  var contentDiv = document.createElement('div');
  contentDiv.innerHTML = '<p class="dialog-title">' + config.title + '</p>' +
      '<p>' + config.text + '</p>';

  var buttons = document.createElement('div');
  ReactDOM.render(React.createElement(DialogButtons, {
    confirmText: applabMsg.dialogOK(),
    cancelText: applabMsg.dialogCancel()
  }), buttons);
  contentDiv.appendChild(buttons);

  var dialog = studioApp.createModalDialog({
    contentDiv: contentDiv,
    defaultBtnSelector: '#confirm-button'
  });

  var cancelButton = buttons.querySelector('#again-button');
  if (cancelButton) {
    dom.addClickTouchEvent(cancelButton, function () {
      dialog.hide();
    });
  }

  var confirmButton = buttons.querySelector('#confirm-button');
  if (confirmButton) {
    dom.addClickTouchEvent(confirmButton, function () {
      if (config.onConfirm) {
        config.onConfirm();
      }
      dialog.hide();
    });
  }

  dialog.show();
};

Applab.onPuzzleSubmit = function () {
  Applab.showConfirmationDialog({
    title: applabMsg.submitYourProject(),
    text: applabMsg.submitYourProjectConfirm(),
    onConfirm: function () {
      Applab.onPuzzleComplete(true);
    }
  });
};

Applab.unsubmit = function () {
  $.post(level.unsubmitUrl,
         {'_method': 'PUT', user_level: {submitted: false}},
         function (data) {
           window.location.reload();
         });
};

Applab.onPuzzleUnsubmit = function () {
  Applab.showConfirmationDialog({
    title: applabMsg.unsubmitYourProject(),
    text: applabMsg.unsubmitYourProjectConfirm(),
    onConfirm: function () {
      Applab.unsubmit();
    }
  });
};

Applab.onPuzzleFinish = function () {
  Applab.onPuzzleComplete(false); // complete without submitting
};

Applab.onPuzzleComplete = function (submit) {
  if (Applab.executionError) {
    Applab.result = ResultType.ERROR;
  } else {
    // In most cases, submit all results as success
    Applab.result = ResultType.SUCCESS;
  }

  // If we know they succeeded, mark levelComplete true
  var levelComplete = (Applab.result === ResultType.SUCCESS);

  if (Applab.executionError) {
    Applab.testResults = studioApp.getTestResults(levelComplete, {
      executionError: Applab.executionError
    });
  } else if (level.logConditions) {
    var results = executionLog.getResultsFromLog(level.logConditions,
        Applab.currentExecutionLog);
    Applab.testResults = results.testResult;
    Applab.message = results.message;
  } else if (!submit) {
    Applab.testResults = TestResults.FREE_PLAY;
  }

  // If we're failing due to failOnLintErrors, replace the previous test result
  // when it is a more positive (relatively more successful) test result
  if (level.failOnLintErrors && annotationList.getJSLintAnnotations().length) {
    if (Applab.testResults > TestResults.GENERIC_LINT_FAIL) {
      Applab.testResults = TestResults.GENERIC_LINT_FAIL;
    }
  }

  // Stop everything on screen
  Applab.clearEventHandlersKillTickLoop();

  if (Applab.testResults >= TestResults.FREE_PLAY) {
    studioApp.playAudio('win');
  } else {
    studioApp.playAudio('failure');
  }

  var program;

  if (level.editCode) {
    // If we want to "normalize" the JavaScript to avoid proliferation of nearly
    // identical versions of the code on the service, we could do either of these:

    // do an acorn.parse and then use escodegen to generate back a "clean" version
    // or minify (uglifyjs) and that or js-beautify to restore a "clean" version

    program = studioApp.getCode();
  } else {
    var xml = Blockly.Xml.blockSpaceToDom(Blockly.mainBlockSpace);
    program = Blockly.Xml.domToText(xml);
  }

  Applab.waitingForReport = true;

  var sendReport = function () {
    studioApp.report({
      app: 'applab',
      level: level.id,
      result: levelComplete,
      testResult: Applab.testResults,
      submitted: submit,
      program: encodeURIComponent(program),
      image: Applab.encodedFeedbackImage,
      onComplete: (submit ? Applab.onSubmitComplete : Applab.onReportComplete)
    });
  };

  var divApplab = document.getElementById('divApplab');
  if (!divApplab || typeof divApplab.toDataURL === 'undefined') { // don't try it if function is not defined
    sendReport();
  } else {
    divApplab.toDataURL('image/png', {
      callback: function (pngDataUrl) {
        Applab.feedbackImage = pngDataUrl;
        Applab.encodedFeedbackImage = encodeURIComponent(Applab.feedbackImage.split(',')[1]);

        sendReport();
      }
    });
  }
};

Applab.executeCmd = function (id, name, opts) {
  var cmd = {
    'id': id,
    'name': name,
    'opts': opts
  };
  return Applab.callCmd(cmd);
};

//
// Execute an API command
//

Applab.callCmd = function (cmd) {
  var retVal = false;
  if (applabCommands[cmd.name] instanceof Function) {
    studioApp.highlight(cmd.id);
    retVal = applabCommands[cmd.name](cmd.opts);
  }
  return retVal;
};

/*
var onWaitComplete = function (opts) {
  if (!opts.complete) {
    if (opts.waitCallback) {
      opts.waitCallback();
    }
    opts.complete = true;
  }
};

Studio.wait = function (opts) {
  if (!opts.started) {
    opts.started = true;

    // opts.value is the number of milliseconds to wait - or 'click' which means
    // "wait for click"
    if ('click' === opts.value) {
      opts.waitForClick = true;
    } else {
      opts.waitTimeout = window.setTimeout(
        delegate(this, onWaitComplete, opts),
        opts.value);
    }
  }

  return opts.complete;
};
*/

Applab.timedOut = function () {
  return Applab.tickCount > Applab.timeoutFailureTick;
};

var checkFinished = function () {
  // if we have a succcess condition and have accomplished it, we're done and successful
  if (level.goal && level.goal.successCondition && level.goal.successCondition()) {
    Applab.result = ResultType.SUCCESS;
    return true;
  }

  // if we have a failure condition, and it's been reached, we're done and failed
  if (level.goal && level.goal.failureCondition && level.goal.failureCondition()) {
    Applab.result = ResultType.FAILURE;
    return true;
  }

  /*
  if (Applab.allGoalsVisited()) {
    Applab.result = ResultType.SUCCESS;
    return true;
  }
  */

  if (Applab.timedOut()) {
    Applab.result = ResultType.FAILURE;
    return true;
  }

  return false;
};

Applab.startInDesignMode = function () {
  return !!level.designModeAtStart;
};

Applab.isInDesignMode = function () {
  return $('#designWorkspace').is(':visible');
};

function quote(str) {
  return '"' + str + '"';
}

/**
 * Return droplet dropdown options representing a list of ids currently present
 * in the DOM, optionally limiting the result to a certain HTML element tagName.
 * @param {string} [filterSelector] Optional selector to filter for.
 * @returns {Array}
 */
Applab.getIdDropdown = function (filterSelector) {
  return Applab.getIdDropdownFromDom_($(document), filterSelector);
};

/**
 * Internal helper for getIdDropdown, which takes a documentRoot
 * argument to remove its global dependency and make it testable.
 * @param {jQuery} documentRoot
 * @param {string} filterSelector
 * @returns {Array}
 * @private
 */
Applab.getIdDropdownFromDom_ = function (documentRoot, filterSelector) {
  var elements = documentRoot.find('#designModeViz [id^="' + applabConstants.DESIGN_ELEMENT_ID_PREFIX + '"]');

  // Return all elements when no filter is given
  if (filterSelector) {
    elements = elements.filter(filterSelector);
  }

  return elements.sort(byId).map(function (_, element) {
    var id = quote(elementUtils.getId(element));
    return {text: id, display: id};
  }).get();
};

function byId(a, b) {
  return a.id > b.id ? 1 : -1;
}

/**
 * Returns a list of IDs currently present in the DOM of the current screen,
 * including the screen, sorted by z-index.
 */
Applab.getIdDropdownForCurrentScreen = function () {
  return Applab.getIdDropdownForCurrentScreenFromDom_($('#designModeViz'));
};

/**
 * Internal helper for getIdDropdownForCurrentScreen.
 * @private
 */
Applab.getIdDropdownForCurrentScreenFromDom_ = function (documentRoot) {
  var screen = documentRoot.find('.screen').filter(function () {
    return this.style.display !== 'none';
  }).first();

  var elements = screen.find('[id^="' + applabConstants.DESIGN_ELEMENT_ID_PREFIX + '"]').add(screen);

  return elements.map(function (_, element) {
    return elementUtils.getId(element);
  }).get();
};

/**
 * @returns {HTMLElement} The first "screen" that isn't hidden.
 */
Applab.activeScreen = function () {
  return Applab.getScreens().filter(function () {
    return this.style.display !== 'none';
  }).first()[0];
};

/**
 * Changes the active screen by toggling all screens in divApplab to be non-visible,
 * unless they match the provided screenId. Also focuses the screen.
 */
Applab.changeScreen = function (screenId) {
  Applab.getScreens().each(function () {
    $(this).toggle(this.id === screenId);
    if ((this.id === screenId)) {
      // Allow the active screen to receive keyboard events.
      this.focus();
    }
  });

  // Hacky - showTurtleBeforeRun option is designed for authored levels, so we
  // probably ought to make sure it's shown regardless of what screen we display.
  if (!Applab.isRunning()) {
    if (level.showTurtleBeforeRun) {
      applabTurtle.turtleSetVisibility(true);
    }
  }
};

Applab.loadDefaultScreen = function () {
  var defaultScreenId = Applab.getScreens().first().attr('id');
  Applab.changeScreen(defaultScreenId);
};

Applab.getScreens = function () {
  return $('#divApplab > .screen');
};

// Wrap design mode function so that we can call from commands
Applab.updateProperty = function (element, property, value) {
  return designMode.updateProperty(element, property, value);
};

Applab.isCrosshairAllowed = function () {
  return !Applab.isReadOnlyView && !Applab.isRunning();
};

Applab.showRateLimitAlert = function () {
  // only show the alert once per session
  if (hasSeenRateLimitAlert) {
    return false;
  }
  hasSeenRateLimitAlert = true;

  var alert = <div>{applabMsg.dataLimitAlert()}</div>;
  if (studioApp.share) {
    studioApp.displayPlayspaceAlert('error', alert);
  } else {
    studioApp.displayWorkspaceAlert('error', alert);
  }
};


text:
<?php

namespace Symfony\Component\Validator\Tests\Fixtures;

use Symfony\Component\Validator\Constraints\NotNull;

class EntityParent
{
    protected $firstName;
    private $internal;

    /**
     * @NotNull
     */
    protected $other;
}

redpajama_set_name: RedPajamaGithub


text:
using Count;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Grpc.Net.Client;

using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Counter.CounterClient(channel);

await UnaryCallExample(client);

await ClientStreamingCallExample(client);

await ServerStreamingCallExample(client);

Console.WriteLine("Shutting down");
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

static async Task UnaryCallExample(Counter.CounterClient client)
{
    var reply = await client.IncrementCountAsync(new Empty());
    Console.WriteLine("Count: " + reply.Count);
}

static async Task ClientStreamingCallExample(Counter.CounterClient client)
{
    using var call = client.AccumulateCount();
    for (var i = 0; i < 3; i++)
    {
        var count = Random.Shared.Next(5);
        Console.WriteLine($"Accumulating with {count}");
        await call.RequestStream.WriteAsync(new CounterRequest { Count = count });
        await Task.Delay(TimeSpan.FromSeconds(2));
    }

    await call.RequestStream.CompleteAsync();

    var response = await call;
    Console.WriteLine($"Count: {response.Count}");
}

static async Task ServerStreamingCallExample(Counter.CounterClient client)
{
    using var call = client.Countdown(new Empty());

    await foreach (var message in call.ResponseStream.ReadAllAsync())
    {
        Console.WriteLine($"Countdown: {message.Count}");
    }
}


text:
{% extends "base.html" %}

{% load i18n %}
{% load markdown_deux_tags %}

{% block title %}
{% trans "Send Mail" %}
{% endblock title %}

{% block content %}

{% trans "Send Mail" %}

        {% for error in form.non_field_errors %}

            {{ error }}
            <button type="button" class="close" data-dismiss="alert" aria-label="{% trans 'Close' context 'action' %}">
                ×
            </button>

        {% endfor %}

        <form class="send-message-form form-horizontal" method="post">
            {% csrf_token %}
            {% for field in form %}

            {% if forloop.first %}

{% trans "Recipients" %}

            {% elif field.auto_id == 'id_subject' %}

{% trans "Message" %}

            {% endif %}

            {% if field.field.widget.input_type == 'hidden' %}
            {{ field }}
            {% else %}

                {{ field.label }}

                    {{ field }}
                    {% if field.errors %}

                        {{ field.errors }}

                    {% endif %}
                    {% if field.help_text %}

                        {{ field.help_text }}

                    {% endif %}

            {% endif %}
            {% endfor %}

            {% if mail_recipient_count > 50 %}

                {% blocktrans trimmed with user_count=mail_recipient_count %}
                Warning! You have chosen to send this message to a lot of people (around {{ user_count }}).
                This may take a long time. As a rough estimate, 100 recipients takes about 30 seconds.
                You may time out while waiting, but the emails should still get sent in even if you go to another page.
                Don't try to submit again or refresh this page while waiting, though!
                You can check the admin panel for status updates.
                {% endblocktrans %}

            {% endif %}

                <input type="submit" class="btn btn-info" name="preview" value="{% trans "Preview" context "verb" %}" />
                <input type="submit" class="btn btn-primary" name="send" value="{% trans "Send" %}" />

        </form>

{% if mail_content %}

{% trans "Preview" context "noun" %}

{% trans "Total number of receivers:" %} {{ mail_recipient_count }}

{{ mail_subject }}

                {{ mail_content | striptags | markdown }}

{% endif %}
{% endblock content %}


text:
struct A {
  constexpr A() : a(b + 1), b(a + 1) {} // expected-note 5{{outside its lifetime}}
  int a;
  int b;
};
struct B { // expected-note {{in call to 'A()'}}
  A a;
};

constexpr A a1; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
constexpr A a2 = A(); // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
void f() {
  constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
}

constexpr B b1; // expected-error {{constant expression}} expected-note {{in call to 'B()'}}
constexpr B b2 = B(); // ok
static_assert(b2.a.a == 1, "");
static_assert(b2.a.b == 2, "");

struct C {
  int c;
};
struct D : C { int d; };
constexpr C c1; // expected-error {{without a user-provided default constructor}}
constexpr C c2 = C(); // ok
constexpr D d1; // expected-error {{without a user-provided default constructor}}
constexpr D d2 = D(); // ok with DR1452
static_assert(D().c == 0, "");
static_assert(D().d == 0, "");

struct V : virtual C {};
template<typename T> struct Z : T {
  constexpr Z() : V() {}
};
constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{non-literal type 'Z<V>'}}

struct E { // expected-note {{in call to 'A()'}}
  A a[2];
};
constexpr E e1; // expected-error {{constant expression}} expected-note {{in call to 'E()'}}
constexpr E e2 = E();
static_assert(e2.a[0].a == 1, "");
static_assert(e2.a[0].b == 2, "");
static_assert(e2.a[1].a == 1, "");
static_assert(e2.a[1].b == 2, "");


text:
/* TODO: High-level file comment. */

#ifndef GEO_EARTH_ENTERPRISE_SRC_FUSION_PORTABLEGLOBE_SERVERS_FILEUNPACKER_WINDOWS_KHTYPES_H_
#define GEO_EARTH_ENTERPRISE_SRC_FUSION_PORTABLEGLOBE_SERVERS_FILEUNPACKER_WINDOWS_KHTYPES_H_

#include <assert.h>
#include <sys/types.h>

typedef unsigned short                  uint16;
typedef short                           int16;
typedef unsigned long                   uint32;
typedef long                            int32;
typedef unsigned __int64                uint64;
typedef __int64                         int64;
typedef unsigned short                  ushort;

typedef unsigned char                   uchar;
typedef unsigned char                   uint8;
typedef signed char                     int8;
typedef float                           float32;
typedef double                          float64;

#endif  // GEO_EARTH_ENTERPRISE_SRC_FUSION_PORTABLEGLOBE_SERVERS_FILEUNPACKER_WINDOWS_KHTYPES_H_


text:
class RectangleShape : public Shape
{
public:
	RectangleShape();
	RectangleShape(const glm::vec2& size);
	RectangleShape(float width, float height);

public:
	float width;
	float height;
};

#endif


text:
<?php

namespace Ffcms\Core\Interfaces;

/**
 * Interface iUser
 * @package Ffcms\Core\Interfaces
 * @property int $id
 * @property string $login
 * @property string $email
 * @property string $password
 * @property int $role_id
 * @property string $approve_token
 */
interface iUser
{
    /**
     * Get current user id if auth
     * @return int
     */
    public function getId(): ?int;

    /**
     * Get user param
     * @param string $param
     * @param null|string $defaultValue
     * @return string|null
     */
    public function getParam(string $param, ?string $defaultValue = null): ?string;

    /**
     * Check if current user session is auth
     * @return bool
     */
    public static function isAuth(): bool;

    /**
     * Check if user with $id exist
     * @param string|int|null $id
     * @return bool
     */
    public static function isExist(?string $id = null): bool;

    /**
     * Get user person all data like a object
     * @param string|int|null $id
     * @return self
     */
    public static function identity(?string $id = null);

    /**
     * Check if use with $email is exist
     * @param string|null $email
     * @return bool
     */
    public static function isMailExist(?string $email = null): bool;

    /**
     * Get user person like a object via email
     * @param string|null $email
     * @return null|self
     */
    public static function getIdentityViaEmail(?string $email = null);

    /**
     * Check if target user with $target_id in blacklist for current session user_id
     * @param string|int|bool $target
     * @return bool
     */
    public function inBlacklist(?string $target = null): bool;
}


text:
  Facebook
  Google+
  Twitter
  GitHub
  RSS
  License
  Bug Report


text:
#import <Foundation/Foundation.h>

@interface CMISBase64Encoder : NSObject

/// encodes data into base 64 and returns the result as NSString
+ (NSString *)stringByEncodingText:(NSData *)plainText;

/// returns base64 encoded data for given input data
+ (NSData *)dataByEncodingText:(NSData *)plainText;

/// base64 encodes the content of a file
+ (NSString *)encodeContentOfFile:(NSString *)sourceFilePath;

/// base64 encodes data from an input stream
+ (NSString *)encodeContentFromInputStream:(NSInputStream*)inputStream;

/// base64 encodes data from a source file and appends the encoded result to the given destination file
+ (void)encodeContentOfFile:(NSString *)sourceFilePath appendToFile:(NSString *)destinationFilePath;

/// base64 encodes data from an input stream and appends the encoded data to a given destination file
+ (void)encodeContentFromInputStream:(NSInputStream*)inputStream appendToFile:(NSString *)destinationFilePath;

@end


text:
title: About
taxonomy:
    category: sidebar
css_suffix: widget_text
---

Receptar is simple, modern, responsive, high-DPI, fully customizable blog Grav theme. It features split-screen book-like design inspired by a modern cook book with emphasize on beautiful imagery and typography.

More info at [getgrav.org](getgrav.org).


text:
@import UIKit;

@interface PTSViewController : UIViewController<UIScrollViewDelegate>

@end


text:
(function() {
  'use strict';

  describe('Launch Instance Configuration Step', function() {

    describe('LaunchInstanceConfigurationController', function() {
      var scope, ctrl;

      beforeEach(module('horizon.dashboard.project.workflow.launch-instance'));

      beforeEach(inject(function($controller) {
        scope = {
          model: {
            newInstanceSpec: {}
          }
        };

        ctrl = $controller('LaunchInstanceConfigurationController', {
          $scope: scope
        });
      }));

      it('contains its own labels', function() {
        expect(ctrl.label).toBeDefined();
        expect(Object.keys(ctrl.label).length).toBeGreaterThan(0);
      });

      it('has correct disk configuration options', function() {
        expect(ctrl.diskConfigOptions).toBeDefined();
        expect(ctrl.diskConfigOptions.length).toBe(2);
        var vals = ctrl.diskConfigOptions.map(function(x) { return x.value; });
        expect(vals).toContain('AUTO');
        expect(vals).toContain('MANUAL');
      });

      it('defaults the disk configuration to "AUTO"', function() {
        expect(scope.model.newInstanceSpec.disk_config).toBe('AUTO');
      });

      it('defaults the config_drive configuration to false', function() {
        expect(scope.model.newInstanceSpec.config_drive).toBe(false);
      });

      it('defaults the user_data configuration to ""', function() {
        expect(scope.model.newInstanceSpec.user_data).toBe('');
      });

    });

    describe('LaunchInstanceConfigHelpController', function() {
      var ctrl;

      beforeEach(module('horizon.dashboard.project.workflow.launch-instance'));

      beforeEach(inject(function($controller) {
        ctrl = $controller('LaunchInstanceConfigHelpController');
      }));

      it('defines the title', function() {
        expect(ctrl.title).toBeDefined();
      });

      it('has help paragraphs', function() {
        expect(ctrl.paragraphs).toBeDefined();
        expect(ctrl.paragraphs.length).toBeGreaterThan(0);
      });
    });

  });

})();


text:
template <class... Types>
struct typelist
{
};

/// Concatenate two typelists.
// Source: http://stackoverflow.com/a/9122122/111426
template <class S, class T>
struct typelist_cat;

template <class ...Ss, class ...Ts>
struct typelist_cat<typelist<Ss...>, typelist<Ts...>>
{
  typedef typelist<Ss..., Ts...> type;
};

/// Cartesian product of two typelists.
// Source: http://stackoverflow.com/a/9122122/111426
template <class S, class T> struct typelist_product;

template <class S, class ...Ss, class... Ts>
struct typelist_product<typelist<S, Ss...>, typelist<Ts...>>
{
  // the cartesian product of {S} and {Ts...}
  // is a list of pairs -- here: a typelist of 2-element typelists
  typedef typelist<typelist<S, Ts>...> S_cross_Ts;

  // the cartesian product of {Ss...} and {Ts...} (computed recursively)
  typedef typename typelist_product<typelist<Ss...>, typelist<Ts...>>::type Ss_cross_Ts;

  // concatenate both products
  typedef typename typelist_cat<S_cross_Ts, Ss_cross_Ts>::type type;
};

template <typename ...Ts>
struct typelist_product<typelist<>, typelist<Ts...>>
{
  typedef typelist<> type;
};

#endif // ifndef DARTPY_TEMPLATE_METAPROGRAMMING_H_


text:
  // Uncomment to disable all protocol checks. The prover will not attempt to
  // compute any sane responses. This is useful to quickly check for memory
  // usage.
  //#define CMTGKR_DISABLE_CHECKS 1

  // Uncomment to log the current layer that the verifier is on.
  // TODO: Implement proper logging levels.
  //#define LOG_LAYER 1
#endif

struct CMTProverConfig
{
  int startInstance;
  int endInstance;

  CMTProverConfig(int firstInstance, int lastInstance)
    : startInstance(firstInstance), endInstance(lastInstance)
  { }

  int batchSize() const { return endInstance - startInstance; }
};

struct CMTVerifierConfig
{
  int batchSize;

  explicit CMTVerifierConfig(int nBatch)
    : batchSize(nBatch)
  { }
};

struct CMTProtocolConfig
{
  CMTVerifierConfig vConf;
  std::vector<CMTProverConfig> pConfs;

  CMTProtocolConfig()
    : vConf(1), pConfs(1, CMTProverConfig(0, 1))
  { }

  CMTProtocolConfig(int nBatch, int nProvers)
    : vConf(nBatch), pConfs()
  {
    int numResponsible = nBatch / nProvers;
    int extra = nBatch - numResponsible * nProvers;

    for (int pid = 0; pid < nProvers; pid++)
    {
      int start = pid * numResponsible + std::min(pid, extra);
      int end = start + numResponsible + (pid < extra ? 1 : 0);

      pConfs.push_back(CMTProverConfig(start, end));
    }
  }

  int batchSize() const { return vConf.batchSize; }
  size_t numProvers() const { return pConfs.size(); }
};

#endif


text:
@extends('layouts.app')

@section('page_title')
    Dashboard
@endsection

@section('content')

Dashboard API

                <passport-clients></passport-clients>
                <passport-authorized-clients></passport-authorized-clients>
                <passport-personal-access-tokens></passport-personal-access-tokens>

@endsection


text:
class RelaunchRequiredDialogViewDialogTest : public DialogBrowserTest {
 public:
  RelaunchRequiredDialogViewDialogTest(
      const RelaunchRequiredDialogViewDialogTest&) = delete;
  RelaunchRequiredDialogViewDialogTest& operator=(
      const RelaunchRequiredDialogViewDialogTest&) = delete;

 protected:
  RelaunchRequiredDialogViewDialogTest() = default;

  // DialogBrowserTest:
  void ShowUi(const std::string& name) override {
    base::Time deadline = base::Time::Now() + base::Days(3);
    RelaunchRequiredDialogView::Show(browser(), deadline, base::DoNothing());
  }
};

IN_PROC_BROWSER_TEST_F(RelaunchRequiredDialogViewDialogTest, InvokeUi_default) {
  ShowAndVerifyUi();
}


text:
package com.iosdevlog.a241creatingrichnavigationwithfragments;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity
        implements NavigationDrawerFragment.NavigationDrawerCallbacks {

    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */
    private NavigationDrawerFragment mNavigationDrawerFragment;

    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */
    private CharSequence mTitle;

    String[] mTitles;
    String[] mTitlesShort;
    String[] mDescriptions;
    int[] mTopImageResourceIds = {
            R.drawable.db_programming_top_card,
            R.drawable.android_4_top_card,
            R.drawable.sys_dev_top_card,
            R.drawable.and_engine_top_card
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTitles = getResources().getStringArray(R.array.book_titles);
        mTitlesShort = getResources().getStringArray(R.array.book_titles_short);
        mDescriptions = getResources().getStringArray(R.array.book_descriptions);
        mTitle = mTitles[0];

        setContentView(R.layout.activity_main);

        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getFragmentManager().findFragmentById(R.id.navigation_drawer);

        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        mTitle = mTitles[position];

        // update the main content by replacing fragments
        BookFragment newFragment =
                BookFragment.newInstance(mTitles[position], mDescriptions[position], mTopImageResourceIds[position]);
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, newFragment)
                .commit();
    }

    public void onSectionAttached(int number) {
        mTitle = mTitles[number];
//        switch (number) {
//            case 1:
//                mTitle = getString(R.string.title_section1);
//                break;
//            case 2:
//                mTitle = getString(R.string.title_section2);
//                break;
//            case 3:
//                mTitle = getString(R.string.title_section3);
//                break;
//        }
    }

    public void restoreActionBar() {
        ActionBar actionBar = getActionBar();
        //actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.main, menu);
            //restoreActionBar();
            ActionBar actionBar = getActionBar();
            actionBar.setDisplayShowTitleEnabled(true);
            actionBar.setTitle(mTitle);

            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class BookFragment extends Fragment {
        private static final String ARG_TITLE = "title";
        private static final String ARG_DESCRIPTION = "description";
        private static final String ARG_IMAGE_ID = "image id";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static BookFragment newInstance(String title, String description, int imageResourceId) {
            BookFragment fragment = new BookFragment();
            Bundle args = new Bundle();
            args.putString(ARG_TITLE, title);
            args.putString(ARG_DESCRIPTION, description);
            args.putInt(ARG_IMAGE_ID, imageResourceId);
            fragment.setArguments(args);
            return fragment;
        }

        public BookFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_book_info, container, false);

            TextView bookTitleView = (TextView)rootView.findViewById(R.id.bookTitle);
            TextView bookDescriptionView = (TextView)rootView.findViewById(R.id.bookDescription);
            ImageView topImageView = (ImageView)rootView.findViewById(R.id.topImage);

            Bundle args = getArguments();
            bookTitleView.setText(args.getString(ARG_TITLE));
            bookDescriptionView.setText(args.getString(ARG_DESCRIPTION));
            topImageView.setImageResource(args.getInt(ARG_IMAGE_ID));

            return rootView;
        }
    }

}


text:
package org.apache.servicecomb.swagger.invocation.schemas;

import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.apache.servicecomb.swagger.invocation.schemas.models.AddBeanParamV2;

@Path("/")
public interface JaxrsAddBeanParamV2 {
  @Path("/add")
  @GET
  int add(@BeanParam AddBeanParamV2 wrapper);
}


text:
/**
 * All methods are used to initialize the file upload processs.
 *
 * @author Robb Krasnow
 * @version 1.0
 */

/**
 * This method initializes the file upload process. It will first check
 * if the browser is capable of using the File API and display appropriate
 * errors before the file is even uploaded to the server. It will check for
 * file size limits as well as file extenstions. Once the file passes all
 * validation, AJAX sends the file to the server.
 */
function initUpload() {
	var successString,
		errorString,
		progress,
		file;

	successString = $('.success-box');
	errorString	= $('.error-box');
	progress = $('.progress');
	file = $('#file');

	progress.hide();
	successString.css({ display: 'none' });
	errorString.css({ display: 'none' });

	$('button[type="submit"]').prop('disabled', true);

	// Check if browser is capable of File API
	if(window.File && window.FileReader && window.FileList && window.Blob) {
		file.bind('change', function() {
			var fileSize = this.files[0].size;
			var fileExt = file.val().split('.').pop().toLowerCase();

			// Check if file size is larger than 128 MB (134217728 bytes)
			// 4096 MB (4294967296 bytes)
			if(fileSize > 4294967296) {
				$('button[type="submit"]').prop('disabled', true);
				errorString.empty();
				errorString.append('Exceeded file size limit.');
				errorString.fadeIn(200);

				return false;
			}

			// Check if file is a .mbox file
			if(fileExt !== 'mbox') {
				$('button[type="submit"]').prop('disabled', true);
				errorString.empty();
				errorString.append('Invalid file format. Please add .mbox extention if it\'s missing.');
				errorString.fadeIn(200);

				return false;
			}

			errorString.css({ display: 'none' });
			$('button[type="submit"]').prop('disabled', false);
		});
	}
	else {
		errorString.empty();
		errorString.append('Please upgrade your browser');
		errorString.fadeIn(200);
	}

	// When the Upload button is clicked, make an AJAX request to
	// send the file to the server.
	// @see https://www.developphp.com/video/JavaScript/File-Upload-Progress-Bar-Meter-Tutorial-Ajax-PHP
	$('#upload-form').submit(function(e) {
		e.preventDefault();

		var file,
			formData;

		file = document.getElementById('file').files[0];
		formData = new FormData();
		formData.append('file', file);

		// Make AJAX call to the uploader script
		$.ajax({
			type: 'POST',
			url: 'uploader.php',
			data: formData,
			dataType: 'json',
			async: true,
			cache: false,
			contentType: false,
			processData: false,
			xhr: function() {
				var xhr = $.ajaxSettings.xhr();

				// Follow upload progress
				xhr.upload.onprogress = function(e) {
					var progress,
						progressStatus,
						progressBar,
						percent;

					progress = $('.progress');
					progressStatus = $('.progress-status');
					progressBar = $('.progress-bar');
					percent = Math.floor(e.loaded / e.total * 100);

					progress.show();
					progressStatus.text(percent + '% uploaded ... please wait');
					progressBar.css('width', percent + '%')
						.attr('aria-valuenow', percent);
				};

				return xhr;
			},
			success: function(result) {
				var successString,
					errorString,
					progressStatus,
					progress;

				successString = $('.success-box');
				errorString	= $('.error-box');
				progressStatus = $('.progress-status');
				progress = $('.progress');

				progressStatus.text('Upload Complete');

				if(result.error) {
					progressStatus.hide();
					progress.hide();
					errorString.empty()
						.append('' + result.error.msg)
						.fadeIn(200);
				}
				else if(result.success) {
					setTimeout(function() {
						progressStatus.text('Parsing file ... please wait');
					}, 1000);

					// Start the upload/parsing process
					initUploadAjax('start_upload',
						userId + '|' +
						result.success.file_hash + '|' +
						result.success.file_name + '|' +
						result.success.file_type + '|' +
						result.success.file_size
					);

					// Anonymous function to continually ask for the parsing status from the server
					// for the particular file that was just uploaded
					(function getParse() {
						initGetParseStatusAjax('start_get_parse_status',
							userId + '|' +
							result.success.file_hash
						);

						// Set interval loop for every 1 second
						setTimeout(getParse, 1000);
					})();
				}
			},
			error: function(err) {
				var errorString,
					progressStatus,
					progress;

				errorString = $('.error-box');
				progressStatus = $('.progress-status');
				progress = $('.progress');

				progressStatus.hide();
				progress.hide();
				errorString.empty()
					.append('Error uploading file. Please try again.')
					.fadeIn(200);
			}
		});
	});
}


text:
package com.webside.base.baseservice.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.webside.base.basemapper.BaseMapper;
import com.webside.base.baseservice.BaseService;
import com.webside.exception.ServiceException;

/**
 *
 * @ClassName: AbstractService
 * @Description: service层基类
 * @author gaogang
 * @date 2016年7月12日 下午3:03:43
 *
 * @param <T>	操作对象类型
 * @param <ID>	id
 */
public class AbstractService<T, ID extends Serializable> implements BaseService<T, ID> {

	private BaseMapper<T, ID> baseMapper;

	public void setBaseMapper(BaseMapper<T, ID> baseMapper) {
		this.baseMapper = baseMapper;
	}

	@Override
	public int insert(T t) {
		try
		{
			return baseMapper.insert(t);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public int insertBatch(List<T> t) {
		try
		{
			return baseMapper.insertBatch(t);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public int deleteById(ID id) {
		try
		{
			return baseMapper.deleteById(id);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public int deleteById(String id) {
		try
		{
			return baseMapper.deleteById(id);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public int update(T t) {
		try
		{
			return baseMapper.update(t);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public int deleteBatchById(List<ID> ids) {
		try
		{
			return baseMapper.deleteBatchById(ids);
		}catch(Exception e)
		{
			throw new ServiceException(e);
		}
	}

	@Override
	public T find(Map<String, Object> parameter) {
		return baseMapper.find(parameter);
	}

	@Override
	public T findById(ID id) {
		return baseMapper.findById(id);
	}

	@Override
	public T findById(String id) {
		return baseMapper.findById(id);
	}

	@Override
	public T findByName(String name) {
		return baseMapper.findByName(name);
	}

	@Override
	public List<T> queryListAll(Map<String, Object> parameter) {
		return baseMapper.queryListAll(parameter);
	}

	@Override
	public List<T> queryListByPage(Map<String, Object> parameter) {
		return baseMapper.queryListByPage(parameter);
	}

	@Override
	public int count(Map<String, Object> parameter) {
		return baseMapper.count(parameter);
	}

}


text:
namespace supersonic {using std::string; }

#include "supersonic/utils/macros.h"
#include "supersonic/utils/scoped_ptr.h"
#include "supersonic/utils/stringprintf.h"
#include "supersonic/base/exception/exception.h"
#include "supersonic/base/exception/exception_macros.h"
#include "supersonic/base/exception/result.h"
#include "supersonic/base/infrastructure/types.h"
#include "supersonic/expression/base/expression.h"
#include "supersonic/expression/core/regexp_bound_expressions.h"
#include "supersonic/expression/core/regexp_bound_expressions_internal.h"
#include "supersonic/expression/core/regexp_evaluators.h"  // IWYU pragma: keep
#include "supersonic/expression/infrastructure/basic_expressions.h"
#include "supersonic/expression/infrastructure/expression_utils.h"
#include "supersonic/expression/proto/operators.pb.h"
#include "supersonic/expression/vector/expression_traits.h"
#include "supersonic/proto/supersonic.pb.h"
#include "supersonic/utils/strings/stringpiece.h"

namespace supersonic {

class BufferAllocator;
class TupleSchema;

namespace {

// The RegExp expressions. They differ from the standard abstract setting in
// having a state - the regexp pattern. This is not an argument (that is - its
// not an expression, as we do not want to compile the pattern each time), but
// really a state.
// TODO(onufry): This could be done through expressions traits, by making them
// stateful and passing an instance of the traits through the building of an
// expression. But that looks like a giant piece of work, and probably isn't
// worth it unless we hit a large number of stateful expressions.
template<OperatorId operation_type>
class RegexpExpression : public UnaryExpression {
 public:
  RegexpExpression(const Expression* const arg,
                   const StringPiece& pattern)
      : UnaryExpression(arg),
        pattern_(pattern.data(), pattern.length()) {}

  virtual string ToString(bool verbose) const {
    return UnaryExpressionTraits<operation_type>::FormatDescription(
        child_expression_->ToString(verbose));
  }

 private:
  virtual FailureOrOwned<BoundExpression> CreateBoundUnaryExpression(
      const TupleSchema& schema,
      BufferAllocator* const allocator,
      rowcount_t row_capacity,
      BoundExpression* child) const {
    scoped_ptr<BoundExpression> child_ptr(child);
    DataType child_type = GetExpressionType(child);
    if (child_type != STRING) {
      THROW(new Exception(ERROR_ATTRIBUTE_TYPE_MISMATCH,
          StringPrintf("Invalid argument type (%s) to %s, STRING expected",
                       GetTypeInfo(child_type).name().c_str(),
                       ToString(true).c_str())));
    }
    return BoundGeneralRegexp<operation_type>(
        child_ptr.release(), pattern_, allocator, row_capacity);
  }

  string pattern_;

  DISALLOW_COPY_AND_ASSIGN(RegexpExpression);
};

class RegexpExtractExpression : public UnaryExpression {
 public:
  RegexpExtractExpression(const Expression* const arg,
                          const StringPiece& pattern)
      : UnaryExpression(arg),
        pattern_(pattern.data(), pattern.length()) {}

  virtual string ToString(bool verbose) const {
    return StringPrintf("REGEXP_EXTRACT(%s)",
                        child_expression_->ToString(verbose).c_str());
  }

 private:
  virtual FailureOrOwned<BoundExpression> CreateBoundUnaryExpression(
      const TupleSchema& schema,
      BufferAllocator* const allocator,
      rowcount_t row_capacity,
      BoundExpression* child) const {
    scoped_ptr<BoundExpression> child_ptr(child);
    DataType child_type = GetExpressionType(child);
    if (child_type != STRING) {
      THROW(new Exception(ERROR_ATTRIBUTE_TYPE_MISMATCH,
          StringPrintf("Invalid argument type (%s) to %s, STRING expected",
                       GetTypeInfo(child_type).name().c_str(),
                       ToString(true).c_str())));
    }
    return BoundRegexpExtract(child_ptr.release(), pattern_, allocator,
                              row_capacity);
  }

  string pattern_;

  DISALLOW_COPY_AND_ASSIGN(RegexpExtractExpression);
};

class RegexpReplaceExpression : public BinaryExpression {
 public:
  RegexpReplaceExpression(const Expression* const haystack,
                          const StringPiece& needle,
                          const Expression* const substitute)
      : BinaryExpression(haystack, substitute),
        pattern_(needle.data(), needle.length()) {}

  virtual string ToString(bool verbose) const {
    return BinaryExpressionTraits<OPERATOR_REGEXP_REPLACE>::FormatDescription(
        left_->ToString(verbose), right_->ToString(verbose));
  }

 private:
  virtual FailureOrOwned<BoundExpression> CreateBoundBinaryExpression(
      const TupleSchema& schema,
      BufferAllocator* const allocator,
      rowcount_t row_capacity,
      BoundExpression* left,
      BoundExpression* right) const {
    scoped_ptr<BoundExpression> left_ptr(left);
    scoped_ptr<BoundExpression> right_ptr(right);
    DataType left_type = GetExpressionType(left);
    if (left_type != STRING) {
      THROW(new Exception(ERROR_ATTRIBUTE_TYPE_MISMATCH,
          StringPrintf("Invalid argument type (%s) as first argument to %s, "
                       "STRING expected",
                       GetTypeInfo(left_type).name().c_str(),
                       ToString(true).c_str())));
    }
    DataType right_type = GetExpressionType(right);
    if (right_type != STRING) {
      THROW(new Exception(ERROR_ATTRIBUTE_TYPE_MISMATCH,
          StringPrintf("Invalid argument type (%s) as last argument to %s, "
                       "STRING expected",
                       GetTypeInfo(right_type).name().c_str(),
                       ToString(true).c_str())));
    }
    return BoundRegexpReplace(left_ptr.release(), pattern_, right_ptr.release(),
                              allocator, row_capacity);
  }

  string pattern_;

  DISALLOW_COPY_AND_ASSIGN(RegexpReplaceExpression);
};

}  // namespace

const Expression* RegexpPartialMatch(const Expression* const str,
                                     const StringPiece& pattern) {
  return new RegexpExpression<OPERATOR_REGEXP_PARTIAL>(str, pattern);
}

const Expression* RegexpFullMatch(const Expression* const str,
                                  const StringPiece& pattern) {
  return new RegexpExpression<OPERATOR_REGEXP_FULL>(str, pattern);
}

const Expression* RegexpExtract(const Expression* const str,
                                const StringPiece& pattern) {
  return new RegexpExtractExpression(str, pattern);
}

const Expression* RegexpReplace(const Expression* const haystack,
                                const StringPiece& needle,
                                const Expression* const substitute) {
  return new RegexpReplaceExpression(haystack, needle, substitute);
}

}  // namespace supersonic


text:
package springfox.documentation.spring.web.plugins;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import springfox.documentation.RequestHandler;
import springfox.documentation.spi.service.RequestHandlerCombiner;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.*;
import static springfox.documentation.RequestHandler.*;
import static springfox.documentation.builders.BuilderDefaults.*;
import static springfox.documentation.spi.service.contexts.Orderings.byOperationName;
import static springfox.documentation.spi.service.contexts.Orderings.byPatternsCondition;

class DefaultRequestHandlerCombiner implements RequestHandlerCombiner {
  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRequestHandlerCombiner.class);
  private static final PathAndParametersEquivalence EQUIVALENCE = new PathAndParametersEquivalence();

  public List<RequestHandler> combine(List<RequestHandler> source) {
    List<RequestHandler> combined = new ArrayList<RequestHandler>();
    Map<String, List<RequestHandler>> byPath = new HashMap<>();
    LOGGER.debug("Total number of request handlers {}", nullToEmptyList(source).size());
    for (RequestHandler each : nullToEmptyList(source)) {
      String pathKey = sortedPaths(each.getPatternsCondition());
      LOGGER.debug("Adding key: {}, {}", pathKey, each.toString());
      byPath.putIfAbsent(pathKey, new ArrayList<>());
      byPath.get(pathKey).add(each);
    }
    for (String key : byPath.keySet()) {
      combined.addAll(combined(byPath.get(key)));
    }
    LOGGER.debug("Combined number of request handlers {}", combined.size());
    return combined.stream()
        .sorted(byPatternsCondition())
        .collect(toList());
  }

  private Collection<RequestHandler> combined(Collection<RequestHandler> requestHandlers) {
    List<RequestHandler> source = new ArrayList<>(requestHandlers);
    if (source.size() == 0 || source.size() == 1) {
      return requestHandlers;
    }
    Map<PathAndParametersEquivalence.Wrapper, List<RequestHandler>> groupByEquality = safeGroupBy(source);
    List<RequestHandler> combined = new ArrayList<>();
    groupByEquality.keySet().stream().sorted(wrapperComparator()).forEachOrdered(path -> {
      List<RequestHandler> handlers = groupByEquality.get(path);

      RequestHandler toCombine = path.get();
      if (handlers.size() > 1) {
        for (RequestHandler each : handlers) {
          if (each.equals(toCombine)) {
            continue;
          }
          //noinspection ConstantConditions
          LOGGER.debug("Combining {} and {}", toCombine.toString(), each.toString());
          toCombine = combine(toCombine, each);
        }
      }
      combined.add(toCombine);
    });
    return combined;
  }

  private Comparator<PathAndParametersEquivalence.Wrapper> wrapperComparator() {
    return (first, second) -> byPatternsCondition()
        .thenComparing(byOperationName())
        .compare(first.get(), second.get());
  }

  private Map<PathAndParametersEquivalence.Wrapper, List<RequestHandler>> safeGroupBy(
      List<RequestHandler> source) {
    try {
      return source.stream()
          .collect(groupingBy(EQUIVALENCE::wrap, LinkedHashMap::new, toList()));
    } catch (Exception e) {
      LOGGER.error("Unable to index request handlers {}. Request handlers with issues{}",
          e.getMessage(),
          keys(source));
      return Collections.emptyMap();
    }
  }

  private String keys(List<RequestHandler> source) {
    final StringBuilder sb = new StringBuilder("Request Handlers with duplicate keys {");
    for (int i = 0; i < source.size(); i++) {
      sb.append('\t')
          .append(i)
          .append(". ")
          .append(source.get(i).key());
    }
    sb.append('}');
    return sb.toString();
  }

  private RequestHandler combine(RequestHandler first, RequestHandler second) {
    if (first.compareTo(second) < 0) {
      return new CombinedRequestHandler(first, second);
    }
    return new CombinedRequestHandler(second, first);
  }
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">

		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
		<title>Apache MINA 2.0.0-RC1 Cross Reference Package org.apache.mina.handler.chain</title>
		<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="style" />

        	org.apache.mina.handler.chain

Classes

            	ChainedIoHandler

            	Entry

            	IoHandlerChain

            	IoHandlerCommand

            	NextCommand