<commit_before>/**
 * @fileoverview Base JS file for pages that want to parse the results JSON
 * from the testing bots. This deals with generic utility functions, visible
 * history, popups and appending the script elements for the JSON files.
 *
 * The calling page is expected to implement three "abstract" functions/objects.
 * generatePage, validateHashParameter and defaultStateValues.
 */
 var pageLoadStartTime = Date.now();

/**
 * Generates the contents of the dashboard. The page should override this with
 * a function that generates the page assuming all resources have loaded.
 */
 function generatePage() {
}

/**
 * Takes a key and a value and sets the currentState[key] = value iff key is
 * a valid hash parameter and the value is a valid value for that key.
 *
 * @return {boolean} Whether the key what inserted into the currentState.
 */
function handleValidHashParameter(key, value) {
  return false;
}

/**
 * Default hash parameters for the page. The page should override this to create
 * default states.
 */
var defaultStateValues = {};

//////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////
var EXPECTATIONS_MAP = {
  'T': 'TIMEOUT',
  'C': 'CRASH',
  'P': 'PASS',
  'F': 'TEXT FAIL',
  'S': 'SIMPLIFIED',
  'I': 'IMAGE',
  'O': 'OTHER',
  'N': 'NO DATA',
  'X': 'SKIP'
};

// Keys in the JSON files.
var WONTFIX_COUNTS_KEY = 'wontfixCounts';
var FIXABLE_COUNTS_KEY = 'fixableCounts';
var DEFERRED_COUNTS_KEY = 'deferredCounts';
var WONTFIX_DESCRIPTION = 'Tests never to be fixed (WONTFIX)';
var FIXABLE_DESCRIPTION = 'All tests for this release';
var DEFERRED_DESCRIPTION = 'All deferred tests (DEFER)';
var FIXABLE_COUNT_KEY = 'fixableCount';
var ALL_FIXABLE_COUNT_KEY = 'allFixableCount';
var CHROME_REVISIONS_KEY = 'chromeRevision';
var WEBKIT_REVISIONS_KEY = 'webkitRevision';

/**
 * Takes a key and a value and sets the currentState[key] = value iff key is
 * a valid hash parameter and the value is a valid value for that key. Handles
 * cross-dashboard parameters then falls back to calling
 * handleValidHashParameter for dashboard-specific parameters.
 *
 * @return {boolean} Whether the key what inserted into the currentState.
 */
function handleValidHashParameterWrapper(key, value) {
  switch(key) {
    case 'testType':
      validateParameter(currentState, key, value,
          function() {
            return isValidName(value);
          });

      return true;

    case 'debug':
      currentState[key] = value == 'true';

      return true;

    default:
      return handleValidHashParameter(key, value);
  }
}

var defaultCrossDashboardStateValues = {
  testType: 'layout_test_results',
  debug: false
}

// Generic utility functions.
function $(id) {
  return document.getElementById(id);
}

function stringContains(a, b) {
  return a.indexOf(b) != -1;
}

function startsWith(a, b) {
  return a.indexOf(b) == 0;
}

function isValidName(str) {
  return str.match(/[A-Za-z0-9\-\_,]/);
}

function trimString(str) {
  return str.replace(/^\s+|\s+$/g, '');
}

/**
 * Naive check that path points to a directory.
 */
function isDirectory(path) {
  return !stringContains(path, '.')
}

function validateParameter(state, key, value, validateFn) {
  if (validateFn()) {
    state[key] = value;
  } else {
    console.log(key + ' value is not valid: ' + value);
  }
}

/**
 * Parses a string (e.g. window.location.hash) and calls
 * validValueHandler(key, value) for each key-value pair in the string.
 */
function parseParameters(parameterStr, validValueHandler) {
  var params = parameterStr.split('&');
  var invalidKeys = [];
  for (var i = 0; i < params.length; i++) {
    var thisParam = params[i].split('=');
    if (thisParam.length != 2) {
      console.log('Invalid query parameter: ' + params[i]);
      continue;
    }

    var key = thisParam[0];
    var value = decodeURIComponent(thisParam[1]);
    if (!validValueHandler(key, value))
      invalidKeys.push(key + '=' + value);
  }

  if (invalidKeys.length)
    console.log("Invalid query parameters: " + invalidKeys.join(','));
}

function fillMissingValues(to, from) {
  for (var state in from) {
    if (!(state in to))
      to[state] = from[state];
  }
}

function parseAllParameters() {
  saveStoredWindowLocation();
  parseParameters(window.location.hash.substring(1),
      handleValidHashParameterWrapper);
  fillMissingValues(currentState, defaultCrossDashboardStateValues);
  fillMissingValues(currentState, defaultStateValues);
}

// Keep the location around for detecting changes to hash arguments
// manually typed into the URL bar.
var oldLocation;
function saveStoredWindowLocation() {
  oldLocation = window.location.href;
}

function appendScript(path) {
  var script = document.createElement('script');
  script.src = path;
  document.getElementsByTagName('head')[0].appendChild(script);
}

// Permalinkable state of the page.
var currentState = {};

// Parse cross-dashboard parameters before using them.
parseAllParameters();

if (currentState.debug) {
  // In debug mode point to the results.json and expectations.json in the
  // local tree. Useful for debugging changes to the python JSON generator.
  var builders = {'DUMMY_BUILDER_NAME': ''};
  var builderBase = '../../Debug/';
} else {
  // Map of builderName (the name shown in the waterfall)
  // to builderPath (the path used in the builder's URL)
  // TODO(ojan): Make this switch based off of the testType.
  var builders = {
    'Webkit': 'webkit-rel',
    'Webkit (dbg)(1)': 'webkit-dbg-1',
    'Webkit (dbg)(2)': 'webkit-dbg-2',
    'Webkit (dbg)(3)': 'webkit-dbg-3',
    'Webkit Linux': 'webkit-rel-linux',
    'Webkit Linux (dbg)(1)': 'webkit-dbg-linux-1',
    'Webkit Linux (dbg)(2)': 'webkit-dbg-linux-2',
    'Webkit Linux (dbg)(3)': 'webkit-dbg-linux-3',
    'Webkit Mac10.5': 'webkit-rel-mac5',
    'Webkit Mac10.5 (dbg)(1)': 'webkit-dbg-mac5-1',
    'Webkit Mac10.5 (dbg)(2)': 'webkit-dbg-mac5-2',
    'Webkit Mac10.5 (dbg)(3)': 'webkit-dbg-mac5-3'
  };
  var builderBase = 'http://build.chromium.org/buildbot/';
}

// Append JSON script elements.
var resultsByBuilder = {};
var expectationsByTest = {};
function ADD_RESULTS(builds) {
  for (var builderName in builds) {
    if (builderName != 'version')
      resultsByBuilder[builderName] = builds[builderName];
  }

  handleLocationChange();
}

function getPathToBuilderResultsFile(builderName) {
  return builderBase + currentState['testType'] + '/' +
      builders[builderName] + '/';
}

var expectationsLoaded = false;
function ADD_EXPECTATIONS(expectations) {
  expectationsLoaded = true;
  expectationsByTest = expectations;
  handleLocationChange();
}

function appendJSONScriptElements() {
  parseAllParameters();

  for (var builderName in builders) {
    appendScript(getPathToBuilderResultsFile(builderName) + 'results.json');
  }

  // Grab expectations file from any builder.
  appendScript(getPathToBuilderResultsFile(builderName) + 'expectations.json');
}

function setLoadingUIDisplayStyle(value) {
  if ($('loading-ui'))
    $('loading-ui').style.display = value;
}

function handleLocationChange() {
  setLoadingUIDisplayStyle('block');
  setTimeout(function() {
    saveStoredWindowLocation();
    parseAllParameters();

    if (!expectationsLoaded)
      return;

    for (var build in builders) {
      if (!resultsByBuilder[build])
        return;
    }

    generatePage();

    setLoadingUIDisplayStyle('none');
  }, 0);
}

/**
 * Sets the page state. Takes varargs of key, value pairs.
 *
 * @return list of keys modified
 */
function setQueryParameter(key, value) {
  var keys = [];
  for (var i = 0; i < arguments.length; i += 2) {
    var key = arguments[i];
    keys.push(key);
    currentState[key] = arguments[i + 1];
  }
  window.location.replace(getPermaLinkURL());
  saveStoredWindowLocation();
  return keys;
}

function getPermaLinkURL() {
  return window.location.pathname + '#' + joinParameters(currentState);
}

function joinParameters(stateObject) {
  var state = [];
  for (var key in stateObject) {
    state.push(key + '=' + encodeURIComponent(stateObject[key]));
  }
  return state.join('&');
}

function logTime(msg, startTime) {
  console.log(msg + ': ' + (Date.now() - startTime));
}

function hidePopup() {
  var popup = $('popup');
  popup.parentNode.removeChild(popup);
}

function showPopup(e, html) {
  var popup = $('popup');
  if (!popup) {
    popup = document.createElement('div');
    popup.id = 'popup';
    document.body.appendChild(popup);
  }

  // Set html first so that we can get accurate size metrics on the popup.
  popup.innerHTML = html;

  var targetRect = e.target.getBoundingClientRect();

  var x = Math.min(targetRect.left - 10,
      document.documentElement.clientWidth - popup.offsetWidth);
  x = Math.max(0, x);
  popup.style.left = x + document.body.scrollLeft + 'px';

  var y = targetRect.top + targetRect.height;
  if (y + popup.offsetHeight > document.documentElement.clientHeight) {
    y = targetRect.top - popup.offsetHeight;
  }
  y = Math.max(0, y);
  popup.style.top = y + document.body.scrollTop + 'px';
}

appendJSONScriptElements();

document.addEventListener('mousedown', function(e) {
      // Clear the open popup, unless the click was inside the popup.
      var popup = $('popup');
      if (popup && e.target != popup &&
          !(popup.compareDocumentPosition(e.target) & 16)) {
        hidePopup();
      }
    }, false);

window.addEventListener('load', function() {
      // This doesn't seem totally accurate as there is a race between
      // onload firing and the last script tag being executed.
      logTime('Time to load JS', pageLoadStartTime);
      setInterval(function() {
        if (oldLocation != window.location.href)
          handleLocationChange();
      }, 100);
    }, false);
<commit_msg>Fix dashboard history management to properly start from a blank slate when converting the hash parameters to the currentState object. Review URL: http://codereview.chromium.org/242038<commit_after>/**
 * @fileoverview Base JS file for pages that want to parse the results JSON
 * from the testing bots. This deals with generic utility functions, visible
 * history, popups and appending the script elements for the JSON files.
 *
 * The calling page is expected to implement three "abstract" functions/objects.
 * generatePage, validateHashParameter and defaultStateValues.
 */
 var pageLoadStartTime = Date.now();

/**
 * Generates the contents of the dashboard. The page should override this with
 * a function that generates the page assuming all resources have loaded.
 */
 function generatePage() {
}

/**
 * Takes a key and a value and sets the currentState[key] = value iff key is
 * a valid hash parameter and the value is a valid value for that key.
 *
 * @return {boolean} Whether the key what inserted into the currentState.
 */
function handleValidHashParameter(key, value) {
  return false;
}

/**
 * Default hash parameters for the page. The page should override this to create
 * default states.
 */
var defaultStateValues = {};

//////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////
var EXPECTATIONS_MAP = {
  'T': 'TIMEOUT',
  'C': 'CRASH',
  'P': 'PASS',
  'F': 'TEXT FAIL',
  'S': 'SIMPLIFIED',
  'I': 'IMAGE',
  'O': 'OTHER',
  'N': 'NO DATA',
  'X': 'SKIP'
};

// Keys in the JSON files.
var WONTFIX_COUNTS_KEY = 'wontfixCounts';
var FIXABLE_COUNTS_KEY = 'fixableCounts';
var DEFERRED_COUNTS_KEY = 'deferredCounts';
var WONTFIX_DESCRIPTION = 'Tests never to be fixed (WONTFIX)';
var FIXABLE_DESCRIPTION = 'All tests for this release';
var DEFERRED_DESCRIPTION = 'All deferred tests (DEFER)';
var FIXABLE_COUNT_KEY = 'fixableCount';
var ALL_FIXABLE_COUNT_KEY = 'allFixableCount';
var CHROME_REVISIONS_KEY = 'chromeRevision';
var WEBKIT_REVISIONS_KEY = 'webkitRevision';

/**
 * Takes a key and a value and sets the currentState[key] = value iff key is
 * a valid hash parameter and the value is a valid value for that key. Handles
 * cross-dashboard parameters then falls back to calling
 * handleValidHashParameter for dashboard-specific parameters.
 *
 * @return {boolean} Whether the key what inserted into the currentState.
 */
function handleValidHashParameterWrapper(key, value) {
  switch(key) {
    case 'testType':
      validateParameter(currentState, key, value,
          function() {
            return isValidName(value);
          });

      return true;

    case 'debug':
      currentState[key] = value == 'true';

      return true;

    default:
      return handleValidHashParameter(key, value);
  }
}

var defaultCrossDashboardStateValues = {
  testType: 'layout_test_results',
  debug: false
}

// Generic utility functions.
function $(id) {
  return document.getElementById(id);
}

function stringContains(a, b) {
  return a.indexOf(b) != -1;
}

function startsWith(a, b) {
  return a.indexOf(b) == 0;
}

function isValidName(str) {
  return str.match(/[A-Za-z0-9\-\_,]/);
}

function trimString(str) {
  return str.replace(/^\s+|\s+$/g, '');
}

/**
 * Naive check that path points to a directory.
 */
function isDirectory(path) {
  return !stringContains(path, '.')
}

function validateParameter(state, key, value, validateFn) {
  if (validateFn()) {
    state[key] = value;
  } else {
    console.log(key + ' value is not valid: ' + value);
  }
}

/**
 * Parses window.location.hash and set the currentState values appropriately.
 */
function parseParameters(parameterStr) {
  saveStoredWindowLocation();
  currentState = {};

  var params = window.location.hash.substring(1).split('&');
  var invalidKeys = [];
  for (var i = 0; i < params.length; i++) {
    var thisParam = params[i].split('=');
    if (thisParam.length != 2) {
      console.log('Invalid query parameter: ' + params[i]);
      continue;
    }

    var key = thisParam[0];
    var value = decodeURIComponent(thisParam[1]);
    if (!handleValidHashParameterWrapper(key, value))
      invalidKeys.push(key + '=' + value);
  }

  if (invalidKeys.length)
    console.log("Invalid query parameters: " + invalidKeys.join(','));

  fillMissingValues(currentState, defaultCrossDashboardStateValues);
  fillMissingValues(currentState, defaultStateValues);
}

function fillMissingValues(to, from) {
  for (var state in from) {
    if (!(state in to))
      to[state] = from[state];
  }
}

// Keep the location around for detecting changes to hash arguments
// manually typed into the URL bar.
var oldLocation;
function saveStoredWindowLocation() {
  oldLocation = window.location.href;
}

function appendScript(path) {
  var script = document.createElement('script');
  script.src = path;
  document.getElementsByTagName('head')[0].appendChild(script);
}

// Permalinkable state of the page.
var currentState;

// Parse cross-dashboard parameters before using them.
parseParameters();

if (currentState.debug) {
  // In debug mode point to the results.json and expectations.json in the
  // local tree. Useful for debugging changes to the python JSON generator.
  var builders = {'DUMMY_BUILDER_NAME': ''};
  var builderBase = '../../Debug/';
} else {
  // Map of builderName (the name shown in the waterfall)
  // to builderPath (the path used in the builder's URL)
  // TODO(ojan): Make this switch based off of the testType.
  var builders = {
    'Webkit': 'webkit-rel',
    'Webkit (dbg)(1)': 'webkit-dbg-1',
    'Webkit (dbg)(2)': 'webkit-dbg-2',
    'Webkit (dbg)(3)': 'webkit-dbg-3',
    'Webkit Linux': 'webkit-rel-linux',
    'Webkit Linux (dbg)(1)': 'webkit-dbg-linux-1',
    'Webkit Linux (dbg)(2)': 'webkit-dbg-linux-2',
    'Webkit Linux (dbg)(3)': 'webkit-dbg-linux-3',
    'Webkit Mac10.5': 'webkit-rel-mac5',
    'Webkit Mac10.5 (dbg)(1)': 'webkit-dbg-mac5-1',
    'Webkit Mac10.5 (dbg)(2)': 'webkit-dbg-mac5-2',
    'Webkit Mac10.5 (dbg)(3)': 'webkit-dbg-mac5-3'
  };
  var builderBase = 'http://build.chromium.org/buildbot/';
}

// Append JSON script elements.
var resultsByBuilder = {};
var expectationsByTest = {};
function ADD_RESULTS(builds) {
  for (var builderName in builds) {
    if (builderName != 'version')
      resultsByBuilder[builderName] = builds[builderName];
  }

  handleLocationChange();
}

function getPathToBuilderResultsFile(builderName) {
  return builderBase + currentState['testType'] + '/' +
      builders[builderName] + '/';
}

var expectationsLoaded = false;
function ADD_EXPECTATIONS(expectations) {
  expectationsLoaded = true;
  expectationsByTest = expectations;
  handleLocationChange();
}

function appendJSONScriptElements() {
  parseParameters();

  for (var builderName in builders) {
    appendScript(getPathToBuilderResultsFile(builderName) + 'results.json');
  }

  // Grab expectations file from any builder.
  appendScript(getPathToBuilderResultsFile(builderName) + 'expectations.json');
}

function setLoadingUIDisplayStyle(value) {
  if ($('loading-ui'))
    $('loading-ui').style.display = value;
}

function handleLocationChange() {
  setLoadingUIDisplayStyle('block');
  setTimeout(function() {
    saveStoredWindowLocation();
    parseParameters();

    if (!expectationsLoaded)
      return;

    for (var build in builders) {
      if (!resultsByBuilder[build])
        return;
    }

    generatePage();

    setLoadingUIDisplayStyle('none');
  }, 0);
}

/**
 * Sets the page state. Takes varargs of key, value pairs.
 *
 * @return list of keys modified
 */
function setQueryParameter(key, value) {
  var keys = [];
  for (var i = 0; i < arguments.length; i += 2) {
    var key = arguments[i];
    keys.push(key);
    currentState[key] = arguments[i + 1];
  }
  window.location.replace(getPermaLinkURL());
  saveStoredWindowLocation();
  return keys;
}

function getPermaLinkURL() {
  return window.location.pathname + '#' + joinParameters(currentState);
}

function joinParameters(stateObject) {
  var state = [];
  for (var key in stateObject) {
    state.push(key + '=' + encodeURIComponent(stateObject[key]));
  }
  return state.join('&');
}

function logTime(msg, startTime) {
  console.log(msg + ': ' + (Date.now() - startTime));
}

function hidePopup() {
  var popup = $('popup');
  popup.parentNode.removeChild(popup);
}

function showPopup(e, html) {
  var popup = $('popup');
  if (!popup) {
    popup = document.createElement('div');
    popup.id = 'popup';
    document.body.appendChild(popup);
  }

  // Set html first so that we can get accurate size metrics on the popup.
  popup.innerHTML = html;

  var targetRect = e.target.getBoundingClientRect();

  var x = Math.min(targetRect.left - 10,
      document.documentElement.clientWidth - popup.offsetWidth);
  x = Math.max(0, x);
  popup.style.left = x + document.body.scrollLeft + 'px';

  var y = targetRect.top + targetRect.height;
  if (y + popup.offsetHeight > document.documentElement.clientHeight) {
    y = targetRect.top - popup.offsetHeight;
  }
  y = Math.max(0, y);
  popup.style.top = y + document.body.scrollTop + 'px';
}

appendJSONScriptElements();

document.addEventListener('mousedown', function(e) {
      // Clear the open popup, unless the click was inside the popup.
      var popup = $('popup');
      if (popup && e.target != popup &&
          !(popup.compareDocumentPosition(e.target) & 16)) {
        hidePopup();
      }
    }, false);

window.addEventListener('load', function() {
      // This doesn't seem totally accurate as there is a race between
      // onload firing and the last script tag being executed.
      logTime('Time to load JS', pageLoadStartTime);
      setInterval(function() {
        if (oldLocation != window.location.href)
          handleLocationChange();
      }, 100);
    }, false);
<|endoftext|>


<commit_before>import { createSynth as Synth, createSequencer as Seq } from 'sound-engine';
import {expect} from 'chai';
import sinon from 'sinon';

const audio_context_methods = [
	'createOscillator' // TODO: complete
];

function createAudioContextMock() {
	return audio_context_methods.reduce((mock, method) => Object.assign(
		mock,
		{[method]: sinon.spy()}
	), {
		currentTime: 0
	});
}

describe('createSynth(audio_context)',()=>{
	it('creates and return a new Synth object', () => {
		const synth = Synth(createAudioContextMock());
		expect(synth).to.be.an('object');
	});
});

describe('createSequencer(audio_context)',()=>{
	it('creates and return a new Sequencer object', () => {
		const seq = Seq(createAudioContextMock());
		expect(seq).to.be.an('object');
	});
});
<commit_msg>fix test<commit_after>import {Synth, Seq} from 'sound';
import {expect} from 'chai';
import sinon from 'sinon';

const audio_context_methods = [
	'createOscillator' // TODO: complete
];

function createAudioContextMock() {
	return audio_context_methods.reduce((mock, method) => Object.assign(
		mock,
		{[method]: sinon.spy()}
	), {
		currentTime: 0
	});
}

describe('createSynth(audio_context)',()=>{
	it('creates and return a new Synth object', () => {
		const synth = Synth(createAudioContextMock());
		expect(synth).to.be.an('object');
	});
});

describe('createSequencer(audio_context)',()=>{
	it('creates and return a new Sequencer object', () => {
		const synth = Synth(createAudioContextMock());
		const seq = Seq(createAudioContextMock(), {slave:synth});
		expect(seq).to.be.an('object');
	});
});
<|endoftext|>


<commit_before>// @flow

import React, { Fragment, useContext, useEffect } from 'react';
import { BridgeContext } from './context';
import { ModalDialogContext } from './ModalDialog';

import styles from './WarnIfLegacyBackendDetected.css';

export default function WarnIfLegacyBackendDetected(_: {||}) {
  const bridge = useContext(BridgeContext);
  const { dispatch } = useContext(ModalDialogContext);

  // Detect pairing with legacy v3 backend.
  // We do this by listening to a message that it broadcasts but the v4 backend doesn't.
  // In this case the frontend should show upgrade instructions.
  useEffect(() => {
    // Wall.listen returns a cleanup function
    let unlisten = bridge.wall.listen(event => {
      switch (event.type) {
        case 'call':
        case 'event':
        case 'many-events':
          // Any of these types indicate the v3 backend.
          dispatch({
            canBeDismissed: false,
            type: 'SHOW',
            title:
              'DevTools v4 is incompatible with this version of React',
            content: <InvalidBackendDetected />,
          });

          if (typeof unlisten === 'function') {
            unlisten();
            unlisten = null;
          }
          break;
        default:
          break;
      }
    });

    return () => {
      if (typeof unlisten === 'function') {
        unlisten();
        unlisten = null;
      }
    };
  }, [bridge, dispatch]);

  return null;
}

function InvalidBackendDetected(_: {||}) {
  return (
    <Fragment>

Either upgrade React or install React DevTools v3:

      npm install -d react-devtools@^3
    </Fragment>
  );
}
<commit_msg>Make my code PRETTIER<commit_after>// @flow

import React, { Fragment, useContext, useEffect } from 'react';
import { BridgeContext } from './context';
import { ModalDialogContext } from './ModalDialog';

import styles from './WarnIfLegacyBackendDetected.css';

export default function WarnIfLegacyBackendDetected(_: {||}) {
  const bridge = useContext(BridgeContext);
  const { dispatch } = useContext(ModalDialogContext);

  // Detect pairing with legacy v3 backend.
  // We do this by listening to a message that it broadcasts but the v4 backend doesn't.
  // In this case the frontend should show upgrade instructions.
  useEffect(() => {
    // Wall.listen returns a cleanup function
    let unlisten = bridge.wall.listen(event => {
      switch (event.type) {
        case 'call':
        case 'event':
        case 'many-events':
          // Any of these types indicate the v3 backend.
          dispatch({
            canBeDismissed: false,
            type: 'SHOW',
            title: 'DevTools v4 is incompatible with this version of React',
            content: <InvalidBackendDetected />,
          });

          if (typeof unlisten === 'function') {
            unlisten();
            unlisten = null;
          }
          break;
        default:
          break;
      }
    });

    return () => {
      if (typeof unlisten === 'function') {
        unlisten();
        unlisten = null;
      }
    };
  }, [bridge, dispatch]);

  return null;
}

function InvalidBackendDetected(_: {||}) {
  return (
    <Fragment>

Either upgrade React or install React DevTools v3:

      npm install -d react-devtools@^3
    </Fragment>
  );
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('hexo-fs');
const pathFn = require('path');
const Promise = require('bluebird');

describe('render', () => {
  const Hexo = require('../../../lib/hexo');
  const hexo = new Hexo(pathFn.join(__dirname, 'render_test'), {silent: true});
  const render = require('../../../lib/plugins/console/render').bind(hexo);

  before(() => fs.mkdirs(hexo.base_dir).then(() => hexo.init()));

  after(() => fs.rmdir(hexo.base_dir));

  const body = [
    'foo: 1',
    'bar:',
    '  boo: 2'
  ].join('\n');

  it('relative path', () => {
    const src = pathFn.join(hexo.base_dir, 'test.yml');
    const dest = pathFn.join(hexo.base_dir, 'result.json');

    return fs.writeFile(src, body).then(() => render({_: ['test.yml'], output: 'result.json'})).then(() => fs.readFile(dest)).then(result => {
      JSON.parse(result).should.eql({
        foo: 1,
        bar: {
          boo: 2
        }
      });

      return Promise.all([
        fs.unlink(src),
        fs.unlink(dest)
      ]);
    });
  });

  it('absolute path', () => {
    const src = pathFn.join(hexo.base_dir, 'test.yml');
    const dest = pathFn.join(hexo.base_dir, 'result.json');

    return fs.writeFile(src, body).then(() => render({_: [src], output: 'result.json'})).then(() => fs.readFile(dest)).then(result => {
      JSON.parse(result).should.eql({
        foo: 1,
        bar: {
          boo: 2
        }
      });

      return Promise.all([
        fs.unlink(src),
        fs.unlink(dest)
      ]);
    });
  });

  it('absolute output', () => {
    const src = pathFn.join(hexo.base_dir, 'test.yml');
    const dest = pathFn.join(hexo.base_dir, 'result.json');

    return fs.writeFile(src, body).then(() => render({_: ['test.yml'], output: dest})).then(() => fs.readFile(dest)).then(result => {
      JSON.parse(result).should.eql({
        foo: 1,
        bar: {
          boo: 2
        }
      });

      return Promise.all([
        fs.unlink(src),
        fs.unlink(dest)
      ]);
    });
  });

  // it('output'); missing-unit-test

  it('engine', () => {
    const src = pathFn.join(hexo.base_dir, 'test');
    const dest = pathFn.join(hexo.base_dir, 'result.json');

    return fs.writeFile(src, body).then(() => render({_: ['test'], output: 'result.json', engine: 'yaml'})).then(() => fs.readFile(dest)).then(result => {
      JSON.parse(result).should.eql({
        foo: 1,
        bar: {
          boo: 2
        }
      });

      return Promise.all([
        fs.unlink(src),
        fs.unlink(dest)
      ]);
    });
  });

  it('pretty', () => {
    const src = pathFn.join(hexo.base_dir, 'test.yml');
    const dest = pathFn.join(hexo.base_dir, 'result.json');

    return fs.writeFile(src, body).then(() => render({_: ['test.yml'], output: 'result.json', pretty: true})).then(() => fs.readFile(dest)).then(result => {
      result.should.eql(JSON.stringify({
        foo: 1,
        bar: {
          boo: 2
        }
      }, null, '  '));

      return Promise.all([
        fs.unlink(src),
        fs.unlink(dest)
      ]);
    });
  });
});
<commit_msg>refactor(test-console-render): destructure & async/await (#3980)<commit_after>'use strict';

const { mkdirs, readFile, rmdir, unlink, writeFile } = require('hexo-fs');
const { join } = require('path');
const Promise = require('bluebird');

describe('render', () => {
  const Hexo = require('../../../lib/hexo');
  const hexo = new Hexo(join(__dirname, 'render_test'), {silent: true});
  const render = require('../../../lib/plugins/console/render').bind(hexo);

  before(async () => {
    await mkdirs(hexo.base_dir);
    hexo.init();
  });

  after(() => rmdir(hexo.base_dir));

  const body = [
    'foo: 1',
    'bar:',
    '  boo: 2'
  ].join('\n');

  it('relative path', async () => {
    const src = join(hexo.base_dir, 'test.yml');
    const dest = join(hexo.base_dir, 'result.json');

    await writeFile(src, body);
    await render({_: ['test.yml'], output: 'result.json'});
    const result = await readFile(dest);
    JSON.parse(result).should.eql({
      foo: 1,
      bar: {
        boo: 2
      }
    });

    await Promise.all([
      unlink(src),
      unlink(dest)
    ]);
  });

  it('absolute path', async () => {
    const src = join(hexo.base_dir, 'test.yml');
    const dest = join(hexo.base_dir, 'result.json');

    await writeFile(src, body);
    await render({_: [src], output: 'result.json'});

    const result = await readFile(dest);
    JSON.parse(result).should.eql({
      foo: 1,
      bar: {
        boo: 2
      }
    });

    await Promise.all([
      unlink(src),
      unlink(dest)
    ]);
  });

  it('absolute output', async () => {
    const src = join(hexo.base_dir, 'test.yml');
    const dest = join(hexo.base_dir, 'result.json');

    await writeFile(src, body);
    await render({_: ['test.yml'], output: dest});

    const result = await readFile(dest);
    JSON.parse(result).should.eql({
      foo: 1,
      bar: {
        boo: 2
      }
    });

    await Promise.all([
      unlink(src),
      unlink(dest)
    ]);
  });

  // it('output'); missing-unit-test

  it('engine', async () => {
    const src = join(hexo.base_dir, 'test');
    const dest = join(hexo.base_dir, 'result.json');

    await writeFile(src, body);
    await render({_: ['test'], output: 'result.json', engine: 'yaml'});

    const result = await readFile(dest);
    JSON.parse(result).should.eql({
      foo: 1,
      bar: {
        boo: 2
      }
    });

    await Promise.all([
      unlink(src),
      unlink(dest)
    ]);
  });

  it('pretty', async () => {
    const src = join(hexo.base_dir, 'test.yml');
    const dest = join(hexo.base_dir, 'result.json');

    await writeFile(src, body);
    await render({_: ['test.yml'], output: 'result.json', pretty: true});

    const result = await readFile(dest);
    result.should.eql(JSON.stringify({
      foo: 1,
      bar: {
        boo: 2
      }
    }, null, '  '));

    await Promise.all([
      unlink(src),
      unlink(dest)
    ]);
  });
});
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular.module('app.components')
    .component('detailReveal', {
      controller: ComponentController,
      controllerAs: 'vm',
      bindings: {
        title: '@',
        detail: '@',
        icon: '@',
        translateTitle: '=',
        rowClass: '@',
      },
      transclude: true,
      templateUrl: 'app/components/detail-reveal/detail-reveal.html',
    });

  /** @ngInject */
  function ComponentController($transclude) {
    var vm = this;
    vm.$onInit = activate();

    function activate() {
      vm.translateTitle = (angular.isUndefined(vm.translateTitle) ? true : vm.translateTitle);
      vm.title = (vm.translateTitle === true ? __(vm.title) : vm.title);
      vm.rowClass = (angular.isDefined(vm.rowClass) ? vm.rowClass : 'row detail-row');
      vm.toggleDetails = false;
      vm.hasMoreDetails = $transclude().length > 0;
    }
  }
})();
<commit_msg>fixed warning<commit_after>(function() {
  'use strict';

  angular.module('app.components')
    .component('detailReveal', {
      controller: ComponentController,
      controllerAs: 'vm',
      bindings: {
        title: '@',
        detail: '@',
        icon: '@',
        translateTitle: '<',
        rowClass: '@',
      },
      transclude: true,
      templateUrl: 'app/components/detail-reveal/detail-reveal.html',
    });

  /** @ngInject */
  function ComponentController($transclude) {
    var vm = this;
    vm.$onInit = activate();

    function activate() {
      vm.translateTitle = (angular.isUndefined(vm.translateTitle) ? true : vm.translateTitle);
      vm.title = (vm.translateTitle === true ? __(vm.title) : vm.title);
      vm.rowClass = (angular.isDefined(vm.rowClass) ? vm.rowClass : 'row detail-row');
      vm.toggleDetails = false;
      vm.hasMoreDetails = $transclude().length > 0;
    }
  }
})();
<|endoftext|>


<commit_before>Ti.include('/util.js');
Ti.include('/data.js');
Ti.include('/eventHandler.js');
(function (window, tab) {
  var createEvent, settings, clubLabel, club, requery, isRequerying, table, options, ID, allEvents;

  ID = "EVENT_OPTIONS";
  options = Data.load(ID, Util.createSet(Data.getUserClubs()));

  clubLabel = Ti.UI.createLabel({
  	top:5, left:5, text:'From Club:'
  });
  window.add(clubLabel);

  club = Ti.UI.createTextField({
  	top:5, left:100, height: 30, width:130,
  	borderWidth: 1, borderColor: '#bbb', borderRadius: 3
  });
  window.add(club);

  club.addEventListener('focus',function(event){
    var viewEvent = Ti.UI.createWindow({
      url: '/windows/pickerWindow.js',
      opacity: 0
    });
    viewEvent.addEventListener('save', function (result) {
      club.value = result.data;
      if (club.getValue() === "All"){
      	options = Data.load(ID, Util.createSet(Data.getUserClubs()));
      }else{
      	options = Util.createSet([club.getValue()]);
      }
      Ti.API.log(options);
      requery();
    });
    viewEvent.addEventListener('close', function () {
      viewEvent.close({ opacity: 0, duration: 500 });
    });
    viewEvent.addEventListener('open', function () {
      var titles = Util.keys(Data.getUserClubs());
      titles.unshift("All");

      var add = Util.foreach(titles, function (_, title) {
        return Ti.UI.createPickerRow({ title: title });
      });

      viewEvent.fireEvent('data', {
        data: {
          type:'club',
          add:add
        }
      });
      viewEvent.animate({
        opacity: 1,
        duration: 500
      });
    });
    viewEvent.open();
  });

  table = Ti.UI.createTableView({top:35});
  table.addEventListener('click', function (event) {
    if (!(event.index in allEvents)) return;
    var eventData = allEvents[event.index];
    var viewEvent = Ti.UI.createWindow({
      url: '/windows/view_event.js'
    });
    viewEvent.addEventListener('open', function () {
      viewEvent.fireEvent('data', {
        data: eventData
      });
    });
    tab.open(viewEvent);
    // viewEvent.open();
  });
  window.add(table);

  isRequerying = false;
  requery = function () {
    // Ti.API.info("REQUERYING!");
    if (isRequerying) return;
    isRequerying = true;

    Ti.API.log('options', options);

    Events.queryClub(options, function (events) {
      allEvents = events;
    	table.data = Util.foreach(events, function (index, event) {
    		return Ti.UI.createTableViewRow({ title: event.name, height: 40 });
    	});
    	isRequerying = false;
    });
  };

  //requery();

  createEvent = Ti.UI.createButton({
    title: "New Event"
  });
  createEvent.addEventListener('click', function () {
    var newEvent;
    newEvent = Ti.UI.createWindow({ url: '/windows/new_event.js' });
    newEvent.open({ transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT });
    newEvent.addEventListener('close', function () {
      requery();
    });
  });
  window.addEventListener('focus', function () {
    window.rightNavButton = Util.isEmptyObject(Data.getUserClubs()) ? undefined : createEvent;
    requery();
  });

  settings = (window.leftNavButton = Ti.UI.createButton({
    title: "Options",
    style: Ti.UI.iPhone.SystemButtonStyle.BORDERED
  }));
  settings.addEventListener('click', function () {
    Ti.UI.createWindow({
      url: '/windows/event_options.js',
      modal: true,
      onchange: requery
    }).open();
  });

  // clubsView = createEventsClubs();
  //   mineView = createEventsMine();
  //
  //   scrollableView = Ti.UI.createScrollableView({
  //     views: [clubsView, mineView],
  //     bottom: 0
  //   });
  //   scrollableView.addEventListener('scroll', function (event) {
  //     Util.foreach(toolbarButtons, function (_, btn) {
  //       btn.backgroundColor = '#fff'; //.style = Ti.UI.iPhone.SystemButtonStyle.BORDERED; //enabled = true;
  //     });
  //     toolbarButtons[event.currentPage].backgroundColor = '#000'; //.style = Ti.UI.iPhone.SystemButtonStyle.DONE; //enabled = false;
  //   });
  //
  //   var toolbarButtons = [];
  //   window.toolbar = Util.foreach([
  //     { type: 'button', title: 'Subscribed Events', index: 0 },
  //     { type: 'space' },
  //     { type: 'button', title: 'View My Events', index: 1 }
  //   ], function (_, item) {
  //     var view;
  //     if (item.type === 'button') {
  //       view = Ti.UI.createButton({
  //         title: item.title,
  //         style: Ti.UI.iPhone.SystemButtonStyle.BORDERED,
  //         selectedColor: '#123',
  //         backgroundColor: '#fff'
  //       });
  //       view.addEventListener('click', function () {
  //         scrollableView.scrollToView(item.index);
  //       });
  //       toolbarButtons.push(view);
  //     } else if (item.type === 'space') {
  //       view = Ti.UI.createButton({
  //         systemButton: Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
  //       });
  //     }
  //     return view;
  //   });
  //   toolbarButtons[0].backgroundColor = '#000'; // = Ti.UI.iPhone.SystemButtonStyle.DONE; //.enabled = false;
  //
  //   // switchBar = Ti.UI.iOS.createTabbedBar({
  //   //   labels: ['Clubs', 'Mine'],
  //   //   backgroundColor: '#336699',
  //   //   bottom: 0,
  //   //   height: 40,
  //   //   style: Titanium.UI.iPhone.SystemButtonStyle.PLAIN,
  //   //   width: 320
  //   // });
  //   // switchBar.addEventListener('click', function (event) {
  //   //   scrollableView.scrollToView(event.index);
  //   // });
  //
  //   window.add(scrollableView);

}).call(Ti.UI.currentWindow, Ti.UI.currentWindow, Ti.UI.currentTab);
<commit_msg>Refresh button, bottom toolbar. Button title doesn't update? Strange.<commit_after>Ti.include('/util.js');
Ti.include('/data.js');
Ti.include('/eventHandler.js');
(function (window, tab) {
  var createEvent, refresh, settings, clubpicker, clubLabel, club, requery, isRequerying, table, options, ID, allEvents;

  ID = "EVENT_OPTIONS";
  options = Data.load(ID, Util.createSet(Data.getUserClubs()));

  settings = (Ti.UI.createButton({
    title: "Options",
    style: Ti.UI.iPhone.SystemButtonStyle.BORDERED
  }));
  settings.addEventListener('click', function () {
    Ti.UI.createWindow({
      url: '/windows/event_options.js',
      modal: true,
      onchange: requery
    }).open();
  });

  (function () {
    var toolbar, space, label;
    label = Ti.UI.createLabel({
      text: 'Events for:', color: '#fff'
    });
    space = Ti.UI.createButton({ systemButton: Ti.UI.iPhone.SystemButton.FLEXIBLE_SPACE });
    club = Ti.UI.createButton({ title: 'Club: All', style: Ti.UI.iPhone.SystemButtonStyle.BORDERED });
    toolbar = Ti.UI.iOS.createToolbar({
      items: [club, space, settings],
      bottom: 0, left: 0, right: 0, barColor: Util.theme.darkColor
    });
    window.add(toolbar);

    club.addEventListener('click',function(event){
      var viewEvent = Ti.UI.createWindow({
        url: '/windows/pickerWindow.js',
        opacity: 0
      });
      viewEvent.addEventListener('save', function (result) {
        var value = result.data;
        club.updateLayout({ title: "Club: " + value });
        toolbar.items = toolbar.items;
        Ti.API.log(result);
        Ti.API.log(value);
        if (value === "All") {
        	options = Util.createSet(Data.getUserClubs());
        } else {
        	options = Util.createSet([value]);
        }
        Ti.API.log(options);
        requery();
      });
      viewEvent.addEventListener('close', function () { viewEvent.close({ opacity: 0, duration: 500 }); });
      viewEvent.addEventListener('open', function () {
        var titles = Util.keys(Data.getUserClubs());
        titles.unshift("All");

        var add = Util.foreach(titles, function (_, title) {
          return Ti.UI.createPickerRow({ title: title });
        });
        viewEvent.fireEvent('data', {
          data: {
            type:'club',
            add:add
          }
        });
        viewEvent.animate({
          opacity: 1,
          duration: 500
        });
      });
      viewEvent.open();
    });

  })();

  (function () {
    var clubview, titles, items;
    titles = Util.keys(Data.getUserClubs());
    titles.unshift("All");
    items = Util.foreach(titles, function (_, title) {
      return Ti.UI.createPickerRow({ title: title });
    });
    clubpicker = Ti.UI.createPicker({
      transform: Ti.UI.create2DMatrix().scale(0.5), width: 680,
      top: -59, selectionIndicator: true
    });
    clubpicker.add(items);

    clubview = Ti.UI.createView({
      top: 0, height: 88, left: 0, right: 0
    });
    clubview.add(clubpicker);
    window.add(clubview);
  });

  clubLabel = Ti.UI.createLabel({
  	top:5, left:5, text:'From Club:'
  });
  // window.add(clubLabel);

  club = Ti.UI.createTextField({
  	top:5, left:100, height: 30, width:130,
  	borderWidth: 1, borderColor: '#bbb', borderRadius: 3
  });
  // window.add(club);

  club.addEventListener('focus',function(event){
    var viewEvent = Ti.UI.createWindow({
      url: '/windows/pickerWindow.js',
      opacity: 0
    });
    viewEvent.addEventListener('save', function (result) {
      club.value = result.data;
      if (club.getValue() === "All"){
      	options = Data.load(ID, Util.createSet(Data.getUserClubs()));
      }else{
      	options = Util.createSet([club.getValue()]);
      }
      Ti.API.log(options);
      requery();
    });
    viewEvent.addEventListener('close', function () {
      viewEvent.close({ opacity: 0, duration: 500 });
    });
    viewEvent.addEventListener('open', function () {
      var titles = Util.keys(Data.getUserClubs());
      titles.unshift("All");

      var add = Util.foreach(titles, function (_, title) {
        return Ti.UI.createPickerRow({ title: title });
      });
      viewEvent.fireEvent('data', {
        data: {
          type:'club',
          add:add
        }
      });
      viewEvent.animate({
        opacity: 1,
        duration: 500
      });
    });
    viewEvent.open();
  });

  table = Ti.UI.createTableView({ top: 0, bottom: 41 });
  table.addEventListener('click', function (event) {
    if (!(event.index in allEvents)) return;
    var eventData = allEvents[event.index];
    var viewEvent = Ti.UI.createWindow({
      url: '/windows/view_event.js'
    });
    viewEvent.addEventListener('open', function () {
      viewEvent.fireEvent('data', {
        data: eventData
      });
    });
    tab.open(viewEvent);
    // viewEvent.open();
  });
  window.add(table);

  isRequerying = false;
  requery = function () {
    // Ti.API.info("REQUERYING!");
    if (isRequerying) return;
    isRequerying = true;

    Ti.API.log('options', options);

    Events.queryClub(options, function (events) {
      allEvents = events;
    	table.data = Util.foreach(events, function (index, event) {
    		return Ti.UI.createTableViewRow({ title: event.name, height: 40 });
    	});
    	isRequerying = false;
    });
  };

  //requery();

  createEvent = Ti.UI.createButton({
    title: "New Event"
  });
  createEvent.addEventListener('click', function () {
    var newEvent;
    newEvent = Ti.UI.createWindow({ url: '/windows/new_event.js' });
    newEvent.open({ transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT });
    newEvent.addEventListener('close', function () {
      requery();
    });
  });
  window.addEventListener('focus', function () {
    window.rightNavButton = Util.isEmptyObject(Data.getUserClubs()) ? undefined : createEvent;
    requery();
  });

  refresh = (window.leftNavButton = Ti.UI.createButton({
    title: "Refresh",
    style: Ti.UI.iPhone.SystemButtonStyle.BORDERED
  }));
  refresh.addEventListener('click', function () {
    requery();
  });

  // clubsView = createEventsClubs();
  //   mineView = createEventsMine();
  //
  //   scrollableView = Ti.UI.createScrollableView({
  //     views: [clubsView, mineView],
  //     bottom: 0
  //   });
  //   scrollableView.addEventListener('scroll', function (event) {
  //     Util.foreach(toolbarButtons, function (_, btn) {
  //       btn.backgroundColor = '#fff'; //.style = Ti.UI.iPhone.SystemButtonStyle.BORDERED; //enabled = true;
  //     });
  //     toolbarButtons[event.currentPage].backgroundColor = '#000'; //.style = Ti.UI.iPhone.SystemButtonStyle.DONE; //enabled = false;
  //   });
  //
  //   var toolbarButtons = [];
  //   window.toolbar = Util.foreach([
  //     { type: 'button', title: 'Subscribed Events', index: 0 },
  //     { type: 'space' },
  //     { type: 'button', title: 'View My Events', index: 1 }
  //   ], function (_, item) {
  //     var view;
  //     if (item.type === 'button') {
  //       view = Ti.UI.createButton({
  //         title: item.title,
  //         style: Ti.UI.iPhone.SystemButtonStyle.BORDERED,
  //         selectedColor: '#123',
  //         backgroundColor: '#fff'
  //       });
  //       view.addEventListener('click', function () {
  //         scrollableView.scrollToView(item.index);
  //       });
  //       toolbarButtons.push(view);
  //     } else if (item.type === 'space') {
  //       view = Ti.UI.createButton({
  //         systemButton: Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
  //       });
  //     }
  //     return view;
  //   });
  //   toolbarButtons[0].backgroundColor = '#000'; // = Ti.UI.iPhone.SystemButtonStyle.DONE; //.enabled = false;
  //
  //   // switchBar = Ti.UI.iOS.createTabbedBar({
  //   //   labels: ['Clubs', 'Mine'],
  //   //   backgroundColor: '#336699',
  //   //   bottom: 0,
  //   //   height: 40,
  //   //   style: Titanium.UI.iPhone.SystemButtonStyle.PLAIN,
  //   //   width: 320
  //   // });
  //   // switchBar.addEventListener('click', function (event) {
  //   //   scrollableView.scrollToView(event.index);
  //   // });
  //
  //   window.add(scrollableView);

}).call(Ti.UI.currentWindow, Ti.UI.currentWindow, Ti.UI.currentTab);
<|endoftext|>


<commit_before>export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
}

import '@instructure/canvas-theme'
<commit_msg>Add high contrast to storybook<commit_after>import React from 'react'
import {ApplyTheme} from '@instructure/ui-themeable'
import '@instructure/canvas-high-contrast-theme'
import '@instructure/canvas-theme'

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
}

export const globalTypes = {
  canvasTheme: {
    name: 'Canvas Theme',
    description: 'Default or High Contrast',
    defaultValue: 'canvas',
    toolbar: {
      icon: 'user',
      items: ['canvas', 'canvas-high-contrast']
    }
  }
}

const canvasThemeProvider = (Story, context) => {
  const canvasTheme = context.globals.canvasTheme
  return (
    <ApplyTheme theme={ApplyTheme.generateTheme(canvasTheme)}>
      <Story {...context}/>
    </ApplyTheme>
  )
}

export const decorators = [canvasThemeProvider]
<|endoftext|>


<commit_before>var game = function() {
	// Set up an instance of the Quintus engine and include
	// the Sprites, Scenes, Input and 2D module. The 2D module
	// includes the `TileLayer` class as well as the `2d` componet.
	var Q = window.Q = Quintus({ audioSupported: [ 'ogg', 'mp3' ]})
		 .include("Sprites, Scenes, Input, 2D, TMX, Anim, Touch, UI, Audio")
		 // Maximize this game to whatever the size of the browser is
		 .setup({ maximize: true })
		 // And turn on default input controls and touch input (for UI)
		 .controls().touch().enableSound();
	var levelwin = false;
	var currentLevel = 1;
	var lost = false;

	Q.state.set({coins: 0, lives: 3});
	Q.state.on("change.coins, change.lives", function(){Q.stageScene("HUD", 1, {label: "Lives: "+Q.state.get("lives")+"	Coins: "+Q.state.get("coins")});});

	Q.load(["mario_small.png","mario_small.json","bloopa.png", "mainTitle.png",
				"bloopa.json","goomba.png","goomba.json", "princess.png",
					"coin.png", "coin.json", "music_main.mp3", "coin.mp3", "music_die.mp3"], function(){
		Q.compileSheets("mario_small.png","mario_small.json");
		Q.compileSheets("bloopa.png","bloopa.json");
		Q.compileSheets("goomba.png","goomba.json");
		Q.compileSheets("coin.png", "coin.json");
		Q.audio.play("music_main.mp3",{ loop: true });
	});

	//------------MARIO
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Mario", {

	  init: function(p) {
		this._super(p, {
			sprite: "mario anim",
			sheet: "marioR",
			x: 150,
			y: 280,
			jumpSpeed: -500,
			dead: false
		});
		this.add('2d, platformerControls, animation');
	  },

	  step: function(dt) {
		if(this.p.y > 600 && !this.p.dead){
			this.death();
		}
		if(!this.p.dead){

			if(this.p.direction == "right"){
				if(this.p.vx != 0 && this.p.vy == 0){
					this.play("run_right");
				}else if (this.p.vy != 0){
					this.play("jump_right");
				}else {
					this.play("stand_right");
				}
			}
		}
	  },

	  death: function(){
		if(!levelwin && !this.p.dead)
			Q.audio.stop("");
			Q.audio.play("music_die.mp3");
			this.del('platformerControls');
			this.p.vx = 0;
			this.p.vy = -400;
			this.play("dead_"+this.p.direction);
			this.p.dead = true;
			var self = this;
			Q.state.inc("lives", -1);
			if(Q.state.get("lives")<0){
				lost = true;
				Q.stageScene("endGame", 1, {label: "GAME OVER"});
			}
			else{
				Q.stageScene("endGame", 1, {label: "You died"});
			}
			setTimeout(function(){self.destroy();}, 1000);
	  },

	});
	Q.animations('mario anim', {
		run_right: { frames: [1, 2, 3], rate: 1/10},
		run_left: { frames: [17, 16, 15], rate: 1/10 },
		stand_right: { frames: [0], rate: 1/5 },
		stand_left: { frames: [14], rate: 1/5 },
		jump_right: { frames: [4], rate: 1/5 },
		jump_left: { frames: [18], rate: 1/5 },
		dead_right: { frames: [12], rate: 1/5 },
		dead_left: { frames: [26], rate: 1/5 }
	});

	//------------PRINCESS
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Peach", {

	  init: function(p) {
		this._super( {
			asset: "princess.png",
			x: 9000,
			y: 500
		});
		this.add('2d');
		this.on("bump.left, bump.right, bump.top", this, "win");
	  },
	  win: function(collision){
		if(collision.obj.isA("Mario")){
			collision.obj.del('platformerControls');
			collision.obj.p.vx=0;
			levelwin = true;
			Q.stageScene("endGame", 1, {label: "You win this time..."});
		}
	  }

	});

	//------------DEFAULT ENEMY
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.component('defaultEnemy', {

		added: function() {
			this.entity.on("bump.left, bump.right", this.entity, "kill");
			this.entity.on("bump.top", this.entity, "stomp");
		},

		extend: {
			stomp: function(collision) {
				if(collision.obj.isA("Mario")) {
					this.play("die", 1);
					this.p.vx=0;
					this.p.vy=0;
					this.off("bump.bottom");
					var self = this;
					setTimeout(function(){self.destroy()}, 800);
					collision.obj.p.vy = -500; // make the player jump
				}
			},

			kill: function(collision) {
				if(collision.obj.isA("Mario")) {
					collision.obj.death();
				}
			}
		}
	});

	//------------BLOOPA
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Bloopa",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'bloopa anim',
				sheet: "bloopa",
				x: 350,
				y: 500,
				vx: 75,
				vy: -300,
				gravity: 0.4
			});
			this.add('2d, animation, aiBounce, defaultEnemy');
			this.on("bump.bottom", this, "jump");
		},

		jump: function(collision) {
			this.kill(collision);
			this.p.vy = -300;
			this.play("jump");
			var self = this;
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
			if(this.p.y > 600){
				this.destroy();
			}
		}
	});

	Q.animations('bloopa anim', {
		walk: { frames: [0], rate: 1},
		jump: { frames: [1], next: "walk", rate: 1/8},
		die: { frames: [2], rate: 1}
	});

	//------------GOOMBA
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Goomba",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'goomba anim',
				sheet: "goomba",
				vx: 150,
				x: 250,
				y: 500
			});
			this.add('2d, animation, aiBounce, defaultEnemy');
			this.on("bump.bottom", this, "kill");
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
			this.play("walk");
			if(this.p.y > 600){
				this.destroy();
			}
		}
	});

	Q.animations('goomba anim', {
		walk: { frames: [0, 1], rate: 1/4},
		die: { frames: [2/*, 3*/], rate: 1/1}
	});

	//------------COIN
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Coin",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'coin anim',
				sheet: 'coin',
				catched: false,
				sensor: true
			});
			this.add('animation, tween');
			this.on("hit", this, "getCoin");
		},

		getCoin: function(collision) {
			if(collision.obj.isA("Mario") && !this.p.catched) {
				Q.audio.stop('coin.mp3');
				Q.audio.play('coin.mp3');
				this.animate({x: this.p.x, y: this.p.y-100, opacity: 0}, 1, Q.Easing.Quadratic.Out);
				var self = this;
				setTimeout(function(){self.destroy()}, 1200);
				Q.state.inc("coins", 1);
				this.p.catched = true;
			}
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
		//this.stage.collide(this);
			this.play("shining");
		}
	});

	Q.animations('coin anim', {
		shining: { frames: [0, 1, 2], rate: 1/5}
	});

	Q.loadTMX("level1.tmx, sprites.json, level2.tmx, wynot.tmx", function() {
		Q.stageScene("mainTitle");
	});

	Q.scene('endGame',function(stage) {
		var box = stage.insert(new Q.UI.Container({
			x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
		}));

		if(levelwin){
			var button = box.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC", label: "Next Level" }));
			button.on("click",function() {
				if(currentLevel<=2)
					currentLevel++;
				levelwin = false;
				Q.clearStages();
				Q.stageScene('level'+currentLevel);
				Q.stageScene('HUD', 1);
			});
		}else{ //Mario dies
			if(!lost){ //lives >= 0
				var button = box.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC", label: "Play Again" }));
				button.on("click",function() {
					console.log(currentLevel);
					Q.clearStages();
					levelwin = false;
					Q.state.set({coins: 0});
					Q.stageScene('level'+currentLevel);
					Q.stageScene('HUD', 1);
				});
			}
		}
		var button2 = box.insert(new Q.UI.Button({ x: 0, y: 60, fill: "#CCCCCC",
											   label: "Main menu" }));

		var label = box.insert(new Q.UI.Text({cx:button2.width/2, y: -10 - button2.p.h,
											label: stage.options.label }));
		button2.on("click",function() {
			Q.clearStages();
			Q.state.set({coins: 0, lives: 3});
			Q.stageScene('mainTitle');

		});
		box.fit(20);
	});

	Q.scene('HUD',function(stage) {
		var label = stage.insert(new Q.UI.Text({x:150, y: 20, label: "Lives: "+Q.state.get("lives")+"	Coins: "+Q.state.get("coins")}));
		console.log(Q.state.get("coins"));
	});

	Q.scene('mainTitle', function(stage) {
		inMenu=true;
		var box = stage.insert(new Q.UI.Container({
			cx: Q.height/2, cy: Q.height/2,  fill: "rgba(0,0,0,1)"
		}));

		var button = box.insert(new Q.UI.Button({ x: Q.width/2, y: Q.height/2, fill: "#CCCCCC", asset: "mainTitle.png" }));

		button.on("click", init);
		document.addEventListener("keyup", listener);
		document.body.addEventListener("touchstart", touch);

	});

	var touch=function(){
		if(inMenu){
			init();
			inMenu=false;
		}
	}

	var listener = function (evt) {
		if(evt.which==13) init();
	};

	function init(){

		Q.clearStages();
		document.removeEventListener("keyup", listener);
		currentLevel = 1;
		lost = false;
		Q.state.set({coins: 0, lives: 3});
		Q.stageScene('level1');
		Q.stageScene('HUD', 1);
	}

	// ## Level1 scene
		// Create a new scene called level 1
	Q.scene('level1', function(stage) {
		Q.stageTMX("wynot.tmx", stage);
		var mario = stage.insert(new Q.Mario());
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:8000,vx:-50}));},3000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:4000,vx:-50}));},3000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:2000,vx:-50}));},3000);
		var peach = stage.insert(new Q.Peach());
		stage.add("viewport").follow(mario, {x:true, y:false});
	});
	// ## Level2 scene
		// Create a new scene called level 2
	Q.scene('level2', function(stage) {
		Q.stageTMX("level2.tmx", stage);
		var mario = stage.insert(new Q.Mario());
		stage.insert(new Q.Bloopa());
		setInterval(function(){stage.insert(new Q.Bloopa());},4000);
		setInterval(function(){stage.insert(new Q.Bloopa({x:3094,y:500}));},3000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:1300}));},3000);
		var peach = stage.insert(new Q.Peach());
		var coin = stage.insert(new Q.Coin({x:300, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:350, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:450, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:650, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:700, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:1200, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:1250, y:400}));

		stage.add("viewport").follow(mario, {x:true, y:false});
	});
};

<commit_msg>nivel posible<commit_after>var game = function() {
	// Set up an instance of the Quintus engine and include
	// the Sprites, Scenes, Input and 2D module. The 2D module
	// includes the `TileLayer` class as well as the `2d` componet.
	var Q = window.Q = Quintus({ audioSupported: [ 'ogg', 'mp3' ]})
		 .include("Sprites, Scenes, Input, 2D, TMX, Anim, Touch, UI, Audio")
		 // Maximize this game to whatever the size of the browser is
		 .setup({ maximize: true })
		 // And turn on default input controls and touch input (for UI)
		 .controls().touch().enableSound();
	var levelwin = false;
	var currentLevel = 1;
	var lost = false;

	Q.state.set({coins: 0, lives: 3});
	Q.state.on("change.coins, change.lives", function(){Q.stageScene("HUD", 1, {label: "Lives: "+Q.state.get("lives")+"	Coins: "+Q.state.get("coins")});});

	Q.load(["mario_small.png","mario_small.json","bloopa.png", "mainTitle.png",
				"bloopa.json","goomba.png","goomba.json", "princess.png",
					"coin.png", "coin.json", "music_main.mp3", "coin.mp3", "music_die.mp3"], function(){
		Q.compileSheets("mario_small.png","mario_small.json");
		Q.compileSheets("bloopa.png","bloopa.json");
		Q.compileSheets("goomba.png","goomba.json");
		Q.compileSheets("coin.png", "coin.json");
		Q.audio.play("music_main.mp3",{ loop: true });
	});

	//------------MARIO
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Mario", {

	  init: function(p) {
		this._super(p, {
			sprite: "mario anim",
			sheet: "marioR",
			x: 150,
			y: 280,
			jumpSpeed: -500,
			dead: false
		});
		this.add('2d, platformerControls, animation');
	  },

	  step: function(dt) {
		if(this.p.y > 600 && !this.p.dead){
			this.death();
		}
		if(!this.p.dead){

			if(this.p.direction == "right"){
				if(this.p.vx != 0 && this.p.vy == 0){
					this.play("run_right");
				}else if (this.p.vy != 0){
					this.play("jump_right");
				}else {
					this.play("stand_right");
				}
			}
		}
	  },

	  death: function(){
		if(!levelwin && !this.p.dead)
			Q.audio.stop("");
			Q.audio.play("music_die.mp3");
			this.del('platformerControls');
			this.p.vx = 0;
			this.p.vy = -400;
			this.play("dead_"+this.p.direction);
			this.p.dead = true;
			var self = this;
			Q.state.inc("lives", -1);
			if(Q.state.get("lives")<0){
				lost = true;
				Q.stageScene("endGame", 1, {label: "GAME OVER"});
			}
			else{
				Q.stageScene("endGame", 1, {label: "You died"});
			}
			setTimeout(function(){self.destroy();}, 1000);
	  },

	});
	Q.animations('mario anim', {
		run_right: { frames: [1, 2, 3], rate: 1/10},
		run_left: { frames: [17, 16, 15], rate: 1/10 },
		stand_right: { frames: [0], rate: 1/5 },
		stand_left: { frames: [14], rate: 1/5 },
		jump_right: { frames: [4], rate: 1/5 },
		jump_left: { frames: [18], rate: 1/5 },
		dead_right: { frames: [12], rate: 1/5 },
		dead_left: { frames: [26], rate: 1/5 }
	});

	//------------PRINCESS
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Peach", {

	  init: function(p) {
		this._super( {
			asset: "princess.png",
			x: 9000,
			y: 500
		});
		this.add('2d');
		this.on("bump.left, bump.right, bump.top", this, "win");
	  },
	  win: function(collision){
		if(collision.obj.isA("Mario")){
			collision.obj.del('platformerControls');
			collision.obj.p.vx=0;
			levelwin = true;
			Q.stageScene("endGame", 1, {label: "You win this time..."});
		}
	  }

	});

	//------------DEFAULT ENEMY
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.component('defaultEnemy', {

		added: function() {
			this.entity.on("bump.left, bump.right", this.entity, "kill");
			this.entity.on("bump.top", this.entity, "stomp");
		},

		extend: {
			stomp: function(collision) {
				if(collision.obj.isA("Mario")) {
					this.play("die", 1);
					this.p.vx=0;
					this.p.vy=0;
					this.off("bump.bottom");
					var self = this;
					setTimeout(function(){self.destroy()}, 800);
					collision.obj.p.vy = -500; // make the player jump
				}
			},

			kill: function(collision) {
				if(collision.obj.isA("Mario")) {
					collision.obj.death();
				}
			}
		}
	});

	//------------BLOOPA
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Bloopa",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'bloopa anim',
				sheet: "bloopa",
				x: 350,
				y: 500,
				vx: 75,
				vy: -300,
				gravity: 0.4
			});
			this.add('2d, animation, aiBounce, defaultEnemy');
			this.on("bump.bottom", this, "jump");
		},

		jump: function(collision) {
			this.kill(collision);
			this.p.vy = -300;
			this.play("jump");
			var self = this;
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
			if(this.p.y > 600){
				this.destroy();
			}
		}
	});

	Q.animations('bloopa anim', {
		walk: { frames: [0], rate: 1},
		jump: { frames: [1], next: "walk", rate: 1/8},
		die: { frames: [2], rate: 1}
	});

	//------------GOOMBA
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Goomba",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'goomba anim',
				sheet: "goomba",
				vx: 150,
				x: 250,
				y: 500
			});
			this.add('2d, animation, aiBounce, defaultEnemy');
			this.on("bump.bottom", this, "kill");
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
			this.play("walk");
			if(this.p.y > 600){
				this.destroy();
			}
		}
	});

	Q.animations('goomba anim', {
		walk: { frames: [0, 1], rate: 1/4},
		die: { frames: [2/*, 3*/], rate: 1/1}
	});

	//------------COIN
	//-----------------------------------------------------
	//-----------------------------------------------------
	Q.Sprite.extend("Coin",{
		init: function(p) {
			// Listen for hit event and call the collision method
			this._super(p, {
				sprite: 'coin anim',
				sheet: 'coin',
				catched: false,
				sensor: true
			});
			this.add('animation, tween');
			this.on("hit", this, "getCoin");
		},

		getCoin: function(collision) {
			if(collision.obj.isA("Mario") && !this.p.catched) {
				Q.audio.stop('coin.mp3');
				Q.audio.play('coin.mp3');
				this.animate({x: this.p.x, y: this.p.y-100, opacity: 0}, 1, Q.Easing.Quadratic.Out);
				var self = this;
				setTimeout(function(){self.destroy()}, 1200);
				Q.state.inc("coins", 1);
				this.p.catched = true;
			}
		},

		step: function(dt) {
		// Tell the stage to run collisions on this sprite
		//this.stage.collide(this);
			this.play("shining");
		}
	});

	Q.animations('coin anim', {
		shining: { frames: [0, 1, 2], rate: 1/5}
	});

	Q.loadTMX("level1.tmx, sprites.json, level2.tmx, wynot.tmx", function() {
		Q.stageScene("mainTitle");
	});

	Q.scene('endGame',function(stage) {
		var box = stage.insert(new Q.UI.Container({
			x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
		}));

		if(levelwin){
			var button = box.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC", label: "Next Level" }));
			button.on("click",function() {
				if(currentLevel<=2)
					currentLevel++;
				levelwin = false;
				Q.clearStages();
				Q.stageScene('level'+currentLevel);
				Q.stageScene('HUD', 1);
			});
		}else{ //Mario dies
			if(!lost){ //lives >= 0
				var button = box.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC", label: "Play Again" }));
				button.on("click",function() {
					console.log(currentLevel);
					Q.clearStages();
					levelwin = false;
					Q.state.set({coins: 0});
					Q.stageScene('level'+currentLevel);
					Q.stageScene('HUD', 1);
				});
			}
		}
		var button2 = box.insert(new Q.UI.Button({ x: 0, y: 60, fill: "#CCCCCC",
											   label: "Main menu" }));

		var label = box.insert(new Q.UI.Text({cx:button2.width/2, y: -10 - button2.p.h,
											label: stage.options.label }));
		button2.on("click",function() {
			Q.clearStages();
			Q.state.set({coins: 0, lives: 3});
			Q.stageScene('mainTitle');

		});
		box.fit(20);
	});

	Q.scene('HUD',function(stage) {
		var label = stage.insert(new Q.UI.Text({x:150, y: 20, label: "Lives: "+Q.state.get("lives")+"	Coins: "+Q.state.get("coins")}));
		console.log(Q.state.get("coins"));
	});

	Q.scene('mainTitle', function(stage) {
		inMenu=true;
		var box = stage.insert(new Q.UI.Container({
			cx: Q.height/2, cy: Q.height/2,  fill: "rgba(0,0,0,1)"
		}));

		var button = box.insert(new Q.UI.Button({ x: Q.width/2, y: Q.height/2, fill: "#CCCCCC", asset: "mainTitle.png" }));

		button.on("click", init);
		document.addEventListener("keyup", listener);
		document.body.addEventListener("touchstart", touch);

	});

	var touch=function(){
		if(inMenu){
			init();
			inMenu=false;
		}
	}

	var listener = function (evt) {
		if(evt.which==13) init();
	};

	function init(){

		Q.clearStages();
		document.removeEventListener("keyup", listener);
		currentLevel = 1;
		lost = false;
		Q.state.set({coins: 0, lives: 3});
		Q.stageScene('level1');
		Q.stageScene('HUD', 1);
	}

	// ## Level1 scene
		// Create a new scene called level 1
	Q.scene('level1', function(stage) {
		Q.stageTMX("wynot.tmx", stage);
		var mario = stage.insert(new Q.Mario());
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:8000,vx:-50}));},3000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:4000,vx:-50}));},5000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:2000,vx:-50}));},4000);
		var peach = stage.insert(new Q.Peach());
		stage.add("viewport").follow(mario, {x:true, y:false});
	});
	// ## Level2 scene
		// Create a new scene called level 2
	Q.scene('level2', function(stage) {
		Q.stageTMX("level2.tmx", stage);
		var mario = stage.insert(new Q.Mario());
		stage.insert(new Q.Bloopa());
		setInterval(function(){stage.insert(new Q.Bloopa());},4000);
		setInterval(function(){stage.insert(new Q.Bloopa({x:3094,y:500}));},3000);
		setInterval(function(){stage.insert(new Q.Goomba({y:400,x:1300}));},3000);
		var peach = stage.insert(new Q.Peach());
		var coin = stage.insert(new Q.Coin({x:300, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:350, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:450, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:650, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:700, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:1200, y:400}));
		var coin2 = stage.insert(new Q.Coin({x:1250, y:400}));

		stage.add("viewport").follow(mario, {x:true, y:false});
	});
};

<|endoftext|>


<commit_before>// Websocket server which handles data to/from the inspector
var fs = require('fs');
var express = require('express');
var remoteDebugger = express();

var remoteDebugServer = require('http').Server(remoteDebugger);
var remoteDebugSocket = require('socket.io')(remoteDebugServer);
var inspectorSocket = null;

// Load the inspector html from the node_modules folder
// (it should be there because we list it as a dependency)
var inspectorPath = __dirname + '/../node_modules/ember-extension/dist_websocket/';
var inspectorHtml = fs.readFileSync(inspectorPath + 'panes/index.html').toString();

remoteDebugger.use('/', express.static(inspectorPath)); // Serve inspector static files
remoteDebugger.get('/', function(req, res) {            // Serve inspector
  res.end(inspectorHtml);
});

module.exports = {
  /*
   Injects the script used to connect socket.io to the inspector into the inspector HTML
   */
  setRemoteDebugSocketScript: function(scriptHtml) {
    inspectorHtml = inspectorHtml.replace('{{ remote-port }}', scriptHtml)
  },

  /*
   Start the server for the inspector + socket.io
   */
  start: function(port, host) {
    remoteDebugServer.listen(port, host, function(){
      console.log('Ember inspector available on http://' + host + ':' + port + '.');
    });

    remoteDebugSocket.on('connect', function(socket){
      socket.on('emberInspectorMessage', function(msg){
        // If this message comes from the inspector, emit to all clients
        // and set inspectorSocket
        if(msg.from==='devtools') {
          inspectorSocket = socket;
          remoteDebugSocket.emit('emberInspectorMessage', msg);
        }
        // If the messge comes from a client, send only to inspector
        else if(inspectorSocket) {
          inspectorSocket.emit('emberInspectorMessage', msg);
        }
      });
    });
  }
}<commit_msg>Inspector fixed name<commit_after>// Websocket server which handles data to/from the inspector
var fs = require('fs');
var express = require('express');
var remoteDebugger = express();

var remoteDebugServer = require('http').Server(remoteDebugger);
var remoteDebugSocket = require('socket.io')(remoteDebugServer);
var inspectorSocket = null;

// Load the inspector html from the node_modules folder
// (it should be there because we list it as a dependency)
var inspectorPath = __dirname + '/../node_modules/ember-inspector/dist_websocket/';
var inspectorHtml = fs.readFileSync(inspectorPath + 'panes/index.html').toString();

remoteDebugger.use('/', express.static(inspectorPath)); // Serve inspector static files
remoteDebugger.get('/', function(req, res) {            // Serve inspector
  res.end(inspectorHtml);
});

module.exports = {
  /*
   Injects the script used to connect socket.io to the inspector into the inspector HTML
   */
  setRemoteDebugSocketScript: function(scriptHtml) {
    inspectorHtml = inspectorHtml.replace('{{ remote-port }}', scriptHtml)
  },

  /*
   Start the server for the inspector + socket.io
   */
  start: function(port, host) {
    remoteDebugServer.listen(port, host, function(){
      console.log('Ember inspector available on http://' + host + ':' + port + '.');
    });

    remoteDebugSocket.on('connect', function(socket){
      socket.on('emberInspectorMessage', function(msg){
        // If this message comes from the inspector, emit to all clients
        // and set inspectorSocket
        if(msg.from==='devtools') {
          inspectorSocket = socket;
          remoteDebugSocket.emit('emberInspectorMessage', msg);
        }
        // If the messge comes from a client, send only to inspector
        else if(inspectorSocket) {
          inspectorSocket.emit('emberInspectorMessage', msg);
        }
      });
    });
  }
}<|endoftext|>


<commit_before>export { SameWhenPassThrough_PrefixSqueezeExcitation };

import * as BoundsArraySet from "../BoundsArraySet.js";
import * as ReturnOrClone from "../ReturnOrClone.js";
import * as SqueezeExcitation from "../SqueezeExcitation.js";
import { SameWhenPassThrough } from "./Pointwise_SameWhenPassThrough.js";

//!!! ...unfinished... (2022/05/14)
// Q: Perhaps, let pointwise1 become squeeze and excitation before depthwise.
// A: It may not be possible because input and output channel count may be different.

//!!! ...unfinished... (2022/05/08) Add squeeze and excitation before pointwise.
// globale avg pooling - pointwise - pointwise - multiplyToInput
// And the, the original pointwise

//!!! ...unfinished... (2022/05/09) What if:
// pointwise1 ( bias, activation )
// depthwise ( channelMultipler > 1, bias / no bias, activation / no activation )
// pointwiseSE ( bias, activation )
// pointwise2 ( bias, activation )
//
// pointwise1 - depthwise - pointwiseSE - multiply - pointwise2
//                        \-------------/
//
// No global average pooloing.
//
//
//
//

/**
 * A Pointwise_SameWhenPassThrough with a SqueezeExcitation in front of it.
 *
 *
 * @member {number} byteOffsetBegin
 *   The position which is started (inclusive) to extract from inputFloat32Array.buffer by init(). This is relative to the
 * inputFloat32Array.buffer (not to the inputFloat32Array.byteOffset).
 *
 * @member {number} byteOffsetEnd
 *   The position which is ended to (non-inclusive) extract from inputFloat32Array.buffer by init(). Where to extract next weights.
 * Only meaningful when ( this.bInitOk == true ). This is relative to the inputFloat32Array.buffer (not to the inputFloat32Array.byteOffset).
 *

//!!! ...unfinished... (2022/05/19) ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.Xxx

 * @member {number} nSqueezeExcitationChannelCountDivisor
 *   An integer represents the channel count divisor for squeeze-and-excitation's intermediate pointwise convolution channel count.
 * (Please see also SqueezeExcitation.Base.nSqueezeExcitationChannelCountDivisor explanation.)
 *
 * @member {number} inputHeight
 *   The height of the input tensor. (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 *
 * @member {number} inputWidth
 *   The width of the input tensor. (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 * *
 * @member {number} inputChannelCount
 *   The channel count of the input tensor. It must be greater than zero (> 0).
 *
 * @member {number} outputChannelCount
 *   The channel count of the output tensor.
 *
 * @member {ValueDesc.Pointwise_HigherHalfDifferent} nHigherHalfDifferent
 *   The HigherHalfDifferent type for pointwise convolution.
 *
 * @member {boolean} bExisted
 *   If true, this operation exists. If false, this object is a no-op (i.e. no squeeze-and-excitation, no pointwise).
 *
 * @member {boolean} bSqueezeExcitation
 *   If true, the squeeze-and-excitation exists. It will be false in the following cases:
 *
 *     - ( this.bExisted == false )
 *       - no squeeze, no excitation, no multiply, no pointwise.
 *
 *     - ( nSqueezeExcitationChannelCountDivisor == ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.NONE ) (-2)
 *       - no squeeze, no excitation, no multiply.
 *

//!!! ...unfinished... (2022/05/20) should return the SqueezeExcitation.Base.bSqueeze if ( bSqueezeExcitation == true ).

 * @member {boolean} bSqueeze
 *   Whether squeeze-and-excitation has squeeze. It is only meaningful when ( bSqueezeExcitation == true ). It is always false
 * if ( bSqueezeExcitation == false ). (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Including inferenced weights, if they are used in tensors.
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputFloat32Array and used in tensors. Not including inferenced weights (even if they are
 * used in tensors), because they are not extracted from inputFloat32Array.
 *
 * @member {function} apply
 *   A method accepts one parameter inputTensor (tf.tensor3d) and return an outputTensor (tf.tensor3d). All intermediate tensors
 * will be disposed. The inputTensor may or may not be disposed (according to setKeepInputTensor()). In fact, this method calls one

//!!! ...unfinished... (2022/05/19)

 * of Base.???() according to the parameters.
 *
 * @see SqueezeExcitation.Base
 * @see Pointwise.SameWhenPassThrough
 *
 */
class SameWhenPassThrough_PrefixSqueezeExcitation extends ReturnOrClone.Base {

//!!! ...unfinished... (2022/05/20)

  /**
   */
  constructor(
    nSqueezeExcitationChannelCountDivisor, inputHeight, inputWidth,
    inputChannelCount, outputChannelCount, bBias, nActivationId,
    nHigherHalfDifferent, inputChannelCount_lowerHalf, outputChannelCount_lowerHalf, channelShuffler_outputGroupCount ) {

    this.nSqueezeExcitationChannelCountDivisor = nSqueezeExcitationChannelCountDivisor;
    this.inputHeight = inputHeight;
    this.inputWidth = inputWidth;
    this.inputChannelCount = inputChannelCount;
    this.outputChannelCount = outputChannelCount;
    this.bBias = bBias;
    this.nActivationId = nActivationId;
    this.nHigherHalfDifferent = nHigherHalfDifferent;
    this.inputChannelCount_lowerHalf = inputChannelCount_lowerHalf;
    this.outputChannelCount_lowerHalf = outputChannelCount_lowerHalf;
    this.channelShuffler_outputGroupCount = channelShuffler_outputGroupCount;
  }

  /**
   * @param {Float32Array} inputFloat32Array
   *   A Float32Array whose values will be interpreted as weights.
   *
   * @param {ActivationEscaping.ScaleBoundsArray} inputScaleBoundsArray
   *   The element value bounds (per channel) of input. Usually, it is The .output of the previous operation value bounds set
   * of this operation. It will be kept (not cloned) directly. So caller should not modify them.
   *
   * @return {boolean} Return true, if succeeded.
   */
  init( inputFloat32Array, byteOffsetBegin, inputScaleBoundsArray ) {

    this.disposeTensors();

    this.byteOffsetBegin = this.byteOffsetEnd = byteOffsetBegin;

    // 1. Determine operation functions.
    Base.setup_bExisted.call( this );
    Base.setup_bSqueezeExcitation.call( this );
    Base.setup_pfn.call( this );

//!!!
    if ( this.bExisted ) {

      // 2. Initialize sub-operations.

      // 2.1 squeezeExcitation
      let squeezeExcitation_boundsArraySet_output0;
      if ( this.bSqueezeExcitation ) {
        this.squeezeExcitation = new SqueezeExcitation.Base(
          this.nSqueezeExcitationChannelCountDivisor, this.inputHeight, this.inputWidth,
          this.inputChannelCount, this.nActivationId,
          this.nHigherHalfDifferent, this.inputChannelCount_lowerHalf, this.outputChannelCount_lowerHalf );

        if ( !this.squeezeExcitation.init( inputFloat32Array, this.byteOffsetEnd, inputScaleBoundsArray ) )
          return false;  // e.g. input array does not have enough data.
        this.byteOffsetEnd = this.squeezeExcitation.byteOffsetEnd;

        this.tensorWeightCountTotal += this.squeezeExcitation.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += this.squeezeExcitation.tensorWeightCountExtracted;

        squeezeExcitation_boundsArraySet_output0 = this.squeezeExcitation.boundsArraySet.output0;
      } else {
        squeezeExcitation_boundsArraySet_output0 = inputScaleBoundsArray;
      }

      // 2.2 pointwise
      {
        this.pointwise = new SameWhenPassThrough(
          this.inputChannelCount, this.outputChannelCount, this.bBias, this.nActivationId,
          this.nHigherHalfDifferent,
          this.inputChannelCount_lowerHalf, this.outputChannelCount_lowerHalf,
          this.channelShuffler_outputGroupCount );

        if ( !this.pointwise.init( inputFloat32Array, this.byteOffsetEnd, squeezeExcitation_boundsArraySet_output0 ) )
          return false;  // e.g. input array does not have enough data.
        this.byteOffsetEnd = this.excitationPointwise.byteOffsetEnd;

        this.tensorWeightCountTotal += this.pointwise.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += this.pointwise.tensorWeightCountExtracted;
      }

      // 3. BoundsArraySet
      {
        { // Build self BoundsArraySet.
          this.boundsArraySet = new BoundsArraySet.InputsOutputs( inputScaleBoundsArray, null,
            this.pointwise.boundsArraySet.output0.channelCount, 0 );

          this.boundsArraySet.set_outputs_all_byBoundsArraySet_Outputs( this.pointwise.boundsArraySet );
        }

        this.dispose_all_sub_BoundsArraySet(); // For reduce memory footprint.
      }
    }

    this.bInitOk = true;
    return this.bInitOk;
  }

  /** Release all tensors. */
  disposeTensors() {
    if ( this.squeezeExcitation ) {
      this.squeezeExcitation.disposeTensors();
      this.squeezeExcitation = null;
    }

    if ( this.pointwise ) {
      this.pointwise.disposeTensors();
      this.pointwise = null;
    }

    this.tensorWeightCountTotal = this.tensorWeightCountExtracted = 0;
    this.byteOffsetBegin = this.byteOffsetEnd = -1;
    this.bKeepInputTensor = false;  // Default will dispose input tensor.
    this.bInitOk = false;
  }

  /**
   * Release all BoundsArraySet of squeezeExcitation, pointwise.
   *
   * This could reduce memory footprint.
   *
   * (Note: This Pointwise.SameWhenPassThrough_PrefixSqueezeExcitation's BoundsArraySet is kept.)
   */
  dispose_all_sub_BoundsArraySet() {
    delete this.squeezeExcitation?.boundsArraySet;
    delete this.pointwise.boundsArraySet;
  }

//!!! ...unfinished... (2022/05/19)

  /**
   * The sub operations' setKeepInputTensor() will be called so that only the first operation is responsible for keeping inputTensor.
   * All other operations should always destroy inputTensor..
   *
   */
  setKeepInputTensor( bKeepInputTensor ) {
    if ( bKeepInputTensor == this.bKeepInputTensor )
      return;

    this.bKeepInputTensor = bKeepInputTensor;
    if ( bKeepInputTensor ) {

//!!! ...unfinished... (2022/05/19)

      // Note: The first operation is responsible for keep inputTensor. All other operations should always destroy inputTensor.
      if ( this.squeezeDepthwise ) {
        this.squeezeDepthwise.setKeepInputTensor( true );
        this.intermediatePointwise.setKeepInputTensor( false );
        this.excitationPointwise.setKeepInputTensor( false );
      } else {
        if ( this.intermediatePointwise ) {
          this.intermediatePointwise.setKeepInputTensor( true );
          this.excitationPointwise.setKeepInputTensor( false );
        } else {
          this.excitationPointwise.setKeepInputTensor( true );
        }
      }

    } else {
      this.squeezeDepthwise?.setKeepInputTensor( false );
      this.intermediatePointwise?.setKeepInputTensor( false );
      this.excitationPointwise.setKeepInputTensor( false );
    }
  }

  get bSqueeze() {
    if ( !this.squeezeExcitation )
      return false; // Since no squeeze-and-excitation, there will be no squeeze.
    return this.squeezeExcitation.bSqueeze;
  }

  /** Determine data member this.bExisted
   *
   * @param {Base} this  The Base object to be determined and modified.
   */
  static setup_bExisted() {

//!!! ...unfinished... (2022/05/20) bExisted
// If ( outputChannelCount <= 0 ), no squeeze-and-excitation and no pointwise.
//
// Problem: ( outputChannelCount <= 0 ) but ( channelShuffler_outputGroupCount > 0 ),
//          the pointwise still exists (all-pass-through-and-channel-shuffling).
//
//

    if ( this.outputChannelCount <= 0 ) {
      this.bExisted = false;
    } else {
      this.bExisted = true;
    }
  }

  /** Determine data member this.bSqueezeExcitation
   *
   * @param {Base} this  The Base object to be determined and modified.
   */
  static setup_bSqueezeExcitation() {
    if ( this.bExisted == false ) {
      this.bSqueezeExcitation = false;
    } else {
      if ( this.nSqueezeExcitationChannelCountDivisor == ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.NONE ) { // (-2)
        this.bSqueezeExcitation = false;
      } else {
        this.bSqueezeExcitation = true;
      }
    }
  }

  //!!! ...unfinished... (2022/05/19)

  /** Determine data member this.apply.
   *
   * @param {Base} this
   *   The Base object to be determined and modified.
   */
  static setup_pfn() {

//!!! ...unfinished... (2022/05/20) bExisted
// If ( bExisted == false ) (after pointwise is created), the squeezeExcitation should also be skipped.

//!!! ...unfinished... (2022/05/19)

    if ( this.bExisted ) {
      if ( this.bSqueeze ) {
        if ( this.intermediateChannelCount > 0 ) {
          this.apply = Base.squeeze_intermediate_excitation;
        } else {
          this.apply = Base.squeeze_excitation;
        }
      } else {
        if ( this.intermediateChannelCount > 0 ) {
          this.apply = Base.intermediate_excitation;
        } else {
          this.apply = Base.excitation;
        }
      }
    } else { // There is no operation at all.
      this.apply = Base.return_input_directly;
    }
  }

//!!! ...unfinished... (2022/05/19)

  /** */
  static squeeze_intermediate_excitation( inputTensor ) {

//!!! ...unfinished... (2022/05/19)

    let t0, t1;
    t0 = this.squeezeDepthwise.apply( inputTensor );
    t1 = this.intermediatePointwise.apply( t0 );
    t0 = this.excitationPointwise.apply( t1 );

    t1 = tf.mul( inputTensor, t0 );
    t0.dispose();
    return t1;
  }

}
<commit_msg>Update Pointwise_SameWhenPassThrough_PrefixSqueezeExcitation.js<commit_after>export { SameWhenPassThrough_PrefixSqueezeExcitation };

import * as BoundsArraySet from "../BoundsArraySet.js";
import * as ReturnOrClone from "../ReturnOrClone.js";
import * as SqueezeExcitation from "../SqueezeExcitation.js";
import { SameWhenPassThrough } from "./Pointwise_SameWhenPassThrough.js";

//!!! ...unfinished... (2022/05/14)
// Q: Perhaps, let pointwise1 become squeeze and excitation before depthwise.
// A: It may not be possible because input and output channel count may be different.

//!!! ...unfinished... (2022/05/08) Add squeeze and excitation before pointwise.
// globale avg pooling - pointwise - pointwise - multiplyToInput
// And the, the original pointwise

//!!! ...unfinished... (2022/05/09) What if:
// pointwise1 ( bias, activation )
// depthwise ( channelMultipler > 1, bias / no bias, activation / no activation )
// pointwiseSE ( bias, activation )
// pointwise2 ( bias, activation )
//
// pointwise1 - depthwise - pointwiseSE - multiply - pointwise2
//                        \-------------/
//
// No global average pooloing.
//
//
//
//

/**
 * A Pointwise_SameWhenPassThrough with a SqueezeExcitation in front of it.
 *
 *
 * @member {number} byteOffsetBegin
 *   The position which is started (inclusive) to extract from inputFloat32Array.buffer by init(). This is relative to the
 * inputFloat32Array.buffer (not to the inputFloat32Array.byteOffset).
 *
 * @member {number} byteOffsetEnd
 *   The position which is ended to (non-inclusive) extract from inputFloat32Array.buffer by init(). Where to extract next weights.
 * Only meaningful when ( this.bInitOk == true ). This is relative to the inputFloat32Array.buffer (not to the inputFloat32Array.byteOffset).
 *

//!!! ...unfinished... (2022/05/19) ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.Xxx

 * @member {number} nSqueezeExcitationChannelCountDivisor
 *   An integer represents the channel count divisor for squeeze-and-excitation's intermediate pointwise convolution channel count.
 * (Please see also SqueezeExcitation.Base.nSqueezeExcitationChannelCountDivisor explanation.)
 *
 * @member {number} inputHeight
 *   The height of the input tensor. (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 *
 * @member {number} inputWidth
 *   The width of the input tensor. (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 * *
 * @member {number} inputChannelCount
 *   The channel count of the input tensor. It must be greater than zero (> 0).
 *
 * @member {number} outputChannelCount
 *   The channel count of the output tensor.
 *
 * @member {ValueDesc.Pointwise_HigherHalfDifferent} nHigherHalfDifferent
 *   The HigherHalfDifferent type for pointwise convolution.
 *
 * @member {boolean} bExisted
 *   If true, this operation exists. If false, this object is a no-op (i.e. no squeeze-and-excitation, no pointwise).
 *
 * @member {boolean} bSqueezeExcitation
 *   If true, the squeeze-and-excitation exists. It will be false in the following cases:
 *
 *     - ( this.bExisted == false )
 *       - no squeeze, no excitation, no multiply, no pointwise.
 *
 *     - ( nSqueezeExcitationChannelCountDivisor == ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.NONE ) (-2)
 *       - no squeeze, no excitation, no multiply.
 *

//!!! ...unfinished... (2022/05/20) should return the SqueezeExcitation.Base.bSqueeze if ( bSqueezeExcitation == true ).

 * @member {boolean} bSqueeze
 *   Whether squeeze-and-excitation has squeeze. It is only meaningful when ( bSqueezeExcitation == true ). It is always false
 * if ( bSqueezeExcitation == false ). (Please see also SqueezeExcitation.Base.bSqueeze explanation.)
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Including inferenced weights, if they are used in tensors.
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputFloat32Array and used in tensors. Not including inferenced weights (even if they are
 * used in tensors), because they are not extracted from inputFloat32Array.
 *
 * @member {function} apply
 *   A method accepts one parameter inputTensor (tf.tensor3d) and return an outputTensor (tf.tensor3d). All intermediate tensors
 * will be disposed. The inputTensor may or may not be disposed (according to setKeepInputTensor()). In fact, this method calls one

//!!! ...unfinished... (2022/05/19)

 * of Base.???() according to the parameters.
 *
 * @see SqueezeExcitation.Base
 * @see Pointwise.SameWhenPassThrough
 *
 */
class SameWhenPassThrough_PrefixSqueezeExcitation extends ReturnOrClone.Base {

//!!! ...unfinished... (2022/05/20)

  /**
   */
  constructor(
    nSqueezeExcitationChannelCountDivisor, inputHeight, inputWidth,
    inputChannelCount, outputChannelCount, bBias, nActivationId,
    nHigherHalfDifferent, inputChannelCount_lowerHalf, outputChannelCount_lowerHalf, channelShuffler_outputGroupCount ) {

    this.nSqueezeExcitationChannelCountDivisor = nSqueezeExcitationChannelCountDivisor;
    this.inputHeight = inputHeight;
    this.inputWidth = inputWidth;
    this.inputChannelCount = inputChannelCount;
    this.outputChannelCount = outputChannelCount;
    this.bBias = bBias;
    this.nActivationId = nActivationId;
    this.nHigherHalfDifferent = nHigherHalfDifferent;
    this.inputChannelCount_lowerHalf = inputChannelCount_lowerHalf;
    this.outputChannelCount_lowerHalf = outputChannelCount_lowerHalf;
    this.channelShuffler_outputGroupCount = channelShuffler_outputGroupCount;
  }

  /**
   * @param {Float32Array} inputFloat32Array
   *   A Float32Array whose values will be interpreted as weights.
   *
   * @param {ActivationEscaping.ScaleBoundsArray} inputScaleBoundsArray
   *   The element value bounds (per channel) of input. Usually, it is The .output of the previous operation value bounds set
   * of this operation. It will be kept (not cloned) directly. So caller should not modify them.
   *
   * @return {boolean} Return true, if succeeded.
   */
  init( inputFloat32Array, byteOffsetBegin, inputScaleBoundsArray ) {

    this.disposeTensors();

    this.byteOffsetBegin = this.byteOffsetEnd = byteOffsetBegin;

    // 1. Determine operation functions.
    Base.setup_bExisted.call( this );
    Base.setup_bSqueezeExcitation.call( this );
    Base.setup_pfn.call( this );

//!!!
    if ( this.bExisted ) {

      // 2. Initialize sub-operations.

      // 2.1 squeezeExcitation
      let squeezeExcitation_boundsArraySet_output0;
      if ( this.bSqueezeExcitation ) {
        this.squeezeExcitation = new SqueezeExcitation.Base(
          this.nSqueezeExcitationChannelCountDivisor, this.inputHeight, this.inputWidth,
          this.inputChannelCount, this.nActivationId,
          this.nHigherHalfDifferent, this.inputChannelCount_lowerHalf, this.outputChannelCount_lowerHalf );

        if ( !this.squeezeExcitation.init( inputFloat32Array, this.byteOffsetEnd, inputScaleBoundsArray ) )
          return false;  // e.g. input array does not have enough data.
        this.byteOffsetEnd = this.squeezeExcitation.byteOffsetEnd;

        this.tensorWeightCountTotal += this.squeezeExcitation.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += this.squeezeExcitation.tensorWeightCountExtracted;

        squeezeExcitation_boundsArraySet_output0 = this.squeezeExcitation.boundsArraySet.output0;
      } else {
        squeezeExcitation_boundsArraySet_output0 = inputScaleBoundsArray;
      }

      // 2.2 pointwise
      {
        this.pointwise = new SameWhenPassThrough(
          this.inputChannelCount, this.outputChannelCount, this.bBias, this.nActivationId,
          this.nHigherHalfDifferent,
          this.inputChannelCount_lowerHalf, this.outputChannelCount_lowerHalf,
          this.channelShuffler_outputGroupCount );

        if ( !this.pointwise.init( inputFloat32Array, this.byteOffsetEnd, squeezeExcitation_boundsArraySet_output0 ) )
          return false;  // e.g. input array does not have enough data.
        this.byteOffsetEnd = this.excitationPointwise.byteOffsetEnd;

        this.tensorWeightCountTotal += this.pointwise.tensorWeightCountTotal;
        this.tensorWeightCountExtracted += this.pointwise.tensorWeightCountExtracted;
      }

      // 3. BoundsArraySet
      {
        { // Build self BoundsArraySet.
          this.boundsArraySet = new BoundsArraySet.InputsOutputs( inputScaleBoundsArray, null,
            this.pointwise.boundsArraySet.output0.channelCount, 0 );

          this.boundsArraySet.set_outputs_all_byBoundsArraySet_Outputs( this.pointwise.boundsArraySet );
        }

        this.dispose_all_sub_BoundsArraySet(); // For reduce memory footprint.
      }
    }

    this.bInitOk = true;
    return this.bInitOk;
  }

  /** Release all tensors. */
  disposeTensors() {
    if ( this.squeezeExcitation ) {
      this.squeezeExcitation.disposeTensors();
      this.squeezeExcitation = null;
    }

    if ( this.pointwise ) {
      this.pointwise.disposeTensors();
      this.pointwise = null;
    }

    this.tensorWeightCountTotal = this.tensorWeightCountExtracted = 0;
    this.byteOffsetBegin = this.byteOffsetEnd = -1;
    this.bKeepInputTensor = false;  // Default will dispose input tensor.
    this.bInitOk = false;
  }

  /**
   * Release all BoundsArraySet of squeezeExcitation, pointwise.
   *
   * This could reduce memory footprint.
   *
   * (Note: This Pointwise.SameWhenPassThrough_PrefixSqueezeExcitation's BoundsArraySet is kept.)
   */
  dispose_all_sub_BoundsArraySet() {
    delete this.squeezeExcitation?.boundsArraySet;
    delete this.pointwise.boundsArraySet;
  }

//!!! ...unfinished... (2022/05/19)

  /**
   * The sub operations' setKeepInputTensor() will be called so that only the first operation is responsible for keeping inputTensor.
   * All other operations should always destroy inputTensor..
   *
   */
  setKeepInputTensor( bKeepInputTensor ) {
    if ( bKeepInputTensor == this.bKeepInputTensor )
      return;

    this.bKeepInputTensor = bKeepInputTensor;
    if ( bKeepInputTensor ) {

//!!! ...unfinished... (2022/05/19)

      // Note: The first operation is responsible for keep inputTensor. All other operations should always destroy inputTensor.
      if ( this.squeezeDepthwise ) {
        this.squeezeDepthwise.setKeepInputTensor( true );
        this.intermediatePointwise.setKeepInputTensor( false );
        this.excitationPointwise.setKeepInputTensor( false );
      } else {
        if ( this.intermediatePointwise ) {
          this.intermediatePointwise.setKeepInputTensor( true );
          this.excitationPointwise.setKeepInputTensor( false );
        } else {
          this.excitationPointwise.setKeepInputTensor( true );
        }
      }

    } else {
      this.squeezeDepthwise?.setKeepInputTensor( false );
      this.intermediatePointwise?.setKeepInputTensor( false );
      this.excitationPointwise.setKeepInputTensor( false );
    }
  }

  get bSqueeze() {
    if ( !this.squeezeExcitation )
      return false; // Since no squeeze-and-excitation, there will be no squeeze.
    return this.squeezeExcitation.bSqueeze;
  }

  /** Determine data member this.bExisted
   *
   * @param {Base} this  The Base object to be determined and modified.
   */
  static setup_bExisted() {

//!!! ...unfinished... (2022/05/20) bExisted
// If ( outputChannelCount <= 0 ), no squeeze-and-excitation and no pointwise.
//
// Problem: ( outputChannelCount <= 0 ) but ( channelShuffler_outputGroupCount > 0 ),
//          the pointwise still exists (all-pass-through-and-channel-shuffling).
//
//

    if ( this.outputChannelCount <= 0 ) {
      this.bExisted = false;
    } else {
      this.bExisted = true;
    }
  }

  /** Determine data member this.bSqueezeExcitation
   *
   * @param {Base} this  The Base object to be determined and modified.
   */
  static setup_bSqueezeExcitation() {
    if ( this.bExisted == false ) {
      this.bSqueezeExcitation = false;
    } else {
      if ( this.nSqueezeExcitationChannelCountDivisor == ValueDesc.SqueezeExcitationChannelCountDivisor.Singleton.Ids.NONE ) { // (-2)
        this.bSqueezeExcitation = false;
      } else {
        this.bSqueezeExcitation = true;
      }
    }
  }

  /** Determine data member this.apply.
   *
   * @param {Base} this
   *   The Base object to be determined and modified.
   */
  static setup_pfn() {

//!!! ...unfinished... (2022/05/20) bExisted
// If ( bExisted == false ) (after pointwise is created), the squeezeExcitation should also be skipped.

    if ( this.bExisted ) {
      if ( this.bSqueezeExcitation ) {
        this.apply = Base.squeezeExcitation_pointwise;
      } else {
        this.apply = Base.pointwise;
      }
    } else { // There is no operation at all.
      this.apply = Base.return_input_directly;
    }
  }

  /** */
  static pointwise( inputTensor ) {
    return this.pointwise.apply( inputTensor );
  }

  /** */
  static squeezeExcitation_pointwise( inputTensor ) {
    let t0, t1;
    t0 = this.squeezeExcitation.apply( inputTensor );
    t1 = this.pointwise.apply( t0 );
    return t1;
  }

}
<|endoftext|>