<commit_before>define([
  "backbone",
  "app/views/notes-item",
  "app/models/note"
], function (Backbone, NotesItemView, NoteModel) {

  // TODO: IMPLEMENT!!!!
  describe.skip("app/views/notes-item", function () {
    // Don't need to specify fixtures, as rendering creates an
    // unattached element that the app manually appends, and we
    // directly check here.
    beforeEach(function () {
      sinon.stub(NotesItemView.prototype, "remove");
      this.navigate = sinon.stub(Backbone.history, "navigate");

      this.view = new NotesItemView({
        model: new NoteModel({ id: "0", title: "title" })
      });
    });

    afterEach(function () {
      NotesItemView.prototype.remove.restore();
      this.navigate.restore();
      this.view.remove();
    });

    describe("remove", function () {
      it("is removed on model destroy", function () {
        this.view.model.trigger("destroy");
        expect(this.view.remove.callCount).toBe(1);
      });
    });

    describe("render", function () {
      // One way to verify is with a stub.
      it("renders on model change w/ stub", sinon.test(function () {
        // Stub view and re-init to bind.
        this.stub(this.view, "render");
        this.view.initialize();

        this.view.model.trigger("change");
        expect(this.view.render.callCount).toBe(1);
      }));

      // Here is another way to do the same check with a mock.
      it("renders on model change w/ mock", sinon.test(function () {
        // Mock view and re-init to bind.
        var exp = this.mock(this.view).expects("render").once();
        this.view.initialize();

        this.view.model.trigger("change");
        exp.verify();
      }));
    });

    // -- Omitted in Book. --
    describe("DOM", function () {
      it("renders data to HTML", function () {
        var $item = this.view.render().$el;

        // Should set `id` on DOM element and title.
        expect($item.attr("id")).toBe(this.view.model.id);
        expect($item.find(".note-title").text()).toBe("title");
      });
    });

    describe("actions", function () {
      it("views on click", function () {
        this.view.render().$(".note-view").click();

        expect(this.navigate.callCount).toBe(1);
        expect(this.navigate.calledWith("note/0/view")).toBe(true);
      });

      it("edits on click", function () {
        this.view.render().$(".note-edit").click();

        expect(this.navigate.callCount).toBe(1);
        expect(this.navigate.calledWith("note/0/edit")).toBe(true);
      });

      it("deletes on click", sinon.test(function () {
        // Empty stub for model destroy to prevent side effects.
        this.stub(this.view.model, "destroy");
        this.view.render().$(".note-delete").click();

        expect(this.view.model.destroy.callCount).toBe(1);
      }));
    });
  });
});

/* Backbone Testing References
 *
 * **See**
 * http://backbone-testing.com/chapters/05/test/test.html
 * http://backbone-testing.com/chapters/05/test/js/spec/views/notes-item.spec.js
 * http://backbone-testing.com/notes/test/test.html?grep=App.Views.NotesItem
 */
<commit_msg>app/views/notes-item: Port tests<commit_after>define([
  "backbone",
  "app/views/notes-item",
  "app/models/note"
], function (Backbone, NotesItemView, NoteModel) {

  describe("app/views/notes-item", function () {
    // Don't need to specify fixtures, as rendering creates an
    // unattached element that the app manually appends, and we
    // directly check here.
    before(function () {
      sinon.stub(NotesItemView.prototype, "remove");
      this.navigate = sinon.stub(Backbone.history, "navigate");

      this.view = new NotesItemView({
        model: new NoteModel({ id: "0", title: "title" })
      });
    });

    afterEach(function () {
      this.navigate.reset();
    });

    after(function () {
      NotesItemView.prototype.remove.restore();
      this.navigate.restore();
      this.view.remove();
    });

    describe("remove", function () {
      it("is removed on model destroy", function () {
        this.view.model.trigger("destroy");
        expect(this.view.remove).to.be.calledOnce;
      });
    });

    describe("render", function () {
      // One way to verify is with a stub.
      it("renders on model change w/ stub", sinon.test(function () {
        // Stub view and re-init to bind.
        this.stub(this.view, "render");
        this.view.initialize();

        this.view.model.trigger("change");
        expect(this.view.render).to.have.been.calledOnce;
      }));

      // Here is another way to do the same check with a mock.
      it("renders on model change w/ mock", sinon.test(function () {
        // Mock view and re-init to bind.
        var exp = this.mock(this.view).expects("render").once();
        this.view.initialize();

        this.view.model.trigger("change");
        exp.verify();
      }));
    });

    // -- Omitted in Book. --
    describe("DOM", function () {
      it("renders data to HTML", function () {
        var $item = this.view.render().$el;

        // Should set `id` on DOM element and title.
        expect($item.attr("id")).to.equal(this.view.model.id);
        expect($item.find(".note-title").text()).to.equal("title");
      });
    });

    describe("actions", function () {
      it("views on click", function () {
        this.view.$(".note-view").click();

        expect(this.navigate)
          .to.be.calledOnce.and
          .to.be.calledWith("note/0/view");
      });

      it("edits on click", function () {
        this.view.$(".note-edit").click();

        expect(this.navigate)
          .to.be.calledOnce.and
          .to.be.calledWith("note/0/edit");
      });

      it("deletes on click", sinon.test(function () {
        // Empty stub for model destroy to prevent side effects.
        this.stub(this.view.model, "destroy");
        this.view.$(".note-delete").click();

        expect(this.view.model.destroy).to.be.calledOnce;
      }));
    });
  });
});

/* Backbone Testing References
 *
 * **See**
 * http://backbone-testing.com/chapters/05/test/test.html
 * http://backbone-testing.com/chapters/05/test/js/spec/views/notes-item.spec.js
 * http://backbone-testing.com/notes/test/test.html?grep=App.Views.NotesItem
 */
<|endoftext|>


<commit_before>// ==========================================================================
//                          DG.GameView
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

sc_require('components/game/game_controller');
sc_require('controllers/game_selection');

/** @class

  (Document Your View Here)

  @extends SC.WebView
*/
DG.GameView = SC.WebView.extend(
/** @scope DG.GameView.prototype */ {

  // Bind the 'value' property of the WebView, which determines
  // the URL of the page that is displayed, to the 'currentURL'
  // property of the global DG.gameSelectionController. If we
  // ever wanted to support multiple game instances in a single
  // document, we would need to bind to something like a
  // providerContext.currentUrl, where providerContext is an
  // instance of the DG.ProviderContext class, and a single
  // document can contain multiple DG.ProviderContext instances.
  valueBinding: 'DG.gameSelectionController.currentUrl',

  destroy: function() {
    DG.gameSelectionController.gameViewWillClose();
    sc_super();
  },

  iframeDidLoad: function()
  {
    var iframe = this.$('iframe')[0];

    if (iframe && iframe.contentWindow) {
      var contentWindow = iframe.contentWindow,
          target = DG.currGameController;

      // Allow the iframe to take over the entire screen (requested by InquirySpace)
      $(iframe ).attr('allowfullscreen', true)
        .attr('webkitallowfullscreen', true)
        .attr('mozallowfullscreen', true);

      // Assign the callback functions as properties of the iframe's contentWindow.
      // Note that the callbacks use SC.run() to make sure that SproutCore's runloop
      // has a chance to propagate bindings and data changes. See "Why Does SproutCore
      // Have a Run Loop and When Does It Execute?" at
      // http://frozencanuck.wordpress.com/2010/12/21/why-does-sproutcore-have-a-run-loop-and-when-does-it-execute/
      // for details of why this is necessary. In its concluding paragraph, it states
      // "Therefore the run loop is also used to drive data propagation via binding whenever
      // an asynchronous event is fired in order to drive the application." These callbacks
      // from the game are just such an asynchronous event, and so must invoke the runloop
      // to operate properly.

      // TODO: Eliminate all callbacks but DoCommand() once clients no longer call them.

      // NewCollectionWithAttributes
      contentWindow.NewCollectionWithAttributes =
        function(iCollectionName, iAttributeNames) {
          SC.run( function() {
                    target.newCollectionWithAttributes(iCollectionName,iAttributeNames);
                  });
        };

      // AddCaseToCollectionWithValues
      contentWindow.AddCaseToCollectionWithValues =
        function(iCollectionName, iValues) {
          SC.run( function() {
                    target.addCaseToCollectionWithValues(iCollectionName,iValues);
                  });
        };

      // LogUserAction
      contentWindow.LogUserAction =
        function(iActionString, iValues) {
          SC.run( function() {
                    target.logUserAction(iActionString,iValues);
                  });
        };

      // DoCommand
      contentWindow.DoCommand =
        function(iCmd) {
          var result;
          SC.run( function() {
                    result = target.doCommand(iCmd);
                  });
          return SC.json.encode( result);
        };
    } else {
      DG.logWarn("DG.GameView:iframeDidLoad no contentWindow\n");
    }
    sc_super();
  }

});
<commit_msg>use iframePhone to talk to game iframe<commit_after>// ==========================================================================
//                          DG.GameView
//
//  Copyright (c) 2014 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

/* globals iframePhone */
sc_require('components/game/game_controller');
sc_require('controllers/game_selection');
sc_require('libraries/iframe-phone');

/** @class

  (Document Your View Here)

  @extends SC.WebView
*/
DG.GameView = SC.WebView.extend(
/** @scope DG.GameView.prototype */ {

  // Bind the 'value' property of the WebView, which determines
  // the URL of the page that is displayed, to the 'currentURL'
  // property of the global DG.gameSelectionController. If we
  // ever wanted to support multiple game instances in a single
  // document, we would need to bind to something like a
  // providerContext.currentUrl, where providerContext is an
  // instance of the DG.ProviderContext class, and a single
  // document can contain multiple DG.ProviderContext instances.
  valueBinding: 'DG.gameSelectionController.currentUrl',

  // Setup iframePhone communication with the child iframe before it loads, so that connection
  // (iframe src will change when 'value' changes, but observers fire before bindings are synced)
  valueDidChange: function() {
    var value = this.get('value');

    if (value !== this._previousValue) {

      // First discontinue listening to old game.
      if (DG.gamePhone) {
        DG.gamePhone.disconnect();
      }

      DG.gamePhone = new iframePhone.IframePhoneRpcEndpoint(
        function(command, callback) {
          // TODO. The following May throw a DataCloneError if  there is an Error object in the
          // result from DG.doCommand (it appears to me that the requestAttributeValues and
          // requestFormulaValues commands may include caught Error objects as values in the
          // returned object -- rklancer)
          callback(DG.doCommand(command));
        },
        'codap-game',
        this.$('iframe')[0],
        DG.gameSelectionController.getPath('currentGame.origin')
      );
    }

    this._previousValue = value;

  }.observes('value'),

  destroy: function() {
    DG.gameSelectionController.gameViewWillClose();
    sc_super();
  },

  iframeDidLoad: function()
  {
    var iframe = this.$('iframe')[0];

    if (iframe && iframe.contentWindow) {
      var contentWindow = iframe.contentWindow,
          target = DG.currGameController;

      // Allow the iframe to take over the entire screen (requested by InquirySpace)
      $(iframe ).attr('allowfullscreen', true)
        .attr('webkitallowfullscreen', true)
        .attr('mozallowfullscreen', true);

      // Assign the callback functions as properties of the iframe's contentWindow.
      //
      // Note that the callbacks use SC.run() to make sure that SproutCore's runloop
      // has a chance to propagate bindings and data changes. See "Why Does SproutCore
      // Have a Run Loop and When Does It Execute?" at
      // http://frozencanuck.wordpress.com/2010/12/21/why-does-sproutcore-have-a-run-loop-and-when-does-it-execute/
      // for details of why this is necessary. In its concluding paragraph, it states
      // "Therefore the run loop is also used to drive data propagation via binding whenever
      // an asynchronous event is fired in order to drive the application." These callbacks
      // from the game are just such an asynchronous event, and so must invoke the runloop
      // to operate properly.
      //
      // Furthermore, note that these callbacks cannot be added, and an exception will be thrown, if
      // the game is hosted on another domain. Ignore that because we use HTML5 Web Messaging
      // ("postMessage") via IframePhone to talk to these games, which do not require the callbacks
      // below.

      try {

        // TODO: Eliminate all callbacks but DoCommand() once clients no longer call them.

        // NewCollectionWithAttributes
        contentWindow.NewCollectionWithAttributes =
          function(iCollectionName, iAttributeNames) {
            SC.run( function() {
                      target.newCollectionWithAttributes(iCollectionName,iAttributeNames);
                    });
          };

        // AddCaseToCollectionWithValues
        contentWindow.AddCaseToCollectionWithValues =
          function(iCollectionName, iValues) {
            SC.run( function() {
                      target.addCaseToCollectionWithValues(iCollectionName,iValues);
                    });
          };

        // LogUserAction
        contentWindow.LogUserAction =
          function(iActionString, iValues) {
            SC.run( function() {
                      target.logUserAction(iActionString,iValues);
                    });
          };

        // DoCommand
        contentWindow.DoCommand =
          function(iCmd) {
            var result;
            SC.run( function() {
                      result = target.doCommand(iCmd);
                    });
            return SC.json.encode( result);
          };
      } catch (e) {
        // e should be a SecurityError but I haven't found documentation regarding how standard
        // that error type is.
      }
    } else {
      DG.logWarn("DG.GameView:iframeDidLoad no contentWindow\n");
    }
    sc_super();
  }

});
<|endoftext|>


<commit_before>//Gulp plugin
var gulp = require("gulp"),//http://gulpjs.com/
		util = require("gulp-util"),//https://github.com/gulpjs/gulp-util
		sass = require("gulp-sass"),//https://www.npmjs.org/package/gulp-sass
		autoprefixer = require('gulp-autoprefixer'),//https://www.npmjs.org/package/gulp-autoprefixer
		rename = require('gulp-rename'),//https://www.npmjs.org/package/gulp-rename,
    del=require('del'),//https://github.com/gulpjs/gulp/blob/master/docs/recipes/delete-files-folder.md
    uglify=require('gulp-uglify'),//https://www.npmjs.com/package/gulp-uglify
    concat=require('gulp-concat'),//https://github.com/wearefractal/gulp-concat
    jshint=require('gulp-jshint'),//https://www.npmjs.com/package/gulp-jshint
    wrapper = require('gulp-wrapper'), //https://www.npmjs.com/package/gulp-wrapper
		log = util.log,
    gulpif=require('gulp-if'),
    pump = require('pump'),
    runSequence = require('run-sequence'),
    sourcemaps = require('gulp-sourcemaps');

/* TODO - test image minification
    imagemin = require('gulp-imagemin'),
    pngquant = require('imagemin-pngquant'); // $ npm i -D imagemin-pngquant
*/

var config = {
  images: 'images/*',
  dist: 'target'
};

var env = process.env.NODE_ENV || 'dev'; //environment variable that defaults to 'dev'

var sassFiles = "src/sass/**/*.scss";
gulp.task("sass", function(){
  log("Generate CSS files " + (new Date()).toString());

  var sassOptions = {
    errLogToConsole: true
  };

  if(env === 'dev'){
    sassOptions.outputStyle = 'expanded';
    //sassOptions.sourceComments = 'map';
  }

  if(env === 'prod'){
    sassOptions.outputStyle = 'compressed';
  }

  gulp.src(sassFiles)
      .pipe(gulpif(env ==='dev', sourcemaps.init()))
      .pipe(sass(sassOptions).on('error', sass.logError))
      .pipe(autoprefixer("last 3 version","safari 5", "ie 8", "ie 9"))
      .pipe(gulpif(env ==='dev', sourcemaps.write()))
      .pipe(gulp.dest("target/css"))
});

//copy fonts from source ("static/src/fonts")to the "css" directory because they are referenced by the css files
gulp.task('copy:fonts', function() {
  gulp.src('src/resources/fonts/**/*.{ttf,woff,eof,svg,eot}')
    .pipe(gulp.dest('target/css/fonts'));
});

//deletes content of the target directory, sort of a "maven clean" functionality
gulp.task('clean', function(cb){
    del(config.dist+'/**/*', cb);
});

//delete content of "css" folder, before creating a new one
gulp.task('clean:css', function(cb){
  del.sync('target/css/**/*', cb);//https://github.com/sindresorhus/del#delsyncpatterns-options
});

var jsFiles = "src/js/podcastpedia/**/*.js";
gulp.task('js', function() {
    return gulp.src(jsFiles)
        .pipe(gulpif(env ==='dev', sourcemaps.init()))
        .pipe(jshint())
        .pipe(concat('app.js'))
        .pipe(gulpif(env ==='prod', uglify()))
        .pipe(wrapper({
          header: '$( document ).ready(function() {' + '\n',
          footer: '\n' + '});'
        }))
        .pipe(gulpif(env ==='dev', sourcemaps.write()))
        .pipe(gulp.dest('target/js'));
});

gulp.task('jshint', function() {
    gulp.src('target/js/*.js')
        .pipe(jshint())
        //.pipe(jshint.reporter('default'));
        .pipe(jshint.reporter('jshint-stylish'));
});

//minimize images
/*
gulp.task('min-images', () => {
  return gulp.src(config.images)
    .pipe(imagemin({
      progressive: true,
      svgoPlugins: [
        {removeViewBox: false},
        {cleanupIDs: false}
      ],
      use: [pngquant()]
    }))
    .pipe(gulp.dest('target/images'));
});
*/

gulp.task("build", ["clean", "copy:fonts", "sass", 'js']);

gulp.task("watch", function(){
  log("Watching scss files for modifications");
  gulp.watch(sassFiles, ["sass"]);

  log("Watching js files for modifications");
  gulp.watch(jsFiles, ["js"]);

});

//task is executed when running only the "gulp" command
//gulp.task('default', ['build']);
gulp.task('default', function() {
  runSequence('build');
});
<commit_msg>add some spaces<commit_after>//Gulp plugin
var gulp = require("gulp"),//http://gulpjs.com/
		util = require("gulp-util"),//https://github.com/gulpjs/gulp-util
		sass = require("gulp-sass"),//https://www.npmjs.org/package/gulp-sass
		autoprefixer = require('gulp-autoprefixer'),//https://www.npmjs.org/package/gulp-autoprefixer
		rename = require('gulp-rename'),//https://www.npmjs.org/package/gulp-rename,
    del=require('del'),//https://github.com/gulpjs/gulp/blob/master/docs/recipes/delete-files-folder.md
    uglify=require('gulp-uglify'),//https://www.npmjs.com/package/gulp-uglify
    concat=require('gulp-concat'),//https://github.com/wearefractal/gulp-concat
    jshint=require('gulp-jshint'),//https://www.npmjs.com/package/gulp-jshint
    wrapper = require('gulp-wrapper'), //https://www.npmjs.com/package/gulp-wrapper
		log = util.log,
    gulpif=require('gulp-if'),
    pump = require('pump'),
    runSequence = require('run-sequence'),
    sourcemaps = require('gulp-sourcemaps');

/* TODO - test image minification
    imagemin = require('gulp-imagemin'),
    pngquant = require('imagemin-pngquant'); // $ npm i -D imagemin-pngquant
*/

var config = {
  images: 'images/*',
  dist: 'target'
};

var env = process.env.NODE_ENV || 'dev'; //environment variable that defaults to 'dev'

var sassFiles = "src/sass/**/*.scss";
gulp.task("sass", function(){
  log("Generate CSS files " + (new Date()).toString());

  var sassOptions = {
    errLogToConsole: true
  };

  if(env === 'dev'){
    sassOptions.outputStyle = 'expanded';
    //sassOptions.sourceComments = 'map';
  }

  if(env === 'prod'){
    sassOptions.outputStyle = 'compressed';
  }

  gulp.src(sassFiles)
      .pipe(gulpif(env ==='dev', sourcemaps.init()))
      .pipe(sass(sassOptions).on('error', sass.logError))
      .pipe(autoprefixer("last 3 version","safari 5", "ie 8", "ie 9"))
      .pipe(gulpif(env ==='dev', sourcemaps.write()))
      .pipe(gulp.dest("target/css"))
});

//copy fonts from source ("static/src/fonts")to the "css" directory because they are referenced by the css files
gulp.task('copy:fonts', function() {
  gulp.src('src/resources/fonts/**/*.{ttf,woff,eof,svg,eot}')
    .pipe(gulp.dest('target/css/fonts'));
});

//deletes content of the target directory, sort of a "maven clean" functionality
gulp.task('clean', function(cb){
    del(config.dist + '/**/*', cb);
});

//delete content of "css" folder, before creating a new one
gulp.task('clean:css', function(cb){
  del.sync('target/css/**/*', cb);//https://github.com/sindresorhus/del#delsyncpatterns-options
});

var jsFiles = "src/js/podcastpedia/**/*.js";
gulp.task('js', function() {
    return gulp.src(jsFiles)
        .pipe(gulpif(env ==='dev', sourcemaps.init()))
        .pipe(jshint())
        .pipe(concat('app.js'))
        .pipe(gulpif(env ==='prod', uglify()))
        .pipe(wrapper({
          header: '$( document ).ready(function() {' + '\n',
          footer: '\n' + '});'
        }))
        .pipe(gulpif(env ==='dev', sourcemaps.write()))
        .pipe(gulp.dest('target/js'));
});

gulp.task('jshint', function() {
    gulp.src('target/js/*.js')
        .pipe(jshint())
        //.pipe(jshint.reporter('default'));
        .pipe(jshint.reporter('jshint-stylish'));
});

//minimize images
/*
gulp.task('min-images', () => {
  return gulp.src(config.images)
    .pipe(imagemin({
      progressive: true,
      svgoPlugins: [
        {removeViewBox: false},
        {cleanupIDs: false}
      ],
      use: [pngquant()]
    }))
    .pipe(gulp.dest('target/images'));
});
*/

gulp.task("build", ["clean", "copy:fonts", "sass", 'js']);

gulp.task("watch", function(){
  log("Watching scss files for modifications");
  gulp.watch(sassFiles, ["sass"]);

  log("Watching js files for modifications");
  gulp.watch(jsFiles, ["js"]);

});

//task is executed when running only the "gulp" command
//gulp.task('default', ['build']);
gulp.task('default', function() {
  runSequence('build');
});
<|endoftext|>


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

import ChangesLinks from 'es6!display/changes/links';
import { ChangesPage, APINotLoadedPage } from 'es6!display/page_chrome';
import { Error } from 'es6!display/errors';
import { ManyBuildsStatus } from 'es6!display/changes/builds';
import { TimeText } from 'es6!display/time';
import { get_build_cause } from 'es6!display/changes/build_text';
import { get_runnable_condition, get_runnable_condition_short_text, get_runnable_condition_color_cls } from 'es6!display/changes/build_conditions';

import Sidebar from 'es6!pages/builds_pages/sidebar';
import { SingleBuild, LatestBuildsSummary } from 'es6!pages/builds_pages/build_info';

import * as api from 'es6!server/api';

import * as utils from 'es6!utils/utils';

/*
 * The pages that show the results of builds run on a commit or diff. They're
 * just wrappers around BuildsPage
 */
// TODO: I need a page that just shows a single build, e.g. for arc test.

/**
 * Page that shows the builds associated with a single diff
 */
export var DiffPage = React.createClass({
  getInitialTitle: function() {
    return `${this.props.diff_id}: Builds`;
  },

  getInitialState: function() {
    return {
      diffBuilds: null,
    }
  },

  componentDidMount: function() {
    var diff_id = this.props.diff_id;
    api.fetch(this, {
      diffBuilds: `/api/0/phabricator_diffs/${diff_id}/builds`
    });
  },

  render: function() {
    if (!api.isLoaded(this.state.diffBuilds)) {
      return <APINotLoadedPage calls={this.state.diffBuilds} />;
    }
    var diff_data = this.state.diffBuilds.getReturnedData();
    // Note: if the "fetched_data_from_phabricator" key is false, we weren't
    // able to reach phabricator. We still have builds data that we want to
    // render...just do our best to deal with the missing phabricator data.

    // TODO: delete
    diff_data['fetched_data_from_phabricator'] = true;

    // emergency backups in case phabricator is unreachable
    diff_data['revision_id'] = diff_data['revision_id'] || this.props.diff_id.substr(1);
    diff_data['dateCreated'] = diff_data['dateCreated'] || 0; // unix timestamp

    var builds = _.chain(diff_data.changes)
      .pluck('builds')
      .flatten()
      .value();

    return <BuildsPage
      type="diff"
      targetData={diff_data}
      builds={builds}
    />;
  }
});

/**
 * Page that shows the builds associated with a single commit
 */
export var CommitPage = React.createClass({

  getInitialState: function() {
    return {
      commitBuilds: null,
      source: null,
    }
  },

  componentDidMount: function() {
    var uuid = this.props.sourceUUID;

    // Specify the per_page param to get as many builds as possible.
    // BuildsPage.getContent() below assumes that a selected ID is present in
    // the list, and if the build is missing it crashes the page. Get as many
    // builds as possible up front to minimize the chances of this happening,
    // as a quick workaround.
    api.fetch(this, {
      commitBuilds: `/api/0/sources_builds/?source_id=${uuid}&per_page=100`,
      source: `/api/0/sources/${uuid}`
    });
  },

  render: function() {
    var slug = this.props.project;

    // special-case source API errors...it might be because the commit contains unicode
    if (api.isError(this.state.source)) {
      if (!api.isLoaded(this.state.commitBuilds)) {
        return <APINotLoadedPage calls={this.state.commitBuilds} />;
      }

      var links = _.map(this.state.commitBuilds.getReturnedData(), b => {
        var href = URI(`/single_build/${b.id}/`);
        var condition = get_runnable_condition(b);
        return

          <TimeText time={b.dateFinished || b.dateStarted || b.dateCreated} />
          {": "}
          {b.project.name}
          {" ("}

            {get_runnable_condition_short_text(condition)}

          {")"}

      });

      return <ChangesPage>

          We couldn{"'"}t load this commit. Oftentimes this is because it
          contains unicode characters, which we don{"'"}t properly support. Rest
          assured that we feel both regret and self-loathing about this.

          Here are links to the individual builds. Hopefully you{"'"}ll have a
          better chance loading those pages:

          {links}

      </ChangesPage>;
    }

    if (!api.allLoaded([this.state.commitBuilds, this.state.source])) {
      return <APINotLoadedPage
        calls={[this.state.commitBuilds, this.state.source]}
      />;
    }

    var sha = this.state.source.getReturnedData().revision.sha;
    utils.setPageTitle(`${sha.substr(0, 7)}: Builds`);

    return <BuildsPage
      type="commit"
      targetData={this.state.source.getReturnedData()}
      builds={this.state.commitBuilds.getReturnedData()}
    />;
  }
});

/** ---IMPLEMENTATION--- **/

/**
 * The internal page shared by CommitPage and DiffPage (since the logic is
 * basically the same)
 */
var BuildsPage = React.createClass({

  propTypes: {
    // are we rendering for a diff or a commit
    type: PropTypes.oneOf(['diff', 'commit']).isRequired,
    // info about the commit (a changes source object) or diff (from phab.)
    targetData: PropTypes.object,
    // the builds associated with this diff/commit. They may be more sparse
    // than a call to build_details...we use this to populate the sidebar
    builds: PropTypes.array.isRequired,
  },

  getInitialState: function() {
    var query_params = URI(window.location.href).search(true);

    return {
      activeBuildID: query_params.buildID,
      tests: {}, // fetched on demand
    }
  },

  render: function() {
    this.updateWindowUrl();

    var activeBuild = _.filter(
      this.props.builds,
      b => b.id === this.state.activeBuildID)[0];

    // TODO: cleanup!
    return <ChangesPage
      bodyPadding={false}
      fixed={true}>

        {this.renderLabelHeader()}

      <Sidebar
        builds={this.props.builds}
        type={this.props.type}
        targetData={this.props.targetData}
        activeBuildID={this.state.activeBuildID}
        pageElem={this}
      />

          {this.getErrorMessage()}
          {this.getContent()}

    </ChangesPage>;
  },

  updateWindowUrl: function() {
    var query_params = URI(window.location.href).search(true);
    if (this.state.activeBuildID !== query_params['buildID']) {
      query_params['buildID'] = this.state.activeBuildID;
      window.history.replaceState(
        null,
        'changed tab',
        URI(window.location.href)
          .search(_.pick(query_params, value => !!value))
          .toString()
      );
    }
  },

  getErrorMessage: function() {
    if (this.props.type === 'diff') {
      var diff_data = this.props.targetData;
      if (!diff_data["fetched_data_from_phabricator"]) {
        return <Error className="marginBottomM">
          Unable to get diff data from Phabricator!
        </Error>;
      }
    }
    return null;
  },

  getContent: function() {
    var builds = this.props.builds;

    if (this.state.activeBuildID) {
      var build = _.filter(builds, b => b.id === this.state.activeBuildID);
      if (build) {
        // use a key so that we remount when switching builds
        return {
          [ build[0].id ]:
            <SingleBuild
              build={build[0]}
            />
        };
      }
    }

    // get all builds for latest code
    var latest_builds = builds;

    if (this.props.type === 'diff') {
      var builds_by_diff_id = _.groupBy(
        builds,
        b => b.source.data['phabricator.diffID']);

      var latest_diff_id = _.chain(builds_by_diff_id)
        .keys()
        .sortBy()
        .last()
        .value();

      latest_builds = builds_by_diff_id[latest_diff_id];
    }

    return <LatestBuildsSummary
      builds={latest_builds}
      type={this.props.type}
      targetData={this.props.targetData}
      pageElem={this}
    />;
  },

  renderLabelHeader: function() {
    var type = this.props.type;

    var header = "No header yet";
    if (type === 'commit') {
      var source = this.props.targetData;
      var authorLink = ChangesLinks.author(source.revision.author);
      var commitLink = ChangesLinks.phabCommitHref(source.revision);

      var parentElem = null;
      if (source.revision.parents && source.revision.parents.length > 0) {
        parentElem = <ParentCommit
          sha={source.revision.parents[0]}
          repoID={source.revision.repository.id}
          label={source.revision.parents.length <= 1 ? 'only' : 'first'}
        />;
      }

      header =

          <TimeText time={source.revision.dateCreated} />

          {source.revision.sha.substring(0,7)}

        {": "}
        {utils.truncate(utils.first_line(source.revision.message))}

          {"by "}
          {authorLink}
          {parentElem}

;
    } else if (type === 'diff') {
      var diffData = this.props.targetData;
      var authorLink = ChangesLinks.author(
        this.getAuthorForDiff(this.props.builds), true);

      var parentElem = null;
      var diffSource = this.getSourceForDiff(this.props.builds);
      if (diffSource) {  // maybe this is missing if we have no builds?
        parentElem = <ParentCommit
          sha={diffSource.revision.sha}
          repoID={diffSource.revision.repository.id}
          label="diffParent"
        />;
      }

      header =

          <TimeText time={moment.unix(diffData.dateCreated).toString()} />

          D{diffData.id}

        {": "}
        {utils.truncate(diffData.title)}

          {"by "}
          {authorLink}
          {parentElem}

;
    } else {
      throw 'unreachable';
    }

    return header;
  },

  getAuthorForDiff: function(builds) {
    // the author of any cause=phabricator build for a diff is always the
    // same as the author of the diff.
    var author = null;
    _.each(builds, b => {
      if (get_build_cause(b) === 'phabricator') {
        author = b.author;
      }
    });
    return author;
  },

  getSourceForDiff: function(builds) {
    return builds && builds.length && builds[0].source;
  }
});

export var SingleBuildPage = React.createClass({

  getInitialState: function() {
    return {
      build: null
    };
  },

  componentDidMount: function() {
    api.fetch(this, {
      build: `/api/0/builds/${this.props.buildID}`
    });
  },

  render: function() {
    if (!api.isLoaded(this.state.build)) {
      return <APINotLoadedPage calls={this.state.build} />;
    }
    var build = this.state.build.getReturnedData();

    utils.setPageTitle(`A ${build.project.name} Build`);

    return <ChangesPage>
      <SingleBuild build={build} />
    </ChangesPage>;
  },
});

var ParentCommit = React.createClass({
  getInitialState() {
    return { builds: null };
  },

  componentDidMount() {
    var sha = this.props.sha;
    var repoID = this.props.repoID;

    api.fetch(this, {
      builds: URI('/api/0/sources_builds/')
        .addQuery({ revision_sha: sha, repo_id: repoID })
        .toString()
    });
  },

  render() {
    var sha = this.props.sha;
    var repoID = this.props.repoID;
    var labelProp = this.props.label;

    var label = {
      only: 'Parent: ',
      first: 'First Parent: ',
      diffParent: 'Parent Commit: '
    }[labelProp];

    if (!api.isLoaded(this.state.builds)) {
      return ;
    }

    var builds = this.state.builds.getReturnedData();
    return
      ·
      {label}

        {sha.substr(0,7)}

      <ManyBuildsStatus
        builds={builds}
      />
    ;
  }
});
<commit_msg>When querying for all builds, loop on API pages instead of simply getting the first 100 builds.<commit_after>import React, { PropTypes } from 'react';
import moment from 'moment';

import ChangesLinks from 'es6!display/changes/links';
import { ChangesPage, APINotLoadedPage } from 'es6!display/page_chrome';
import { Error } from 'es6!display/errors';
import { ManyBuildsStatus } from 'es6!display/changes/builds';
import { TimeText } from 'es6!display/time';
import { get_build_cause } from 'es6!display/changes/build_text';
import { get_runnable_condition, get_runnable_condition_short_text, get_runnable_condition_color_cls } from 'es6!display/changes/build_conditions';

import Sidebar from 'es6!pages/builds_pages/sidebar';
import { SingleBuild, LatestBuildsSummary } from 'es6!pages/builds_pages/build_info';

import * as api from 'es6!server/api';

import * as utils from 'es6!utils/utils';

/*
 * The pages that show the results of builds run on a commit or diff. They're
 * just wrappers around BuildsPage
 */
// TODO: I need a page that just shows a single build, e.g. for arc test.

/**
 * Page that shows the builds associated with a single diff
 */
export var DiffPage = React.createClass({
  getInitialTitle: function() {
    return `${this.props.diff_id}: Builds`;
  },

  getInitialState: function() {
    return {
      diffBuilds: null,
    }
  },

  componentDidMount: function() {
    var diff_id = this.props.diff_id;
    api.fetch(this, {
      diffBuilds: `/api/0/phabricator_diffs/${diff_id}/builds`
    });
  },

  render: function() {
    if (!api.isLoaded(this.state.diffBuilds)) {
      return <APINotLoadedPage calls={this.state.diffBuilds} />;
    }
    var diff_data = this.state.diffBuilds.getReturnedData();
    // Note: if the "fetched_data_from_phabricator" key is false, we weren't
    // able to reach phabricator. We still have builds data that we want to
    // render...just do our best to deal with the missing phabricator data.

    // TODO: delete
    diff_data['fetched_data_from_phabricator'] = true;

    // emergency backups in case phabricator is unreachable
    diff_data['revision_id'] = diff_data['revision_id'] || this.props.diff_id.substr(1);
    diff_data['dateCreated'] = diff_data['dateCreated'] || 0; // unix timestamp

    var builds = _.chain(diff_data.changes)
      .pluck('builds')
      .flatten()
      .value();

    return <BuildsPage
      type="diff"
      targetData={diff_data}
      builds={builds}
    />;
  }
});

/**
 * Page that shows the builds associated with a single commit
 */
export var CommitPage = React.createClass({

  getInitialState: function() {
    return {
      commitBuilds: null,
      source: null,
    }
  },

  componentDidMount: function() {
    var uuid = this.props.sourceUUID;

    // BuildsPage.getContent() below assumes that a selected ID is present in
    // the list, and if the build is missing it crashes the page. Get as many
    // builds as possible up front to minimize the chances of this happening,
    // as a quick workaround.
    let commit_builds = [];

    let fetch_one_page_of_builds = (endpoint) => {
      api.make_api_ajax_get(
          endpoint,
          null,
          response => {
              let api_response = api.APIResponse(endpoint);
              api_response.response = response;
              let new_items = api_response.getReturnedData();
              commit_builds = commit_builds.concat(new_items);

              let new_endpoint = api_response.getLinksFromHeader();
              if ('next' in new_endpoint) {
                  fetch_one_page_of_builds(new_endpoint.next);
              } else {
                  this.setState({'commitBuilds': commit_builds});
              }
          },
          error => {
              console.log(`Error fetching builds. (${endpoint})`);
          });
    };

    // 100 is max page size.
    let endpoint = `/api/0/sources_builds/?source_id=${uuid}&per_page=100`;
    fetch_one_page_of_builds(endpoint);
    api.fetch(this, {
      source: `/api/0/sources/${uuid}`
    });
  },

  render: function() {
    var slug = this.props.project;

    // special-case source API errors...it might be because the commit contains unicode
    if (api.isError(this.state.source)) {
      if (this.state.commitBuilds === null) {
        return <APINotLoadedPage calls={this.state.commitBuilds} />;
      }

      var links = _.map(this.state.commitBuilds.getReturnedData(), b => {
        var href = URI(`/single_build/${b.id}/`);
        var condition = get_runnable_condition(b);
        return

          <TimeText time={b.dateFinished || b.dateStarted || b.dateCreated} />
          {": "}
          {b.project.name}
          {" ("}

            {get_runnable_condition_short_text(condition)}

          {")"}

      });

      return <ChangesPage>

          We couldn{"'"}t load this commit. Oftentimes this is because it
          contains unicode characters, which we don{"'"}t properly support. Rest
          assured that we feel both regret and self-loathing about this.

          Here are links to the individual builds. Hopefully you{"'"}ll have a
          better chance loading those pages:

          {links}

      </ChangesPage>;
    }

    if (this.state.commitBuilds === null || !api.allLoaded([this.state.source])) {
      return <APINotLoadedPage
        calls={[this.state.commitBuilds, this.state.source]}
      />;
    }

    var sha = this.state.source.getReturnedData().revision.sha;
    utils.setPageTitle(`${sha.substr(0, 7)}: Builds`);

    return <BuildsPage
      type="commit"
      targetData={this.state.source.getReturnedData()}
      builds={this.state.commitBuilds}
    />;
  }
});

/** ---IMPLEMENTATION--- **/

/**
 * The internal page shared by CommitPage and DiffPage (since the logic is
 * basically the same)
 */
var BuildsPage = React.createClass({

  propTypes: {
    // are we rendering for a diff or a commit
    type: PropTypes.oneOf(['diff', 'commit']).isRequired,
    // info about the commit (a changes source object) or diff (from phab.)
    targetData: PropTypes.object,
    // the builds associated with this diff/commit. They may be more sparse
    // than a call to build_details...we use this to populate the sidebar
    builds: PropTypes.array.isRequired,
  },

  getInitialState: function() {
    var query_params = URI(window.location.href).search(true);

    return {
      activeBuildID: query_params.buildID,
      tests: {}, // fetched on demand
    }
  },

  render: function() {
    this.updateWindowUrl();

    var activeBuild = _.filter(
      this.props.builds,
      b => b.id === this.state.activeBuildID)[0];

    // TODO: cleanup!
    return <ChangesPage
      bodyPadding={false}
      fixed={true}>

        {this.renderLabelHeader()}

      <Sidebar
        builds={this.props.builds}
        type={this.props.type}
        targetData={this.props.targetData}
        activeBuildID={this.state.activeBuildID}
        pageElem={this}
      />

          {this.getErrorMessage()}
          {this.getContent()}

    </ChangesPage>;
  },

  updateWindowUrl: function() {
    var query_params = URI(window.location.href).search(true);
    if (this.state.activeBuildID !== query_params['buildID']) {
      query_params['buildID'] = this.state.activeBuildID;
      window.history.replaceState(
        null,
        'changed tab',
        URI(window.location.href)
          .search(_.pick(query_params, value => !!value))
          .toString()
      );
    }
  },

  getErrorMessage: function() {
    if (this.props.type === 'diff') {
      var diff_data = this.props.targetData;
      if (!diff_data["fetched_data_from_phabricator"]) {
        return <Error className="marginBottomM">
          Unable to get diff data from Phabricator!
        </Error>;
      }
    }
    return null;
  },

  getContent: function() {
    var builds = this.props.builds;

    if (this.state.activeBuildID) {
      var build = _.filter(builds, b => b.id === this.state.activeBuildID);
      if (build) {
        // use a key so that we remount when switching builds
        return {
          [ build[0].id ]:
            <SingleBuild
              build={build[0]}
            />
        };
      }
    }

    // get all builds for latest code
    var latest_builds = builds;

    if (this.props.type === 'diff') {
      var builds_by_diff_id = _.groupBy(
        builds,
        b => b.source.data['phabricator.diffID']);

      var latest_diff_id = _.chain(builds_by_diff_id)
        .keys()
        .sortBy()
        .last()
        .value();

      latest_builds = builds_by_diff_id[latest_diff_id];
    }

    return <LatestBuildsSummary
      builds={latest_builds}
      type={this.props.type}
      targetData={this.props.targetData}
      pageElem={this}
    />;
  },

  renderLabelHeader: function() {
    var type = this.props.type;

    var header = "No header yet";
    if (type === 'commit') {
      var source = this.props.targetData;
      var authorLink = ChangesLinks.author(source.revision.author);
      var commitLink = ChangesLinks.phabCommitHref(source.revision);

      var parentElem = null;
      if (source.revision.parents && source.revision.parents.length > 0) {
        parentElem = <ParentCommit
          sha={source.revision.parents[0]}
          repoID={source.revision.repository.id}
          label={source.revision.parents.length <= 1 ? 'only' : 'first'}
        />;
      }

      header =

          <TimeText time={source.revision.dateCreated} />

          {source.revision.sha.substring(0,7)}

        {": "}
        {utils.truncate(utils.first_line(source.revision.message))}

          {"by "}
          {authorLink}
          {parentElem}

;
    } else if (type === 'diff') {
      var diffData = this.props.targetData;
      var authorLink = ChangesLinks.author(
        this.getAuthorForDiff(this.props.builds), true);

      var parentElem = null;
      var diffSource = this.getSourceForDiff(this.props.builds);
      if (diffSource) {  // maybe this is missing if we have no builds?
        parentElem = <ParentCommit
          sha={diffSource.revision.sha}
          repoID={diffSource.revision.repository.id}
          label="diffParent"
        />;
      }

      header =

          <TimeText time={moment.unix(diffData.dateCreated).toString()} />

          D{diffData.id}

        {": "}
        {utils.truncate(diffData.title)}

          {"by "}
          {authorLink}
          {parentElem}

;
    } else {
      throw 'unreachable';
    }

    return header;
  },

  getAuthorForDiff: function(builds) {
    // the author of any cause=phabricator build for a diff is always the
    // same as the author of the diff.
    var author = null;
    _.each(builds, b => {
      if (get_build_cause(b) === 'phabricator') {
        author = b.author;
      }
    });
    return author;
  },

  getSourceForDiff: function(builds) {
    return builds && builds.length && builds[0].source;
  }
});

export var SingleBuildPage = React.createClass({

  getInitialState: function() {
    return {
      build: null
    };
  },

  componentDidMount: function() {
    api.fetch(this, {
      build: `/api/0/builds/${this.props.buildID}`
    });
  },

  render: function() {
    if (!api.isLoaded(this.state.build)) {
      return <APINotLoadedPage calls={this.state.build} />;
    }
    var build = this.state.build.getReturnedData();

    utils.setPageTitle(`A ${build.project.name} Build`);

    return <ChangesPage>
      <SingleBuild build={build} />
    </ChangesPage>;
  },
});

var ParentCommit = React.createClass({
  getInitialState() {
    return { builds: null };
  },

  componentDidMount() {
    var sha = this.props.sha;
    var repoID = this.props.repoID;

    api.fetch(this, {
      builds: URI('/api/0/sources_builds/')
        .addQuery({ revision_sha: sha, repo_id: repoID })
        .toString()
    });
  },

  render() {
    var sha = this.props.sha;
    var repoID = this.props.repoID;
    var labelProp = this.props.label;

    var label = {
      only: 'Parent: ',
      first: 'First Parent: ',
      diffParent: 'Parent Commit: '
    }[labelProp];

    if (!api.isLoaded(this.state.builds)) {
      return ;
    }

    var builds = this.state.builds.getReturnedData();
    return
      ·
      {label}

        {sha.substr(0,7)}

      <ManyBuildsStatus
        builds={builds}
      />
    ;
  }
});
<|endoftext|>


<commit_before>

function Audixel() {
  this.audioPath = [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1];
}

<commit_msg>Implémentation de Audixel - décodage complet<commit_after>// Interface between Pixels and audio data

function Audixel() {
    this.audioPath = [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1];
    this.center = 128.0;
    this.amp = 127.0;

    this.indexToCoord = function(index) {
        var coord = [0, 0];
        var mask = [1, 1];

        for (var p = 0; p < this.audioPath.length; p++) {
            coord[this.audioPath[p]] |= (index & 1) * mask[this.audioPath[p]];
            index >>= 1; mask[this.audioPath[p]] <<= 1;
        }

        return {x:coord[0], y:coord[1]};
    }

    this.decodeAudio = function(cvCtx, cvWidth, lowRate, highRate) {
        var audioPixels = canvasCtx.getImageData(0, cvWidth, cvWidth, cvWidth).data;
        var nbScaledSamples = cvWidth * cvWidth;
        var scaledSamples = new Float32Array(nbScaledSamples);

        // Basic decoding: Y=R=G=B
        for (var s = 0; s < nbScaledSamples; s++) {
            var coord = this.indexToCoord(s);
            scaledSamples[s] = (audioPixels[(coord.y * cvWidth + coord.x) * 4 + 1] - this.center) / this.amp;
        }

        var dct = new Dct();
        dct.decode(scaledSamples, nbScaledSamples);

        var scaler = new Scaler(lowRate, highRate);
        return scaler.upscale(scaledSamples, nbScaledSamples);
    }
}

<|endoftext|>


<commit_before>
 function showTagsScopesMin(htmlId){
        htmlId=".scope-min-header";
        var numberOfScope = 0;
        if(typeof myMultiScopes != "undefined"){
            $.each(myMultiScopes, function(key, value){
                numberOfScope++;
            })  ;
        }
        scopeHtml="";
        //if(typeof userConnected != "undefined" && userConnected != null ){
             if( typeof $.cookie('communexionName') !== "undefined" && $.cookie('communexionName') != "false" && communexion.state){
                scopeHtml='<button class="pull-left btn btn-link bg-white text-red tooltips item-globalscope-checker start-new-communexion" '+
                            'data-toggle="tooltip" data-placement="top" title="Communecter avec '+$.cookie('communexionName')+'" '+
                            'data-scope-value="'+$.cookie('communexionValue')+'" '+
                            'data-scope-name="'+$.cookie('communexionName')+'" '+
                            'data-scope-level="'+$.cookie('communexionLevel')+'" '+
                            'data-scope-type="'+$.cookie('communexionType')+'" '+
                            'id="btn-my-co">'+
                            ''+
                        '</button>';
            }else{
                scopeHtml='<button class="pull-left hidden btn btn-link bg-white text-red tooltips" onclick="communecterUser();" '+
                            'data-toggle="tooltip" data-placement="top" title="Communectez-vous" '+
                            'id="btn-my-co">'+
                            ''+
                        '</button>';
            }
        //}

        scopeHtml+='
'+
                        '<button class="btn btn-default main-btn-scopes text-white tooltips margin-bottom-5 margin-left-10 margin-right-10" '+
                            'data-target="#modalScopes" data-toggle="modal" '+
                            'data-toggle="tooltip" data-placement="top" '+
                            'title="Sélectionner des lieux de recherche">'+
                            ''+
                        '</button>';
                        if(numberOfScope > 0){
                            scopeHtml+= 'recherche ciblée ';
                        } else{
                            scopeHtml+= ''+
                                           ''+
                                                ' Ajouter des filtres géographiques ?'+
                                            ''+
                                        '';
                        }
        scopeHtml+= '
'+
                    '
'+
                    '
';
        $("#container-scope-filter").html(scopeHtml);
        //}
        /************** SCOPES **************/
        var iconSelectScope = "";
        var scopeSelected = false;

        html = "
";
        if(numberOfScope > 0){
            $.each(myMultiScopes, function(key, value){
                numberOfScope++;
                var disabled = value.active == false ? "disabled" : "";
                if(typeof value.name == "undefined") value.name = key;
                html +=     "" +
                                " " + value.name +
                            " ";
            });
        }
        html += "
";
        $(htmlId).html(html);
        if(actionOnSetGlobalScope=="save"){
            scopeHtml='<a class="pull-left btn btn-link bg-white text-red tooltips item-globalscope-checker start-new-communexion" '+
                            'data-toggle="tooltip" data-placement="top" title="Communecter avec '+$.cookie('communexionName')+'" '+
                            'data-scope-value="'+$.cookie('communexionValue')+'" '+
                            'data-scope-name="'+$.cookie('communexionName')+'" '+
                            'data-scope-level="'+$.cookie('communexionLevel')+'" '+
                            'data-scope-type="'+$.cookie('communexionType')+'" '+
                            'id="btn-my-co">'+
                            ''+
                        ''+
                        '
'+
                            ''+
                                ''+
                            ''+
                            'Selectionner les endroits de publications '+
                        '
'+
                        '
'+
                            html+
                        '
';
            $("#scopeListContainerForm").html(scopeHtml);
        }
        multiTagScopeLbl();
        //bindCommunexionScopeEvents();

        $(".toggle-scope-dropdown").click(function(){ //mylog.log("toogle");
            if(!$("#dropdown-content-multi-scope").hasClass('open'))
            setTimeout(function(){ $("#dropdown-content-multi-scope").addClass('open'); }, 300);
        });

        if(scopeSelected){ $(".btnShowAllScope").hide(); $(".btnHideAllScope").show(); }
        else             { $(".btnShowAllScope").show(); $(".btnHideAllScope").hide(); }

        checkScopeMax();
        rebuildSearchScopeInput();

    }

var currentTypeSearchSend = "search";
function multiTagScopeLbl(type){
	if(!notEmpty(type)) type = currentTypeSearchSend;
	if(type=="search"){
		$("#lbl-my-scopes").html("Rechercher par lieux  ");
		$("#lbl-my-tags").html("Rechercher par tags  ");
		$("br.visible-in-form").hide();
	}else if(type=="send"){
		$("#lbl-my-scopes").html(" Sélectionnez les lieux de destination");
		$("#lbl-my-tags").html(" Sélectionner des tags pour définir le contenu de votre message");
		$("br.visible-in-form").show();
	}
	currentTypeSearchSend = type;
}

function showEmptyMsg(){
	var c=0;
	if(typeof myMultiScopes != "undefined")
		$.each(myMultiScopes, function(key, value){ c++; });
	console.log("showEmptyMsg", c);
	if(c==0) $("#modalScopes .visible-empty").show(); else $("#modalScopes .visible-empty").hide();
	if(c==0) $("#modalScopes .hidden-empty").hide(); else $("#modalScopes .hidden-empty").show();

	//c=0; $.each(myMultiTags, function(key, value){ c++; });
	//if(c==0) $("#dropdown-multi-tag .visible-empty").show(); else $("#dropdown-multi-tag .visible-empty").hide();

}

function slidupScopetagsMin(show){ //mylog.log("slidupScopetagsMin", show);
	if($("#list_filters").hasClass("hidden")){
	    $("#list_filters").removeClass("hidden");
	    $("#btn-slidup-scopetags").html("");
	}
	else{
	    $("#list_filters").addClass("hidden"); //mylog.log("hidden slidupScopetagsMin", show);
	    $("#btn-slidup-scopetags").html("");
	}

	if(show==true){
	    $("#list_filters").removeClass("hidden"); //mylog.log("removeClass hidden slidupScopetagsMin", show);
	    $("#btn-slidup-scopetags").html("");
	}
	else if(show==false){
	    $("#list_filters").addClass("hidden");
	    $("#btn-slidup-scopetags").html("");
	}
}

<commit_msg><commit_after>
 function showTagsScopesMin(htmlId){
        htmlId=".scope-min-header";
        var numberOfScope = 0;
        if(typeof myMultiScopes != "undefined"){
            $.each(myMultiScopes, function(key, value){
                numberOfScope++;
            })  ;
        }
        scopeHtml="";
        //if(typeof userConnected != "undefined" && userConnected != null ){
             if( typeof $.cookie('communexionName') !== "undefined" && $.cookie('communexionName') != "false" && communexion.state){
                scopeHtml='<button class="pull-left btn btn-link bg-white text-red tooltips item-globalscope-checker start-new-communexion" '+
                            'data-toggle="tooltip" data-placement="top" title="Communecter avec '+$.cookie('communexionName')+'" '+
                            'data-scope-value="'+$.cookie('communexionValue')+'" '+
                            'data-scope-name="'+$.cookie('communexionName')+'" '+
                            'data-scope-level="'+$.cookie('communexionLevel')+'" '+
                            'data-scope-type="'+$.cookie('communexionType')+'" '+
                            'id="btn-my-co">'+
                            ''+
                        '</button>';
            }else{
                if(userId!=""){
                    scopeHtml='<button class="pull-left btn btn-link bg-white text-red tooltips" onclick="communecterUser();" '+
                            'data-toggle="tooltip" data-placement="top" title="Communectez-vous" '+
                            'id="btn-my-co">'+
                            ''+
                        '</button>';
                }
            }
        //}

        scopeHtml+='
'+
                        '<button class="btn btn-default main-btn-scopes text-white tooltips margin-bottom-5 margin-left-10 margin-right-10" '+
                            'data-target="#modalScopes" data-toggle="modal" '+
                            'data-toggle="tooltip" data-placement="top" '+
                            'title="Sélectionner des lieux de recherche">'+
                            ''+
                        '</button>';
                        if(numberOfScope > 0){
                            scopeHtml+= 'recherche ciblée ';
                        } else{
                            scopeHtml+= ''+
                                           ''+
                                                ' Ajouter des filtres géographiques ?'+
                                            ''+
                                        '';
                        }
        scopeHtml+= '
'+
                    '
'+
                    '
';
        $("#container-scope-filter").html(scopeHtml);
        //}
        /************** SCOPES **************/
        var iconSelectScope = "";
        var scopeSelected = false;

        html = "
";
        if(numberOfScope > 0){
            $.each(myMultiScopes, function(key, value){
                numberOfScope++;
                var disabled = value.active == false ? "disabled" : "";
                if(typeof value.name == "undefined") value.name = key;
                html +=     "" +
                                " " + value.name +
                            " ";
            });
        }
        html += "
";
        $(htmlId).html(html);
        if(actionOnSetGlobalScope=="save"){
            scopeHtml='<a class="pull-left btn btn-link bg-white text-red tooltips item-globalscope-checker start-new-communexion" '+
                            'data-toggle="tooltip" data-placement="top" title="Communecter avec '+$.cookie('communexionName')+'" '+
                            'data-scope-value="'+$.cookie('communexionValue')+'" '+
                            'data-scope-name="'+$.cookie('communexionName')+'" '+
                            'data-scope-level="'+$.cookie('communexionLevel')+'" '+
                            'data-scope-type="'+$.cookie('communexionType')+'" '+
                            'id="btn-my-co">'+
                            ''+
                        ''+
                        '
'+
                            ''+
                                ''+
                            ''+
                            'Selectionner les endroits de publications '+
                        '
'+
                        '
'+
                            html+
                        '
';
            $("#scopeListContainerForm").html(scopeHtml);
        }
        multiTagScopeLbl();
        //bindCommunexionScopeEvents();

        $(".toggle-scope-dropdown").click(function(){ //mylog.log("toogle");
            if(!$("#dropdown-content-multi-scope").hasClass('open'))
            setTimeout(function(){ $("#dropdown-content-multi-scope").addClass('open'); }, 300);
        });

        if(scopeSelected){ $(".btnShowAllScope").hide(); $(".btnHideAllScope").show(); }
        else             { $(".btnShowAllScope").show(); $(".btnHideAllScope").hide(); }

        checkScopeMax();
        rebuildSearchScopeInput();

    }

var currentTypeSearchSend = "search";
function multiTagScopeLbl(type){
	if(!notEmpty(type)) type = currentTypeSearchSend;
	if(type=="search"){
		$("#lbl-my-scopes").html("Rechercher par lieux  ");
		$("#lbl-my-tags").html("Rechercher par tags  ");
		$("br.visible-in-form").hide();
	}else if(type=="send"){
		$("#lbl-my-scopes").html(" Sélectionnez les lieux de destination");
		$("#lbl-my-tags").html(" Sélectionner des tags pour définir le contenu de votre message");
		$("br.visible-in-form").show();
	}
	currentTypeSearchSend = type;
}

function showEmptyMsg(){
	var c=0;
	if(typeof myMultiScopes != "undefined")
		$.each(myMultiScopes, function(key, value){ c++; });
	console.log("showEmptyMsg", c);
	if(c==0) $("#modalScopes .visible-empty").show(); else $("#modalScopes .visible-empty").hide();
	if(c==0) $("#modalScopes .hidden-empty").hide(); else $("#modalScopes .hidden-empty").show();

	//c=0; $.each(myMultiTags, function(key, value){ c++; });
	//if(c==0) $("#dropdown-multi-tag .visible-empty").show(); else $("#dropdown-multi-tag .visible-empty").hide();

}

function slidupScopetagsMin(show){ //mylog.log("slidupScopetagsMin", show);
	if($("#list_filters").hasClass("hidden")){
	    $("#list_filters").removeClass("hidden");
	    $("#btn-slidup-scopetags").html("");
	}
	else{
	    $("#list_filters").addClass("hidden"); //mylog.log("hidden slidupScopetagsMin", show);
	    $("#btn-slidup-scopetags").html("");
	}

	if(show==true){
	    $("#list_filters").removeClass("hidden"); //mylog.log("removeClass hidden slidupScopetagsMin", show);
	    $("#btn-slidup-scopetags").html("");
	}
	else if(show==false){
	    $("#list_filters").addClass("hidden");
	    $("#btn-slidup-scopetags").html("");
	}
}

<|endoftext|>


<commit_before>export { Base };

import * as ChannelShuffler from "./ChannelShuffler.js";

//!!! ...unfinished... (2021/08/20) setConcatOnly() ?

/**
 * A special channel shuffler for ( outputGroupCount == 2 ). Its apply() does not use loop and not create new array.
 * So its performance should be better.
 */
class Base {

  /**
   *
   * @see ChannelShuffler.ShuffleInfo
   */
  constructor(   ) {

//!!! ...unfinished... (2021/08/19)
    let concatenatedShape = [ ];
    let outputGroupCount = 2;

//!!! ...unfinished... (2021/08/19)
  }

  disposeTensors() {
//!!! ...unfinished... (2021/08/19)
  }

//!!! ...unfinished... (2021/08/19) Use outputTensors[] instead of new created array as return value (for improving performance).
  apply( inputTensors, outputTensors ) {
// Since ( outputGroupCount == 2 ), use optimized (loop-unrolled).
  }

}

/**
 * Concatenate two tensor3d ( height x width x channel ) always along the last axis (i.e. axisId = 2, along the channel axis). It could
 * destroy one or two of the input tensors.
 *
 * @member {boolean} bKeepInputTensor0
 *   If false, the first input tensor will be disposed after concatenating. If true, the first input tensor will be kept after concatenating.
 *
 * @member {boolean} bKeepInputTensor1
 *   If false, the second input tensor will be disposed after concatenating. If true, the second input tensor will be kept after concatenating.
 *
 * @member {function} pfnConcat
 *   This is a method. It has one parameter inputTensorsArray and return a outputTensor. The inputTensorsArray (tf.tensor3d[]) represents
 * all the images ( height x width x channel ) which will be concatenated. They should have the same ( height x width ) but could
 * different channel count. The outputTensor (tf.tensor3d) represents the result of concatenating the inputs along the last axis
 * (i.e. the channel axis ( axisId = 2 ) ). The inputTensor may or may not be disposed. In fact, this method calls one of
 * Concat_and_keep0_keep1(), Concat_and_keep0_destroy1(), Concat_and_destroy0_keep1(), Concat_and_destroy0_destroy1() according
 * to the parameters.
 *
 */
class Base {

  constructor( bKeepInputTensor0, bKeepInputTensor1 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor0( bKeepInputTensor0 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    Base.adjust_pfnConcat.call( this );
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor1( bKeepInputTensor1 ) {
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor( bKeepInputTensor0, bKeepInputTensor1 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );
  }

  /** Set this.pfnConcat according to this.bKeepInputTensor0 and this.bKeepInputTensor1. */
  static adjust_pfnConcat() {
    if ( this.bKeepInputTensor0 ) {
      if ( this.bKeepInputTensor1 ) {
        this.pfnConcat = Base.Concat_and_keep0_keep1;
      } else {
        this.pfnConcat = Base.Concat_and_keep0_destroy1;
      }
    } else {
      if ( this.bKeepInputTensor1 ) {
        this.pfnConcat = Base.Concat_and_destroy0_keep1;
      } else {
        this.pfnConcat = Base.Concat_and_destroy0_destroy1;
      }
    }
  }

  /** Concatenate along axis id 2. (Both the inputTensorsArray[ 0 ] and inputTensorsArray[ 1 ] will not be disposed. */
  static Concat_and_keep0_keep1( inputTensorsArray ) {
    return tf.concat( inputTensorsArray, 2 ); // AxisId = 2
  }

  /** Concatenate along axis id 2. (The inputTensorsArray[ 0 ] will not be disposed. The inputTensorsArray[ 1 ] will be disposed. */
  static Concat_and_keep0_destroy1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 1 ].dispose();
    return t;
  }

  /** Concatenate along axis id 2. (The inputTensorsArray[ 0 ] will be disposed. The inputTensorsArray[ 1 ] will not be disposed. */
  static Concat_and_destroy0_keep1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 0 ].dispose();
    return t;
  }

  /** Concatenate along axis id 2. (Both the inputTensorsArray[ 0 ] and inputTensorsArray[ 1 ] will be disposed. */
  static Concat_and_destroy0_destroy1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 0 ].dispose();
    inputTensorsArray[ 1 ].dispose();
    return t;
  }

}
<commit_msg>Update ChannelShufflerGroupCount2.js<commit_after>export { Base };

import * as ChannelShuffler from "./ChannelShuffler.js";

//!!! ...unfinished... (2021/08/20) setConcatOnly() ?

/**
 * A special channel shuffler for ( outputGroupCount == 2 ). Its pfnConcatShuffleSplit() does not use loop and not create new array.
 * So its performance should be better.

//!!! ...unfinished... (2021/08/20)

 * Concatenate two tensor3d ( height x width x channel ) always along the last axis (i.e. axisId = 2, along the channel axis). It could
 * destroy one or two of the input tensors.
 *
 *
 * @member {boolean} bKeepInputTensor0
 *   If false, the first input tensor will be disposed after concatenating. If true, the first input tensor will be kept after concatenating.
 *
 * @member {boolean} bKeepInputTensor1
 *   If false, the second input tensor will be disposed after concatenating. If true, the second input tensor will be kept after concatenating.
 *
 * @member {function} pfnConcatShuffleSplit
 *   This is a method. It has two parameters inputTensors[] and outputTensors[]. The inputTensors[] (tf.tensor3d[]) represents
 * all the images ( height x width x channel ) which will be concatenated, shuffle, split. They should have the same ( height x width )
 * but could have different channel count. The outputTensors[] (tf.tensor3d[]) represents the result The inputTensor may or may
 * not be disposed. In fact, this method calls one of

//!!! ...unfinished... (2021/08/20)

 * Concat_and_keep0_keep1(), Concat_and_keep0_destroy1(), Concat_and_destroy0_keep1(), Concat_and_destroy0_destroy1() according
 * to the parameters.
 *
 */
class Base {

  /**
   *
   * @see ChannelShuffler.ShuffleInfo
   */
  constructor( bKeepInputTensor0, bKeepInputTensor1 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );

//!!! ...unfinished... (2021/08/19)
    let concatenatedShape = [ ];
    let outputGroupCount = 2;

//!!! ...unfinished... (2021/08/19)

  }

  disposeTensors() {
//!!! ...unfinished... (2021/08/19)
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor0( bKeepInputTensor0 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    Base.adjust_pfnConcat.call( this );
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor1( bKeepInputTensor1 ) {
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );
  }

  /**
   * Adjust this.pfnConcat so that this.pfnConcat() will or will not dispose its inputTensors.
   */
  setKeepInputTensor( bKeepInputTensor0, bKeepInputTensor1 ) {
    this.bKeepInputTensor0 = bKeepInputTensor0;
    this.bKeepInputTensor1 = bKeepInputTensor1;
    Base.adjust_pfnConcat.call( this );
  }

  /** Set this.pfnConcat according to this.bKeepInputTensor0 and this.bKeepInputTensor1. */
  static adjust_pfnConcat() {
    if ( this.bKeepInputTensor0 ) {
      if ( this.bKeepInputTensor1 ) {
        this.pfnConcat = Base.Concat_and_keep0_keep1;
      } else {
        this.pfnConcat = Base.Concat_and_keep0_destroy1;
      }
    } else {
      if ( this.bKeepInputTensor1 ) {
        this.pfnConcat = Base.Concat_and_destroy0_keep1;
      } else {
        this.pfnConcat = Base.Concat_and_destroy0_destroy1;
      }
    }
  }

  /** Concatenate along axis id 2. (Both the inputTensorsArray[ 0 ] and inputTensorsArray[ 1 ] will not be disposed. */
  static Concat_and_keep0_keep1( inputTensorsArray ) {
    return tf.concat( inputTensorsArray, 2 ); // AxisId = 2
  }

  /** Concatenate along axis id 2. (The inputTensorsArray[ 0 ] will not be disposed. The inputTensorsArray[ 1 ] will be disposed. */
  static Concat_and_keep0_destroy1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 1 ].dispose();
    return t;
  }

  /** Concatenate along axis id 2. (The inputTensorsArray[ 0 ] will be disposed. The inputTensorsArray[ 1 ] will not be disposed. */
  static Concat_and_destroy0_keep1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 0 ].dispose();
    return t;
  }

  /** Concatenate along axis id 2. (Both the inputTensorsArray[ 0 ] and inputTensorsArray[ 1 ] will be disposed. */
  static Concat_and_destroy0_destroy1( inputTensorsArray ) {
    let t = tf.concat( inputTensorsArray, 2 ); // AxisId = 2
    inputTensorsArray[ 0 ].dispose();
    inputTensorsArray[ 1 ].dispose();
    return t;
  }

//!!! ...unfinished... (2021/08/19) Use outputTensors[] instead of new created array as return value (for improving performance).
  apply( inputTensors, outputTensors ) {
// Since ( outputGroupCount == 2 ), use optimized (loop-unrolled).
  }

}
<|endoftext|>


<commit_before>    var customIcons = {
        building: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/building_icon.png'
        },
        student_centre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/student_centre_icon.png'
        },
        lecture_theatre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/lecture_theatre_icon.png'
        },
        computer_lab: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/computer_lab_icon.png'
        },
        library: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/library_icon.png'
        },
        cycle_hire: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_hire_icon.png'
        },
        cycle_parking: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_parking_icon.png'
        },
        atm: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/atm_icon.png'
        }
    };

    var markerGroups = {
        "building": [],
        "student_centre": [],
        "lecture_theatre": [],
        "computer_lab": [],
        "library": [],
        "cycle_hire": [],
        "cycle_parking": [],
        "atm": []
    };

    function showCurrentLocation(currentLocationDiv, map) {
        currentLocationDiv.style.padding = '5px';
        var currentLocationUI = document.createElement('div');
        currentLocationUI.style.backgroundColor = 'white';
        currentLocationUI.style.border = '1px solid';
        currentLocationUI.style.cursor = 'pointer';
        currentLocationUI.style.textAlign = 'center';
        currentLocationUI.title = 'Shows current location on the map';
        currentLocationDiv.appendChild(currentLocationUI);
        var currentLocationText = document.createElement('div');
        currentLocationText.style.fontFamily = 'Arial,sans-serif';
        currentLocationText.style.fontSize = '12px';
        currentLocationText.style.paddingLeft = '4px';
        currentLocationText.style.paddingRight = '4px';
        currentLocationText.innerHTML = 'Current location';
        currentLocationUI.appendChild(currentLocationText);

        var current_location_marker = null;

        google.maps.event.addDomListener(currentLocationUI, 'click', function () {

            if(navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function(position) {
                    var pos = new google.maps.LatLng(position.coords.latitude,
                        position.coords.longitude);

                    if (current_location_marker==null) {
                        current_location_marker = new google.maps.Marker({
                            map: map,
                            position: pos,
                            title: 'You are here.'
                        });

                        var current_location_infowindow = new google.maps.InfoWindow({
                            content: 'You are here.'
                        });

                        current_location_infowindow.open(map,current_location_marker);

                        google.maps.event.addListener(marker, 'click', function() {
                            current_location_infowindow.open(map,current_location_marker);
                        });

                        map.setCenter(pos);
                    } else {
                        current_location_marker.setPosition(pos);
                    }

                }, function() {
                    handleNoGeolocation(true);
                });
            } else {
                handleNoGeolocation(false);
            }

        var no_geolocation_marker = null;

        function handleNoGeolocation(errorFlag) {
            if (errorFlag) {
                var content = 'Error: The Geolocation service failed.';
            } else {
                var content = 'Error: Your browser doesn\'t support geolocation.';
            }

            var options = {
                map: map,
                position: new google.maps.LatLng(51.527287, -0.103842),
                content: content
            };

            if (no_geolocation_marker==null) {
                    no_geolocation_marker = new google.maps.Marker({
                    map: map,
                    position: options.position,
                    title: content
                });

                var no_geolocation_infowindow = new google.maps.InfoWindow({
                    content: content
                });

                no_geolocation_infowindow.open(map,no_geolocation_marker);

                google.maps.event.addListener(marker, 'click', function() {
                    no_geolocation_infowindow.open(map,no_geolocation_marker);
                });

                map.setCenter(options.position);
            } else {
                no_geolocation_marker.setPosition(options.position);
            }
        }

        });
    }

    function loadMap() {
    var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(51.527287, -0.103842),
        zoom: 15,
        mapTypeId: 'roadmap'
    });

        // Create a DIV to hold the control and call HomeControl()
    var currentLocationDiv = document.createElement('div');
    var currentLocation = new showCurrentLocation(currentLocationDiv, map);
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(currentLocationDiv);

    downloadUrl("../../includes/university-map/source/overview_source.php", function(data) {
    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var notes = markers[i].getAttribute("notes");
        var category = markers[i].getAttribute("category");
        var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, notes, category, map);
    }
    });
    }

    var infoWindow = new google.maps.InfoWindow({
        maxWidth: 400
    });

    function createMarker(point, name, notes, category, map) {
        var icon = customIcons[category] || {};
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            type: category
        });
        if (!markerGroups[category]) markerGroups[category] = [];
        markerGroups[category].push(marker);
        var html = "" + name + "
" + notes;
        bindInfoWindow(marker, map, infoWindow, html);
        return marker;
    }

    function toggleGroup(category) {
        for (var i = 0; i < markerGroups[category].length; i++) {
            var marker = markerGroups[category][i];
            if (!marker.getVisible()) {
                marker.setVisible(true);
            } else {
                marker.setVisible(false);
            }
        }
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
        google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);

        });
    }

    function downloadUrl(url, callback) {
        var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                request.onreadystatechange = doNothing;
                callback(request, request.status);
            }
        };

        request.open('GET', url, true);
        request.send(null);
    }

    function doNothing() {}
<commit_msg>Changed structure<commit_after>    var customIcons = {
        building: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/building_icon.png'
        },
        student_centre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/student_centre_icon.png'
        },
        lecture_theatre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/lecture_theatre_icon.png'
        },
        computer_lab: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/computer_lab_icon.png'
        },
        library: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/library_icon.png'
        },
        cycle_hire: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_hire_icon.png'
        },
        cycle_parking: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_parking_icon.png'
        },
        atm: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/atm_icon.png'
        }
    };

    var markerGroups = {
        "building": [],
        "student_centre": [],
        "lecture_theatre": [],
        "computer_lab": [],
        "library": [],
        "cycle_hire": [],
        "cycle_parking": [],
        "atm": []
    };

    function showCurrentLocation(currentLocationDiv, map) {
        currentLocationDiv.style.padding = '5px';
        var currentLocationUI = document.createElement('div');
        currentLocationUI.style.backgroundColor = 'white';
        currentLocationUI.style.border = '1px solid';
        currentLocationUI.style.cursor = 'pointer';
        currentLocationUI.style.textAlign = 'center';
        currentLocationUI.title = 'Shows current location on the map';
        currentLocationDiv.appendChild(currentLocationUI);
        var currentLocationText = document.createElement('div');
        currentLocationText.style.fontFamily = 'Arial,sans-serif';
        currentLocationText.style.fontSize = '12px';
        currentLocationText.style.paddingLeft = '4px';
        currentLocationText.style.paddingRight = '4px';
        currentLocationText.innerHTML = 'Current location';
        currentLocationUI.appendChild(currentLocationText);

        var current_location_marker = null;

        google.maps.event.addDomListener(currentLocationUI, 'click', function () {

            if(navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function(position) {
                    var pos = new google.maps.LatLng(position.coords.latitude,
                        position.coords.longitude);

                    if (current_location_marker==null) {
                        current_location_marker = new google.maps.Marker({
                            map: map,
                            position: pos,
                            title: 'You are here.'
                        });

                        var current_location_infowindow = new google.maps.InfoWindow({
                            content: 'You are here.'
                        });

                        current_location_infowindow.open(map,current_location_marker);

                        google.maps.event.addListener(marker, 'click', function() {
                            current_location_infowindow.open(map,current_location_marker);
                        });

                        map.setCenter(pos);
                    } else {
                        current_location_marker.setPosition(pos);
                    }

                }, function() {
                    handleNoGeolocation(true);
                });
            } else {
                handleNoGeolocation(false);
            }

        function handleNoGeolocation(errorFlag) {
            if (errorFlag) {
                var content = 'Error: The Geolocation service failed.';
            } else {
                var content = 'Error: Your browser doesn\'t support geolocation.';
            }

            var options = {
                map: map,
                position: new google.maps.LatLng(60, 105),
                content: content
            };

            var infowindow = new google.maps.InfoWindow(options);
            map.setCenter(options.position);
        }
        });
    }

    function loadMap() {
    var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(51.527287, -0.103842),
        zoom: 15,
        mapTypeId: 'roadmap'
    });

        // Create a DIV to hold the control and call HomeControl()
    var currentLocationDiv = document.createElement('div');
    var currentLocation = new showCurrentLocation(currentLocationDiv, map);
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(currentLocationDiv);

    downloadUrl("../../includes/university-map/source/overview_source.php", function(data) {
    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var notes = markers[i].getAttribute("notes");
        var category = markers[i].getAttribute("category");
        var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, notes, category, map);
    }
    });
    }

    var infoWindow = new google.maps.InfoWindow({
        maxWidth: 400
    });

    function createMarker(point, name, notes, category, map) {
        var icon = customIcons[category] || {};
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            type: category
        });
        if (!markerGroups[category]) markerGroups[category] = [];
        markerGroups[category].push(marker);
        var html = "" + name + "
" + notes;
        bindInfoWindow(marker, map, infoWindow, html);
        return marker;
    }

    function toggleGroup(category) {
        for (var i = 0; i < markerGroups[category].length; i++) {
            var marker = markerGroups[category][i];
            if (!marker.getVisible()) {
                marker.setVisible(true);
            } else {
                marker.setVisible(false);
            }
        }
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
        google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);

        });
    }

    function downloadUrl(url, callback) {
        var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                request.onreadystatechange = doNothing;
                callback(request, request.status);
            }
        };

        request.open('GET', url, true);
        request.send(null);
    }

    function doNothing() {}
<|endoftext|>


<commit_before>import { cloneDeep } from 'lodash'

import { trackEvent } from '../app/event_tracking'
import { t } from '../app/locale'
import { showStatusMessage, hideStatusMessage } from '../app/status_message'
import { infoBubble } from '../info_bubble/info_bubble'
import {
  trimStreetData,
  getStreet,
  setStreet,
  setUpdateTimeToNow,
  updateEverything
} from './data_model'
import { getRemixOnFirstEdit } from './remix'

import store from '../store'
import {
  createNewUndo,
  unifyStack,
  undoAction,
  redoAction
} from '../store/actions/undo'

export function getUndoStack () {
  return cloneDeep(store.getState().undo.stack)
}

export function getUndoPosition () {
  return store.getState().undo.position
}

function finishUndoOrRedo () {
  // set current street to the thing we just updated
  const state = store.getState().undo
  setStreet(cloneDeep(state.stack[state.position]))

  setUpdateTimeToNow()

  infoBubble.hide()
  infoBubble.hideSegment()
  infoBubble.dontConsiderShowing()

  updateEverything(true)
  hideStatusMessage()

  trackEvent('INTERACTION', 'UNDO', null, null, true)
}

export function undo () {
  if (!isUndoAvailable()) {
    showStatusMessage(t('toast.no-undo'))
    return
  }

  // sends current street to update current position before undoing
  store.dispatch(undoAction(trimStreetData(getStreet())))

  finishUndoOrRedo()
}

export function redo () {
  if (!isRedoAvailable()) {
    showStatusMessage(t('toast.no-redo'))
    return
  }

  store.dispatch(redoAction())

  finishUndoOrRedo()
}

export function createNewUndoIfNecessary (lastStreet, currentStreet) {
  // If just the street name has changed, don't make a new undo step for it.
  if (lastStreet.name !== currentStreet.name) {
    return
  }

  store.dispatch(createNewUndo(cloneDeep(lastStreet)))
}

export function isUndoAvailable () {
  const undoPosition = getUndoPosition()
  // Don’t allow undo/redo unless you own the street
  return (undoPosition > 0) && !getRemixOnFirstEdit()
}

export function isRedoAvailable () {
  const undoStack = getUndoStack()
  const undoPosition = getUndoPosition()
  // Don’t allow undo/redo unless you own the street
  return (undoPosition >= 0 && undoPosition < undoStack.length - 1) && !getRemixOnFirstEdit()
}

export function unifyUndoStack () {
  const street = store.getState().street
  store.dispatch(unifyStack(street))
}
<commit_msg>undo/redo using redux street state<commit_after>import { cloneDeep } from 'lodash'

import { trackEvent } from '../app/event_tracking'
import { t } from '../app/locale'
import { showStatusMessage, hideStatusMessage } from '../app/status_message'
import { infoBubble } from '../info_bubble/info_bubble'
import {
  trimStreetData,
  // getStreet,
  // setStreet,
  setUpdateTimeToNow,
  updateEverything
} from './data_model'
import { getRemixOnFirstEdit } from './remix'

import store from '../store'
import {
  createNewUndo,
  unifyStack,
  undoAction,
  redoAction
} from '../store/actions/undo'
import { updateStreetData } from '../store/actions/street'

export function getUndoStack () {
  return cloneDeep(store.getState().undo.stack)
}

export function getUndoPosition () {
  return store.getState().undo.position
}

function finishUndoOrRedo () {
  // set current street to the thing we just updated
  const state = store.getState().undo
  // setStreet(cloneDeep(state.stack[state.position]))
  store.dispatch(updateStreetData(cloneDeep(state.stack[state.position])))

  setUpdateTimeToNow()

  infoBubble.hide()
  infoBubble.hideSegment()
  infoBubble.dontConsiderShowing()

  updateEverything(true)
  hideStatusMessage()

  trackEvent('INTERACTION', 'UNDO', null, null, true)
}

export function undo () {
  if (!isUndoAvailable()) {
    showStatusMessage(t('toast.no-undo'))
    return
  }

  // sends current street to update current position before undoing
  // store.dispatch(undoAction(trimStreetData(getStreet())))
  store.dispatch(undoAction(trimStreetData(store.getState().street)))

  finishUndoOrRedo()
}

export function redo () {
  if (!isRedoAvailable()) {
    showStatusMessage(t('toast.no-redo'))
    return
  }

  store.dispatch(redoAction())

  finishUndoOrRedo()
}

export function createNewUndoIfNecessary (lastStreet, currentStreet) {
  // If just the street name has changed, don't make a new undo step for it.
  if (lastStreet.name !== currentStreet.name) {
    return
  }

  store.dispatch(createNewUndo(cloneDeep(lastStreet)))
}

export function isUndoAvailable () {
  const undoPosition = getUndoPosition()
  // Don’t allow undo/redo unless you own the street
  return (undoPosition > 0) && !getRemixOnFirstEdit()
}

export function isRedoAvailable () {
  const undoStack = getUndoStack()
  const undoPosition = getUndoPosition()
  // Don’t allow undo/redo unless you own the street
  return (undoPosition >= 0 && undoPosition < undoStack.length - 1) && !getRemixOnFirstEdit()
}

export function unifyUndoStack () {
  const street = store.getState().street
  store.dispatch(unifyStack(street))
}
<|endoftext|>