<commit_before>const { Model, transaction } = require('../../../');
const { expect } = require('chai');

module.exports = session => {
  describe('UpsertGraph deletes rows for relation which is not mentioned in graph #1455', () => {
    let knex = session.knex;
    let Role;

    beforeEach(() => {
      const { knex } = session;

      return knex.schema
        .dropTableIfExists('roles')
        .then(() => knex.schema.dropTableIfExists('sets'))
        .then(() => knex.schema.dropTableIfExists('setsAttributes'))
        .then(() => {
          return knex.schema.createTable('roles', table => {
            table.increments();
            table.string('name').notNullable();
          });
        })
        .then(() => {
          return knex.schema.createTable('sets', table => {
            table.increments();
            table.string('name').notNullable();
            table
              .integer('roleId')
              .unsigned()
              .notNullable();
          });
        })
        .then(() => {
          return knex.schema.createTable('setsAttributes', table => {
            table.increments();
            table.string('name').notNullable();
            table
              .integer('setId')
              .unsigned()
              .notNullable();
          });
        });
    });

    afterEach(() => {
      return knex.schema
        .dropTableIfExists('roles')
        .then(() => knex.schema.dropTableIfExists('sets'))
        .then(() => knex.schema.dropTableIfExists('setsAttributes'));
    });

    beforeEach(() => {
      const { knex } = session;

      class BaseModel extends Model {
        static get useLimitInFirst() {
          return true;
        }
      }

      class SetAttribute extends BaseModel {
        static get tableName() {
          return 'setsAttributes';
        }
      }

      class Set extends BaseModel {
        static get tableName() {
          return 'sets';
        }

        static get relationMappings() {
          return {
            setAttributes: {
              relation: BaseModel.HasManyRelation,
              modelClass: SetAttribute,
              join: { from: 'sets.id', to: 'setsAttributes.setId' }
            }
          };
        }
      }

      Role = class Role extends BaseModel {
        static get tableName() {
          return 'roles';
        }

        static get relationMappings() {
          return {
            sets: {
              relation: BaseModel.HasManyRelation,
              modelClass: Set,
              join: { from: 'roles.id', to: 'sets.roleId' }
            }
          };
        }
      };

      BaseModel.knex(knex);
    });

    it('test', () => {
      return transaction(Role.knex(), trx =>
        Role.query(trx).insertGraph({
          name: 'First Role',
          sets: [
            {
              name: 'First Set',
              setAttributes: [{ name: 'First SetAttribute' }, { name: 'Second SetAttribute' }]
            }
          ]
        })
      )
        .then(role => {
          return transaction(Role.knex(), trx =>
            Role.query(trx).upsertGraph({
              id: role.id,
              sets: [
                { id: role.sets[0].id },
                {
                  name: 'Second Set',
                  setAttributes: [{ name: 'First SetAttribute' }, { name: 'Second SetAttribute' }]
                }
              ]
            })
          );
        })
        .then(() => {
          return Role.query()
            .first()
            .eager('sets(orderById).setAttributes(orderById)', {
              orderById(query) {
                query.orderBy('id');
              }
            });
        })
        .then(setsAfterUpsertGraph => {
          expect(setsAfterUpsertGraph).to.eql({
            id: 1,
            name: 'First Role',
            sets: [
              {
                id: 1,
                name: 'First Set',
                roleId: 1,

                setAttributes: [
                  { id: 1, name: 'First SetAttribute', setId: 1 },
                  { id: 2, name: 'Second SetAttribute', setId: 1 }
                ]
              },
              {
                id: 2,
                name: 'Second Set',
                roleId: 1,

                setAttributes: [
                  { id: 3, name: 'First SetAttribute', setId: 2 },
                  { id: 4, name: 'Second SetAttribute', setId: 2 }
                ]
              }
            ]
          });
        });
    });
  });
};
<commit_msg>fix randomly failing test<commit_after>const { Model, transaction } = require('../../../');
const { expect } = require('chai');

module.exports = session => {
  describe('UpsertGraph deletes rows for relation which is not mentioned in graph #1455', () => {
    let knex = session.knex;
    let Role;

    beforeEach(() => {
      const { knex } = session;

      return knex.schema
        .dropTableIfExists('roles')
        .then(() => knex.schema.dropTableIfExists('sets'))
        .then(() => knex.schema.dropTableIfExists('setsAttributes'))
        .then(() => {
          return knex.schema.createTable('roles', table => {
            table.increments();
            table.string('name').notNullable();
          });
        })
        .then(() => {
          return knex.schema.createTable('sets', table => {
            table.increments();
            table.string('name').notNullable();
            table
              .integer('roleId')
              .unsigned()
              .notNullable();
          });
        })
        .then(() => {
          return knex.schema.createTable('setsAttributes', table => {
            table.increments();
            table.string('name').notNullable();
            table
              .integer('setId')
              .unsigned()
              .notNullable();
          });
        });
    });

    afterEach(() => {
      return knex.schema
        .dropTableIfExists('roles')
        .then(() => knex.schema.dropTableIfExists('sets'))
        .then(() => knex.schema.dropTableIfExists('setsAttributes'));
    });

    beforeEach(() => {
      const { knex } = session;

      class BaseModel extends Model {
        static get useLimitInFirst() {
          return true;
        }
      }

      class SetAttribute extends BaseModel {
        static get tableName() {
          return 'setsAttributes';
        }
      }

      class Set extends BaseModel {
        static get tableName() {
          return 'sets';
        }

        static get relationMappings() {
          return {
            setAttributes: {
              relation: BaseModel.HasManyRelation,
              modelClass: SetAttribute,
              join: { from: 'sets.id', to: 'setsAttributes.setId' }
            }
          };
        }
      }

      Role = class Role extends BaseModel {
        static get tableName() {
          return 'roles';
        }

        static get relationMappings() {
          return {
            sets: {
              relation: BaseModel.HasManyRelation,
              modelClass: Set,
              join: { from: 'roles.id', to: 'sets.roleId' }
            }
          };
        }
      };

      BaseModel.knex(knex);
    });

    it('test', () => {
      return transaction(Role.knex(), trx =>
        Role.query(trx).insertGraph({
          name: 'First Role',
          sets: [
            {
              name: 'First Set',
              setAttributes: [{ name: 'First SetAttribute' }, { name: 'Second SetAttribute' }]
            }
          ]
        })
      )
        .then(role => {
          return transaction(Role.knex(), trx =>
            Role.query(trx).upsertGraph({
              id: role.id,
              sets: [
                { id: role.sets[0].id },
                {
                  name: 'Second Set',
                  setAttributes: [{ name: 'First SetAttribute' }, { name: 'Second SetAttribute' }]
                }
              ]
            })
          );
        })
        .then(() => {
          return Role.query()
            .first()
            .withGraphFetched('sets(orderById).setAttributes(orderByName)')
            .modifiers({
              orderById(query) {
                query.orderBy('id');
              },

              orderByName(query) {
                query.orderBy('name');
              }
            });
        })
        .then(setsAfterUpsertGraph => {
          expect(setsAfterUpsertGraph).to.eql({
            id: 1,
            name: 'First Role',
            sets: [
              {
                id: 1,
                name: 'First Set',
                roleId: 1,

                setAttributes: [
                  { id: 1, name: 'First SetAttribute', setId: 1 },
                  { id: 2, name: 'Second SetAttribute', setId: 1 }
                ]
              },
              {
                id: 2,
                name: 'Second Set',
                roleId: 1,

                setAttributes: [
                  { id: 3, name: 'First SetAttribute', setId: 2 },
                  { id: 4, name: 'Second SetAttribute', setId: 2 }
                ]
              }
            ]
          });
        });
    });
  });
};
<|endoftext|>


<commit_before>/*
  Copyright: (C) 2012 KTH, Kungliga tekniska hogskolan, http://www.kth.se/

  This file is part of tinywebtex.
 */

(function() {
	// Load plugin specific language pack
	tinymce.PluginManager.requireLangPack('tinywebtex');

	tinymce.create('tinymce.plugins.TinyWebtexPlugin', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
			// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
			ed.addCommand('mceTinyWebtex', function() {
				ed.windowManager.open({
					file : url + '/dialog.htm',
					width : 500 + parseInt(ed.getLang('tinywebtex.delta_width', 0)),
					height : 200 + parseInt(ed.getLang('tinywebtex.delta_height', 0)),
					inline : 0
				}, {
					plugin_url : url, // Plugin absolute URL
					webtex_url : 'http://localhost:8080/webtex' // Base URL of WebTex service
				});
			});

			// Register example button
			ed.addButton('tinywebtex', {
				title : 'tinywebtex.desc',
				cmd : 'mceTinyWebtex',
				image : url + '/img/button.png'
			});

			// ctrl+e = cmd+e on a mac
            ed.addShortcut('ctrl+e', "Equation editor", 'mceTinyWebtex');

            // Add a node change handler, selects the button in the UI when a image is selected
            ed.onNodeChange.add(function(ed, cm, n) {
                    cm.setActive('tinywebtex', n.nodeName == 'IMG' && n.className.match('webtex'));
            });
		},

		/**
		 * Creates control instances based in the incomming name. This method is normally not
		 * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
		 * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
		 * method can be used to create those.
		 *
		 * @param {String} n Name of the control to create.
		 * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
		 * @return {tinymce.ui.Control} New control instance or null if no control was created.
		 */
		createControl : function(n, cm) {
			return null;
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Tiny Webtex',
				author : 'infosys@kth.se',
				authorurl : 'http://www.kth.se/',
				infourl : 'http://www.kth.se/',
				version : "1.0"
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('tinywebtex', tinymce.plugins.TinyWebtexPlugin);
})();<commit_msg>Don't enable math editor when image is not properly selected.<commit_after>/*
  Copyright: (C) 2012 KTH, Kungliga tekniska hogskolan, http://www.kth.se/

  This file is part of tinywebtex.
 */

(function() {
	// Load plugin specific language pack
	tinymce.PluginManager.requireLangPack('tinywebtex');

	tinymce.create('tinymce.plugins.TinyWebtexPlugin', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
			// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
			ed.addCommand('mceTinyWebtex', function() {
			    if (ed.dom.getAttrib(ed.selection.getNode(), 'class', '').indexOf('mceItem') != -1)
                    return;

				ed.windowManager.open({
					file : url + '/dialog.htm',
					width : 500 + parseInt(ed.getLang('tinywebtex.delta_width', 0)),
					height : 200 + parseInt(ed.getLang('tinywebtex.delta_height', 0)),
					inline : 0
				}, {
					plugin_url : url, // Plugin absolute URL
					webtex_url : 'http://localhost:8080/webtex' // Base URL of WebTex service
				});
			});

			// Register example button
			ed.addButton('tinywebtex', {
				title : 'tinywebtex.desc',
				cmd : 'mceTinyWebtex',
				image : url + '/img/button.png'
			});

			// ctrl+e = cmd+e on a mac
            ed.addShortcut('ctrl+e', "Equation editor", 'mceTinyWebtex');

            // Add a node change handler, selects the button in the UI when a image is selected
            ed.onNodeChange.add(function(ed, cm, n, co) {
                cm.setActive('tinywebtex', !co && (n.nodeName == 'IMG') && n.className.match('webtex'));
            });

		},

		/**
		 * Creates control instances based in the incomming name. This method is normally not
		 * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
		 * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
		 * method can be used to create those.
		 *
		 * @param {String} n Name of the control to create.
		 * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
		 * @return {tinymce.ui.Control} New control instance or null if no control was created.
		 */
		createControl : function(n, cm) {
			return null;
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Tiny Webtex',
				author : 'infosys@kth.se',
				authorurl : 'http://www.kth.se/',
				infourl : 'http://www.kth.se/',
				version : "1.0"
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('tinywebtex', tinymce.plugins.TinyWebtexPlugin);
})();<|endoftext|>


<commit_before>var ResizableStage = (function (changeCoords, changePath, PxCollisionDetector, inheritMethods) {
    "use strict";

    function ResizableStage(stage, gfx, resizer, createInput, changeInput, width, height, timer) {
        this.stage = stage;
        this.gfx = gfx;
        this.resizer = resizer;
        this.createInput = createInput;
        this.changeInput = changeInput; //maybe push to global class dependency injection (see line 1)

        this.width = width;
        this.height = height;

        this.timer = timer;

        this.collisions = {};

        inheritMethods(stage, this, ResizableStage.prototype);
    }

    ResizableStage.prototype.getCollisionDetector = function (drawable) {
        var collisions = new PxCollisionDetector(drawable);
        this.collisions[drawable.id] = collisions;

        return collisions;
    };

    ResizableStage.prototype.detachCollisionDetector = function (collisionDetector) {
        delete this.collisions[collisionDetector.drawable.id];
    };

    ResizableStage.prototype.drawFresh = function (xFn, yFn, imgName, zIndex, resizeIsDependentOnThisDrawables, alpha,
        rotation, scale) {
        var drawable = this.stage.drawFresh(xFn(this.width), yFn(this.height), imgName, zIndex, alpha, rotation, scale);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
        }, resizeIsDependentOnThisDrawables);

        return drawable;
    };

    ResizableStage.prototype.drawFreshWithInput = function (xFn, yFn, imgName, zIndex, resizeIsDependentOnThisDrawables,
        alpha, rotation, scale) {
        var drawable = this.stage.drawFresh(xFn(this.width), yFn(this.height), imgName, zIndex, alpha, rotation, scale);
        var self = this;
        var input = self.createInput(drawable);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            self.changeInput(input, drawable);
        }, resizeIsDependentOnThisDrawables);

        return {
            drawable: drawable,
            input: input
        };
    };

    ResizableStage.prototype.drawText = function (xFn, yFn, text, sizeFn, font, color, zIndex,
        resizeIsDependentOnThisDrawables, rotation, alpha, maxLineLength, lineHeight) {
        var drawable = this.stage.drawText(xFn(this.width), yFn(this.height), text, sizeFn(this.width, this.height),
            font, color, zIndex, rotation, alpha, maxLineLength, lineHeight);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            drawable.txt.size = sizeFn(width, height);
        }, resizeIsDependentOnThisDrawables);

        return drawable;
    };

    ResizableStage.prototype.drawTextWithInput = function (xFn, yFn, text, sizeFn, font, color, zIndex,
        resizeIsDependentOnThisDrawables, alpha, rotation, maxLineLength, lineHeight) {
        var drawable = this.stage.getDrawableText(xFn(this.width), yFn(this.height), zIndex, text,
            sizeFn(this.width, this.height), font, color, rotation, alpha, maxLineLength, lineHeight);
        this.stage.draw(drawable);
        var input = this.createInput(drawable);
        var self = this;
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            drawable.txt.size = sizeFn(width, height);
            self.changeInput(input, drawable);
        }, resizeIsDependentOnThisDrawables);

        return {
            drawable: drawable,
            input: input
        };
    };

    ResizableStage.prototype.resize = function (width, height) {
        this.width = width;
        this.height = height;

        this.stage.resize(width, height);
        if (this.gfx.resize)
            this.gfx.resize(width, height);
        this.resizer.call(width, height);

        for (var key in this.collisions) {
            this.collisions[key].resize();
        }
    };

    ResizableStage.prototype.animateFresh = function (xFn, yFn, imgPathName, numberOfFrames, loop,
        resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {

        var wrapper = this.stage.animateFresh(xFn(this.width), yFn(this.height), imgPathName, numberOfFrames, loop,
            zIndex, alpha, rotation, scale);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;
    };

    ResizableStage.prototype.moveFresh = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBack;
        if (callback) {
            if (loop)
                enhancedCallBack = callback; else {
                enhancedCallBack = function () {
                    callback();
                    registerResizeAfterMove();
                }
            }
        } else {
            if (loop)
                enhancedCallBack = undefined; else
                enhancedCallBack = registerResizeAfterMove;
        }

        var wrapper = this.stage.moveFresh(xFn(this.width), yFn(this.height), imgName, endXFn(this.width),
            endYFn(this.height), speed, spacing, loop, enhancedCallBack, zIndex, alpha, rotation, scale);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
            changePath(wrapper.path, xFn(width), yFn(height), endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;
    };

    ResizableStage.prototype.moveFreshText = function (xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed,
        spacing, loop, callback, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, maxLineLength, lineHeight) {

        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
                wrapper.drawable.txt.size = sizeFn(width, height);
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBack;
        if (callback) {
            enhancedCallBack = function () {
                callback();
                registerResizeAfterMove();
            }
        } else {
            enhancedCallBack = registerResizeAfterMove;
        }

        var wrapper = this.stage.moveFreshText(xFn(this.width), yFn(this.height), text, sizeFn(this.width, this.height),
            font, color, endXFn(this.width), endYFn(this.height), speed, spacing, loop, enhancedCallBack, zIndex, alpha,
            rotation, maxLineLength, lineHeight);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
            wrapper.drawable.txt.size = sizeFn(width, height);
            changePath(wrapper.path, xFn(width), yFn(height), endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;

    };

    ResizableStage.prototype.moveFreshRoundTrip = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing,
        loopTheTrip, callbackTo, callbackReturn, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var self = this;
        var registerResizeReturn = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
                changePath(wrapper.pathTo, xFn(width), yFn(height), endXFn(width), endYFn(height));
                changePath(wrapper.pathReturn, endXFn(width), endYFn(height), xFn(width), yFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBackTo;
        if (callbackTo) {
            enhancedCallBackTo = function () {
                callbackTo();
                registerResizeReturn();
            }
        } else {
            enhancedCallBackTo = registerResizeReturn;
        }

        var initResize = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, xFn(width), yFn(height));
                changePath(wrapper.pathTo, xFn(width), yFn(height), endXFn(width), endYFn(height));
                changePath(wrapper.pathReturn, endXFn(width), endYFn(height), xFn(width), yFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var registerResizeTo = function () {
            if (loopTheTrip) {
                initResize();
            } else {
                self.resizer.add(wrapper.drawable, function (width, height) {
                    changeCoords(wrapper.drawable, xFn(width), yFn(height));
                }, resizeIsDependentOnThisDrawables);
            }
        };

        var enhancedCallBackFrom;
        if (callbackTo) {
            enhancedCallBackFrom = function () {
                callbackTo();
                registerResizeTo();
            }
        } else {
            enhancedCallBackFrom = registerResizeTo;
        }

        var wrapper = this.stage.moveFreshRoundTrip(xFn(this.width), yFn(this.height), imgName, endXFn(this.width),
            endYFn(this.height), speed, spacing, loopTheTrip, enhancedCallBackTo, enhancedCallBackFrom, zIndex, alpha,
            rotation, scale);

        initResize();

        return wrapper;
    };

    ResizableStage.prototype.moveFreshLater = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing, delay, loop,
        callback, startedMovingCallback, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var self = this;
        this.timer.doLater(function () {
            if (startedMovingCallback) {
                startedMovingCallback();
            }
            self.moveFresh(xFn, yFn, imgName, endXFn, endYFn, speed, spacing, loop, callback,
                resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale);

        }, delay);
    };

    ResizableStage.prototype.moveFreshTextLater = function (xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed,
        spacing, delay, loop, callback, startedMovingCallback, resizeIsDependentOnThisDrawables, zIndex, alpha,
        rotation, maxLineLength, lineHeight) {
        var self = this;
        this.timer.doLater(function () {
            if (startedMovingCallback) {
                startedMovingCallback();
            }
            self.moveFreshText(xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed, spacing, loop, callback,
                resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, maxLineLength, lineHeight);
        }, delay);
    };

    ResizableStage.prototype.move = function (drawable, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables) {
        var pathId = {id: drawable.id + '_1'};
        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.remove(pathId);

            if (drawable.txt) {
                var afterFontSize_id = {id: drawable.id + '_2'};
                self.resizer.add(afterFontSize_id, function (width, height) {
                    changeCoords(drawable, endXFn(width), endYFn(height));
                }, resizeIsDependentOnThisDrawables);
            } else {
                resizeIsDependentOnThisDrawables = resizeIsDependentOnThisDrawables.filter(function (element) {
                    return element.id != drawable.id;
                });
                self.resizer.add(drawable, function (width, height) {
                    changeCoords(drawable, endXFn(width), endYFn(height));
                }, resizeIsDependentOnThisDrawables);
            }
        };

        var enhancedCallBack;
        if (callback) {
            enhancedCallBack = function () {
                registerResizeAfterMove();
                callback();
            }
        } else {
            enhancedCallBack = registerResizeAfterMove;
        }

        var path = this.stage.getPath(drawable.x, drawable.y, endXFn(this.width), endYFn(this.height), speed, spacing,
            loop);

        this.stage.move(drawable, path, enhancedCallBack);

        if (resizeIsDependentOnThisDrawables) {
            resizeIsDependentOnThisDrawables.push(drawable);
        } else {
            resizeIsDependentOnThisDrawables = [drawable];
        }

        this.resizer.add(pathId, function (width, height) {
            changePath(path, drawable.x, drawable.y, endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);
    };

    ResizableStage.prototype.moveRoundTrip = function (drawable, endXFn, endYFn, speed, spacing, loopTheTrip,
        callbackTo, callbackReturn, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        //todo implement
    };

    ResizableStage.prototype.moveLater = function (drawable, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables, duration, laterCallback) {
        var self = this;
        this.timer.doLater(function () {
            if (laterCallback) {
                laterCallback();
            }
            self.move(drawable, endXFn, endYFn, speed, spacing, loop, callback, resizeIsDependentOnThisDrawables);

        }, duration);
    };

    ResizableStage.prototype.remove = function (drawable) {
        this.resizer.remove(drawable);
        var idOfPossiblePath = {
            id: drawable.id + '_1'
        };
        this.resizer.remove(idOfPossiblePath);
        var idOfPossibleTxtSizeAfterPath = {
            id: drawable.id + '_2'
        };
        this.resizer.remove(idOfPossibleTxtSizeAfterPath);
        this.stage.remove(drawable);
    };

    ResizableStage.prototype.show = function (drawable) {
        this.stage.draw(drawable);
    };

    ResizableStage.prototype.hide = function (drawable) {
        this.stage.remove(drawable);
    };

    ResizableStage.prototype.has = function (drawable) {
        return this.resizer.has(drawable) || this.stage.has(drawable);
    };

    ResizableStage.prototype.update = function () {
        this.stage.update();
        this.timer.update();
    };

    return ResizableStage;
})(changeCoords, changePath, CanvasImageCollisionDetector, inheritMethods);<commit_msg>fixing return objects for move later API methods #core (cherry picked from commit 52ba791)<commit_after>var ResizableStage = (function (changeCoords, changePath, PxCollisionDetector, inheritMethods) {
    "use strict";

    function ResizableStage(stage, gfx, resizer, createInput, changeInput, width, height, timer) {
        this.stage = stage;
        this.gfx = gfx;
        this.resizer = resizer;
        this.createInput = createInput;
        this.changeInput = changeInput; //maybe push to global class dependency injection (see line 1)

        this.width = width;
        this.height = height;

        this.timer = timer;

        this.collisions = {};

        inheritMethods(stage, this, ResizableStage.prototype);
    }

    ResizableStage.prototype.getCollisionDetector = function (drawable) {
        var collisions = new PxCollisionDetector(drawable);
        this.collisions[drawable.id] = collisions;

        return collisions;
    };

    ResizableStage.prototype.detachCollisionDetector = function (collisionDetector) {
        delete this.collisions[collisionDetector.drawable.id];
    };

    ResizableStage.prototype.drawFresh = function (xFn, yFn, imgName, zIndex, resizeIsDependentOnThisDrawables, alpha,
        rotation, scale) {
        var drawable = this.stage.drawFresh(xFn(this.width), yFn(this.height), imgName, zIndex, alpha, rotation, scale);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
        }, resizeIsDependentOnThisDrawables);

        return drawable;
    };

    ResizableStage.prototype.drawFreshWithInput = function (xFn, yFn, imgName, zIndex, resizeIsDependentOnThisDrawables,
        alpha, rotation, scale) {
        var drawable = this.stage.drawFresh(xFn(this.width), yFn(this.height), imgName, zIndex, alpha, rotation, scale);
        var self = this;
        var input = self.createInput(drawable);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            self.changeInput(input, drawable);
        }, resizeIsDependentOnThisDrawables);

        return {
            drawable: drawable,
            input: input
        };
    };

    ResizableStage.prototype.drawText = function (xFn, yFn, text, sizeFn, font, color, zIndex,
        resizeIsDependentOnThisDrawables, rotation, alpha, maxLineLength, lineHeight) {
        var drawable = this.stage.drawText(xFn(this.width), yFn(this.height), text, sizeFn(this.width, this.height),
            font, color, zIndex, rotation, alpha, maxLineLength, lineHeight);
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            drawable.txt.size = sizeFn(width, height);
        }, resizeIsDependentOnThisDrawables);

        return drawable;
    };

    ResizableStage.prototype.drawTextWithInput = function (xFn, yFn, text, sizeFn, font, color, zIndex,
        resizeIsDependentOnThisDrawables, alpha, rotation, maxLineLength, lineHeight) {
        var drawable = this.stage.getDrawableText(xFn(this.width), yFn(this.height), zIndex, text,
            sizeFn(this.width, this.height), font, color, rotation, alpha, maxLineLength, lineHeight);
        this.stage.draw(drawable);
        var input = this.createInput(drawable);
        var self = this;
        this.resizer.add(drawable, function (width, height) {
            changeCoords(drawable, xFn(width), yFn(height));
            drawable.txt.size = sizeFn(width, height);
            self.changeInput(input, drawable);
        }, resizeIsDependentOnThisDrawables);

        return {
            drawable: drawable,
            input: input
        };
    };

    ResizableStage.prototype.resize = function (width, height) {
        this.width = width;
        this.height = height;

        this.stage.resize(width, height);
        if (this.gfx.resize)
            this.gfx.resize(width, height);
        this.resizer.call(width, height);

        for (var key in this.collisions) {
            this.collisions[key].resize();
        }
    };

    ResizableStage.prototype.animateFresh = function (xFn, yFn, imgPathName, numberOfFrames, loop,
        resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {

        var wrapper = this.stage.animateFresh(xFn(this.width), yFn(this.height), imgPathName, numberOfFrames, loop,
            zIndex, alpha, rotation, scale);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;
    };

    ResizableStage.prototype.moveFresh = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBack;
        if (callback) {
            if (loop)
                enhancedCallBack = callback; else {
                enhancedCallBack = function () {
                    callback();
                    registerResizeAfterMove();
                }
            }
        } else {
            if (loop)
                enhancedCallBack = undefined; else
                enhancedCallBack = registerResizeAfterMove;
        }

        var wrapper = this.stage.moveFresh(xFn(this.width), yFn(this.height), imgName, endXFn(this.width),
            endYFn(this.height), speed, spacing, loop, enhancedCallBack, zIndex, alpha, rotation, scale);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
            changePath(wrapper.path, xFn(width), yFn(height), endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;
    };

    ResizableStage.prototype.moveFreshText = function (xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed,
        spacing, loop, callback, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, maxLineLength, lineHeight) {

        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
                wrapper.drawable.txt.size = sizeFn(width, height);
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBack;
        if (callback) {
            enhancedCallBack = function () {
                callback();
                registerResizeAfterMove();
            }
        } else {
            enhancedCallBack = registerResizeAfterMove;
        }

        var wrapper = this.stage.moveFreshText(xFn(this.width), yFn(this.height), text, sizeFn(this.width, this.height),
            font, color, endXFn(this.width), endYFn(this.height), speed, spacing, loop, enhancedCallBack, zIndex, alpha,
            rotation, maxLineLength, lineHeight);

        this.resizer.add(wrapper.drawable, function (width, height) {
            changeCoords(wrapper.drawable, xFn(width), yFn(height));
            wrapper.drawable.txt.size = sizeFn(width, height);
            changePath(wrapper.path, xFn(width), yFn(height), endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);

        return wrapper;

    };

    ResizableStage.prototype.moveFreshRoundTrip = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing,
        loopTheTrip, callbackTo, callbackReturn, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var self = this;
        var registerResizeReturn = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, endXFn(width), endYFn(height));
                changePath(wrapper.pathTo, xFn(width), yFn(height), endXFn(width), endYFn(height));
                changePath(wrapper.pathReturn, endXFn(width), endYFn(height), xFn(width), yFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var enhancedCallBackTo;
        if (callbackTo) {
            enhancedCallBackTo = function () {
                callbackTo();
                registerResizeReturn();
            }
        } else {
            enhancedCallBackTo = registerResizeReturn;
        }

        var initResize = function () {
            self.resizer.add(wrapper.drawable, function (width, height) {
                changeCoords(wrapper.drawable, xFn(width), yFn(height));
                changePath(wrapper.pathTo, xFn(width), yFn(height), endXFn(width), endYFn(height));
                changePath(wrapper.pathReturn, endXFn(width), endYFn(height), xFn(width), yFn(height));
            }, resizeIsDependentOnThisDrawables);
        };

        var registerResizeTo = function () {
            if (loopTheTrip) {
                initResize();
            } else {
                self.resizer.add(wrapper.drawable, function (width, height) {
                    changeCoords(wrapper.drawable, xFn(width), yFn(height));
                }, resizeIsDependentOnThisDrawables);
            }
        };

        var enhancedCallBackFrom;
        if (callbackTo) {
            enhancedCallBackFrom = function () {
                callbackTo();
                registerResizeTo();
            }
        } else {
            enhancedCallBackFrom = registerResizeTo;
        }

        var wrapper = this.stage.moveFreshRoundTrip(xFn(this.width), yFn(this.height), imgName, endXFn(this.width),
            endYFn(this.height), speed, spacing, loopTheTrip, enhancedCallBackTo, enhancedCallBackFrom, zIndex, alpha,
            rotation, scale);

        initResize();

        return wrapper;
    };

    ResizableStage.prototype.moveFreshLater = function (xFn, yFn, imgName, endXFn, endYFn, speed, spacing, delay, loop,
        callback, startedMovingCallback, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        var returnObject = {};
        var self = this;
        this.timer.doLater(function () {
            if (startedMovingCallback) {
                startedMovingCallback();
            }
            var wrapper = self.moveFresh(xFn, yFn, imgName, endXFn, endYFn, speed, spacing, loop, callback,
                resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale);

            for (var key in wrapper) {
                if (wrapper.hasOwnProperty(key)) {
                    returnObject[key] = wrapper[key];
                }
            }
        }, delay);
        return returnObject;
    };

    ResizableStage.prototype.moveFreshTextLater = function (xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed,
        spacing, delay, loop, callback, startedMovingCallback, resizeIsDependentOnThisDrawables, zIndex, alpha,
        rotation, maxLineLength, lineHeight) {
        var returnObject = {};
        var self = this;
        this.timer.doLater(function () {
            if (startedMovingCallback) {
                startedMovingCallback();
            }
            var wrapper = self.moveFreshText(xFn, yFn, text, sizeFn, font, color, endXFn, endYFn, speed, spacing, loop,
                callback, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, maxLineLength, lineHeight);

            for (var key in wrapper) {
                if (wrapper.hasOwnProperty(key)) {
                    returnObject[key] = wrapper[key];
                }
            }
        }, delay);
        return returnObject;
    };

    ResizableStage.prototype.move = function (drawable, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables) {
        var pathId = {id: drawable.id + '_1'};
        var self = this;
        var registerResizeAfterMove = function () {
            self.resizer.remove(pathId);

            if (drawable.txt) {
                var afterFontSize_id = {id: drawable.id + '_2'};
                self.resizer.add(afterFontSize_id, function (width, height) {
                    changeCoords(drawable, endXFn(width), endYFn(height));
                }, resizeIsDependentOnThisDrawables);
            } else {
                resizeIsDependentOnThisDrawables = resizeIsDependentOnThisDrawables.filter(function (element) {
                    return element.id != drawable.id;
                });
                self.resizer.add(drawable, function (width, height) {
                    changeCoords(drawable, endXFn(width), endYFn(height));
                }, resizeIsDependentOnThisDrawables);
            }
        };

        var enhancedCallBack;
        if (callback) {
            enhancedCallBack = function () {
                registerResizeAfterMove();
                callback();
            }
        } else {
            enhancedCallBack = registerResizeAfterMove;
        }

        var path = this.stage.getPath(drawable.x, drawable.y, endXFn(this.width), endYFn(this.height), speed, spacing,
            loop);

        this.stage.move(drawable, path, enhancedCallBack);

        if (resizeIsDependentOnThisDrawables) {
            resizeIsDependentOnThisDrawables.push(drawable);
        } else {
            resizeIsDependentOnThisDrawables = [drawable];
        }

        this.resizer.add(pathId, function (width, height) {
            changePath(path, drawable.x, drawable.y, endXFn(width), endYFn(height));
        }, resizeIsDependentOnThisDrawables);
    };

    ResizableStage.prototype.moveRoundTrip = function (drawable, endXFn, endYFn, speed, spacing, loopTheTrip,
        callbackTo, callbackReturn, resizeIsDependentOnThisDrawables, zIndex, alpha, rotation, scale) {
        //todo implement
    };

    ResizableStage.prototype.moveLater = function (drawable, endXFn, endYFn, speed, spacing, loop, callback,
        resizeIsDependentOnThisDrawables, duration, laterCallback) {
        var self = this;
        this.timer.doLater(function () {
            if (laterCallback) {
                laterCallback();
            }
            self.move(drawable, endXFn, endYFn, speed, spacing, loop, callback, resizeIsDependentOnThisDrawables);

        }, duration);
    };

    ResizableStage.prototype.remove = function (drawable) {
        this.resizer.remove(drawable);
        var idOfPossiblePath = {
            id: drawable.id + '_1'
        };
        this.resizer.remove(idOfPossiblePath);
        var idOfPossibleTxtSizeAfterPath = {
            id: drawable.id + '_2'
        };
        this.resizer.remove(idOfPossibleTxtSizeAfterPath);
        this.stage.remove(drawable);
    };

    ResizableStage.prototype.show = function (drawable) {
        this.stage.draw(drawable);
    };

    ResizableStage.prototype.hide = function (drawable) {
        this.stage.remove(drawable);
    };

    ResizableStage.prototype.has = function (drawable) {
        return this.resizer.has(drawable) || this.stage.has(drawable);
    };

    ResizableStage.prototype.update = function () {
        this.stage.update();
        this.timer.update();
    };

    return ResizableStage;
})(changeCoords, changePath, CanvasImageCollisionDetector, inheritMethods);<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

// Components
import Tabs from 'components/ui/Tabs';
import Spinner from 'components/ui/Spinner';
import Paginator from 'components/ui/Paginator';
import SearchInput from 'components/ui/SearchInput';
import WidgetList from 'components/widgets/list/WidgetList';

export default function WidgetBlockEdition({ data, onChangeTab, onSelectWidget, onChangePage, onChangeSearch }) {
  return (

Select widget

                  <Tabs
                    options={[
                      { label: 'My widgets', value: 'my-widgets' },
                      { label: 'All widgets', value: 'all-widgets' }
                    ]}
                    defaultSelected={data.tab}
                    selected={data.tab}
                    onChange={onChangeTab}
                  />

                <SearchInput
                  input={{
                    placeholder: 'Search widget'
                  }}
                  link={{}}
                  onSearch={onChangeSearch}
                />

                <Spinner isLoading={data.loading} className="-relative -small -light" />

                <WidgetList
                  widgets={data.widgets}
                  mode="grid"
                  onWidgetClick={onSelectWidget}
                />

                <Spinner isLoading={data.loading} className="-relative -small -light" />

                <Paginator
                  options={{
                    size: data.total,
                    page: data.page,
                    limit: data.pageSize
                  }}
                  onChange={onChangePage}
                />

  );
}

WidgetBlockEdition.propTypes = {
  data: PropTypes.object,
  onChangeTab: PropTypes.func,
  onChangePage: PropTypes.func,
  onChangeSearch: PropTypes.func,
  onSelectWidget: PropTypes.func
};

WidgetBlockEdition.defaultProps = {
  data: {},
  user: {},
  onChangeTab: null,
  onChangePage: null,
  onChangeSearch: null,
  onSelectWidget: null
};
<commit_msg>workaround for pageSize not coming as a prop<commit_after>import React from 'react';
import PropTypes from 'prop-types';

// Components
import Tabs from 'components/ui/Tabs';
import Spinner from 'components/ui/Spinner';
import Paginator from 'components/ui/Paginator';
import SearchInput from 'components/ui/SearchInput';
import WidgetList from 'components/widgets/list/WidgetList';

export default function WidgetBlockEdition({ data, onChangeTab, onSelectWidget,
  onChangePage, onChangeSearch }) {
  console.log('data', data);
  return (

Select widget

                  <Tabs
                    options={[
                      { label: 'My widgets', value: 'my-widgets' },
                      { label: 'All widgets', value: 'all-widgets' }
                    ]}
                    defaultSelected={data.tab}
                    selected={data.tab}
                    onChange={onChangeTab}
                  />

                <SearchInput
                  input={{
                    placeholder: 'Search widget'
                  }}
                  link={{}}
                  onSearch={onChangeSearch}
                />

                <Spinner isLoading={data.loading} className="-relative -small -light" />

                {data.widgets &&
                  <WidgetList
                    widgets={data.widgets}
                    mode="grid"
                    onWidgetClick={onSelectWidget}
                  />
                }

                {data.total &&
                  <Paginator
                    options={{
                      size: data.total,
                      page: data.page,
                      limit: data.pageSize || 9
                    }}
                    onChange={onChangePage}
                  />
                }

  );
}

WidgetBlockEdition.propTypes = {
  data: PropTypes.object,
  onChangeTab: PropTypes.func,
  onChangePage: PropTypes.func,
  onChangeSearch: PropTypes.func,
  onSelectWidget: PropTypes.func
};

WidgetBlockEdition.defaultProps = {
  data: {},
  user: {},
  onChangeTab: null,
  onChangePage: null,
  onChangeSearch: null,
  onSelectWidget: null
};
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
 *
 * 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.
 */

Ext.define('Traccar.controller.Root', {
    extend: 'Ext.app.Controller',

    requires: [
        'Traccar.view.Login',
        'Traccar.view.Main',
        'Traccar.view.MainMobile'
    ],

    init: function () {
        var indicator = document.createElement('div');
        indicator.className = 'state-indicator';
        document.body.appendChild(indicator);
        this.isPhone = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10) !== 0;
    },

    onLaunch: function () {
        Ext.Ajax.request({
            scope: this,
            url: '/api/server',
            callback: this.onServerReturn
        });
    },

    onServerReturn: function (options, success, response) {
        Ext.get('spinner').remove();
        if (success) {
            Traccar.app.setServer(Ext.decode(response.responseText));
            Ext.Ajax.request({
                scope: this,
                url: '/api/session',
                callback: this.onSessionReturn
            });
        } else {
            Traccar.app.showError(response);
        }
    },

    onSessionReturn: function (options, success, response) {
        if (success) {
            Traccar.app.setUser(Ext.decode(response.responseText));
            this.loadApp();
        } else {
            this.login = Ext.create('widget.login', {
                listeners: {
                    scope: this,
                    login: this.onLogin
                }
            });
            this.login.show();
        }
    },

    onLogin: function () {
        this.login.close();
        this.loadApp();
    },

    loadApp: function () {
        Ext.getStore('Groups').load();
        Ext.getStore('Devices').load();
        Ext.get('attribution').remove();
        if (this.isPhone) {
            Ext.create('widget.mainMobile');
        } else {
            Ext.create('widget.main');
        }
        this.asyncUpdate(true);
    },

    asyncUpdate: function (first) {
        var protocol, socket, self = this;
        protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
        socket = new WebSocket(protocol + '//' + window.location.host + '/api/socket');

        socket.onclose = function (event) {
            self.asyncUpdate(false);
        };

        socket.onmessage = function (event) {
            var i, store, data, array, entity;

            data = Ext.decode(event.data);

            if (data.devices) {
                array = data.devices;
                store = Ext.getStore('Devices');
                for (i = 0; i < array.length; i++) {
                    entity = store.findRecord('id', array[i].id, 0, false, false, true);
                    if (entity) {
                        entity.set({
                            status: array[i].status,
                            lastUpdate: array[i].lastUpdate
                        }, {
                            dirty: false
                        });
                    }
                }
            }

            if (data.positions) {
                array = data.positions;
                store = Ext.getStore('LatestPositions');
                for (i = 0; i < array.length; i++) {
                    entity = store.findRecord('deviceId', array[i].deviceId, 0, false, false, true);
                    if (entity) {
                        entity.set(array[i]);
                    } else {
                        store.add(Ext.create('Traccar.model.Position', array[i]));
                    }
                }
            }
        };
    }
});
<commit_msg>Use correct method to find by id<commit_after>/*
 * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
 *
 * 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.
 */

Ext.define('Traccar.controller.Root', {
    extend: 'Ext.app.Controller',

    requires: [
        'Traccar.view.Login',
        'Traccar.view.Main',
        'Traccar.view.MainMobile'
    ],

    init: function () {
        var indicator = document.createElement('div');
        indicator.className = 'state-indicator';
        document.body.appendChild(indicator);
        this.isPhone = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10) !== 0;
    },

    onLaunch: function () {
        Ext.Ajax.request({
            scope: this,
            url: '/api/server',
            callback: this.onServerReturn
        });
    },

    onServerReturn: function (options, success, response) {
        Ext.get('spinner').remove();
        if (success) {
            Traccar.app.setServer(Ext.decode(response.responseText));
            Ext.Ajax.request({
                scope: this,
                url: '/api/session',
                callback: this.onSessionReturn
            });
        } else {
            Traccar.app.showError(response);
        }
    },

    onSessionReturn: function (options, success, response) {
        if (success) {
            Traccar.app.setUser(Ext.decode(response.responseText));
            this.loadApp();
        } else {
            this.login = Ext.create('widget.login', {
                listeners: {
                    scope: this,
                    login: this.onLogin
                }
            });
            this.login.show();
        }
    },

    onLogin: function () {
        this.login.close();
        this.loadApp();
    },

    loadApp: function () {
        Ext.getStore('Groups').load();
        Ext.getStore('Devices').load();
        Ext.get('attribution').remove();
        if (this.isPhone) {
            Ext.create('widget.mainMobile');
        } else {
            Ext.create('widget.main');
        }
        this.asyncUpdate(true);
    },

    asyncUpdate: function (first) {
        var protocol, socket, self = this;
        protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
        socket = new WebSocket(protocol + '//' + window.location.host + '/api/socket');

        socket.onclose = function (event) {
            self.asyncUpdate(false);
        };

        socket.onmessage = function (event) {
            var i, store, data, array, entity;

            data = Ext.decode(event.data);

            if (data.devices) {
                array = data.devices;
                store = Ext.getStore('Devices');
                for (i = 0; i < array.length; i++) {
                    entity = store.getById(array[i].id);
                    if (entity) {
                        entity.set({
                            status: array[i].status,
                            lastUpdate: array[i].lastUpdate
                        }, {
                            dirty: false
                        });
                    }
                }
            }

            if (data.positions) {
                array = data.positions;
                store = Ext.getStore('LatestPositions');
                for (i = 0; i < array.length; i++) {
                    entity = store.findRecord('deviceId', array[i].deviceId, 0, false, false, true);
                    if (entity) {
                        entity.set(array[i]);
                    } else {
                        store.add(Ext.create('Traccar.model.Position', array[i]));
                    }
                }
            }
        };
    }
});
<|endoftext|>


<commit_before>/** This is the workspace. Typically owner should be null. */
hax.core.Workspace = function(nameOrJson,actionResponseForJson,owner) {
    //base init
    hax.core.EventManager.init.call(this);
    hax.core.ContextHolder.init.call(this);
    hax.core.Owner.init.call(this);
    hax.core.RootHolder.init.call(this);

    if(owner === undefined) owner = null;
    this.owner = owner;

    var inputArgType = hax.core.util.getObjectType(nameOrJson);

    if(inputArgType === "String") {
        this.name = nameOrJson;
        this.rootFolder = new hax.core.Folder(nameOrJson,this);
    }
    else {
        this.loadFromJson(nameOrJson,actionResponseForJson);
    }
}

//add components to this class
hax.core.util.mixin(hax.core.Workspace,hax.core.EventManager);
hax.core.util.mixin(hax.core.Workspace,hax.core.ContextHolder);
hax.core.util.mixin(hax.core.Workspace,hax.core.Owner);
hax.core.util.mixin(hax.core.Workspace,hax.core.RootHolder);

/** this method gets the workspace name. */
hax.core.Workspace.prototype.getName = function() {
    return this.name;
}

/** this method gets the root package for the workspace. */
hax.core.Workspace.prototype.getRoot = function() {
    return this.rootFolder;
}

/** This method sets the root object - implemented from RootHolder.  */
hax.core.Workspace.prototype.setRoot = function(child) {
    this.rootFolder = child;
}

/** This allows for a workspace to have a parent. For a normal workspace this should be null.
 * This is used for finding variables in scope. */
hax.core.Workspace.prototype.getOwner = function() {
    return this.owner;
}

/** This method updates the dependencies of any children in the workspace. */
hax.core.Workspace.prototype.updateDependeciesForModelChange = function(recalculateList) {
    if(this.rootFolder) {
        this.rootFolder.updateDependeciesForModelChange(recalculateList);
    }
}

/** This method removes any data from this workspace on closing. */
hax.core.Workspace.prototype.close = function() {
}

//------------------------------
// Owner Methods
//------------------------------

/** this method is implemented for the Owner component/mixin. */
hax.core.Workspace.prototype.getWorkspace = function() {
   return this;
}

/** this method gets the hame the children inherit for the full name. */
hax.core.Workspace.prototype.getPossesionNameBase = function() {
    return this.name + ":";
}

//------------------------------
//ContextHolder methods
//------------------------------

/** This method retrieve creates the loaded context manager. */
hax.core.Workspace.prototype.createContextManager = function() {
    //set the context manager
    var contextManager = new hax.core.ContextManager(this);
    //global variables from window object
    var globalVarEntry = {};
    globalVarEntry.isLocal = false;
    globalVarEntry.data = __globals__;
    contextManager.addToContextList(globalVarEntry);

    return contextManager;
}

//==========================
//virtual workspace methods
//==========================

/** This method makes a virtual workspace that contains a copy of the give folder
 * as the root folder. Optionally the context manager may be set. */
hax.core.Workspace.createVirtualWorkpaceFromFolder = function(name,origRootFolder,ownerInWorkspace) {
	//create a workspace json from the root folder json
	var workspaceJson = {};
    workspaceJson.name = name;
    workspaceJson.fileType = hax.core.Workspace.SAVE_FILE_TYPE;
    workspaceJson.version = hax.core.Workspace.SAVE_FILE_VERSION;
    workspaceJson.data = origRootFolder.toJson();

    return new hax.core.Workspace(workspaceJson,null,ownerInWorkspace);
}

//============================
// Save Functions
//============================

/** This is the supported file type. */
hax.core.Workspace.SAVE_FILE_TYPE = "hax workspace";

/** This is the supported file version. */
hax.core.Workspace.SAVE_FILE_VERSION = 0.1;

hax.core.Workspace.prototype.toJson = function() {
    var json = {};
    json.name = this.name;
    json.fileType = hax.core.Workspace.SAVE_FILE_TYPE;
    json.version = hax.core.Workspace.SAVE_FILE_VERSION;

    //components
    json.data = this.rootFolder.toJson();

    return json;
}

/** This is loads data from the given json into this workspace.
 * @private */
hax.core.Workspace.prototype.loadFromJson = function(json,actionResponse) {
    var fileType = json.fileType;
	if(fileType !== hax.core.Workspace.SAVE_FILE_TYPE) {
		throw hax.core.util.createError("Bad file format.",false);
	}
    if(json.version !== hax.core.Workspace.SAVE_FILE_VERSION) {
        throw hax.core.util.createError("Incorrect file version.",false);
    }

    this.name = json.name;

	//load context links
	if(json.contextManager) {
		//for now just include this one. Later we need to have some options
		//for saving and opening
		//THIS IS ONLY FOR THE WORKSHEET IMPLEMENTATION FOR NOW!
		this.setContextManager(json.contextManager);
	}

	//recreate the root folder and its children
    //this.rootFolder = hax.core.createmember.createMember(this,json.data,actionResponse);
    //DOH! This currently doesn't because create member assumes the root folder is set.
    //maybe we should update so setting the owner on the root folder sets the root folder,
    //such as if the alternative to a parent is a "rootholder" or something like that.
    //for now I will jsut copy everything in create member

    if(!actionResponse) actionResponse = new hax.core.ActionResponse();

    hax.core.createmember.createMember(this,json.data,actionResponse);

    return actionResponse;
}

//================================
// Member generator functions
//================================

hax.core.Workspace.memberGenerators = {};

/** This methods retrieves the member generator for the given type. */
hax.core.Workspace.getMemberGenerator = function(type) {
    return hax.core.Workspace.memberGenerators[type];
}

/** This method registers the member generator for a given named type. */
hax.core.Workspace.addMemberGenerator = function(generator) {
    hax.core.Workspace.memberGenerators[generator.type] = generator;
}<commit_msg>get rid of some old, unneeded code when deserilaizing workspace<commit_after>/** This is the workspace. Typically owner should be null. */
hax.core.Workspace = function(nameOrJson,actionResponseForJson,owner) {
    //base init
    hax.core.EventManager.init.call(this);
    hax.core.ContextHolder.init.call(this);
    hax.core.Owner.init.call(this);
    hax.core.RootHolder.init.call(this);

    if(owner === undefined) owner = null;
    this.owner = owner;

    var inputArgType = hax.core.util.getObjectType(nameOrJson);

    if(inputArgType === "String") {
        this.name = nameOrJson;
        this.rootFolder = new hax.core.Folder(nameOrJson,this);
    }
    else {
        this.loadFromJson(nameOrJson,actionResponseForJson);
    }
}

//add components to this class
hax.core.util.mixin(hax.core.Workspace,hax.core.EventManager);
hax.core.util.mixin(hax.core.Workspace,hax.core.ContextHolder);
hax.core.util.mixin(hax.core.Workspace,hax.core.Owner);
hax.core.util.mixin(hax.core.Workspace,hax.core.RootHolder);

/** this method gets the workspace name. */
hax.core.Workspace.prototype.getName = function() {
    return this.name;
}

/** this method gets the root package for the workspace. */
hax.core.Workspace.prototype.getRoot = function() {
    return this.rootFolder;
}

/** This method sets the root object - implemented from RootHolder.  */
hax.core.Workspace.prototype.setRoot = function(child) {
    this.rootFolder = child;
}

/** This allows for a workspace to have a parent. For a normal workspace this should be null.
 * This is used for finding variables in scope. */
hax.core.Workspace.prototype.getOwner = function() {
    return this.owner;
}

/** This method updates the dependencies of any children in the workspace. */
hax.core.Workspace.prototype.updateDependeciesForModelChange = function(recalculateList) {
    if(this.rootFolder) {
        this.rootFolder.updateDependeciesForModelChange(recalculateList);
    }
}

/** This method removes any data from this workspace on closing. */
hax.core.Workspace.prototype.close = function() {
}

//------------------------------
// Owner Methods
//------------------------------

/** this method is implemented for the Owner component/mixin. */
hax.core.Workspace.prototype.getWorkspace = function() {
   return this;
}

/** this method gets the hame the children inherit for the full name. */
hax.core.Workspace.prototype.getPossesionNameBase = function() {
    return this.name + ":";
}

//------------------------------
//ContextHolder methods
//------------------------------

/** This method retrieve creates the loaded context manager. */
hax.core.Workspace.prototype.createContextManager = function() {
    //set the context manager
    var contextManager = new hax.core.ContextManager(this);
    //global variables from window object
    var globalVarEntry = {};
    globalVarEntry.isLocal = false;
    globalVarEntry.data = __globals__;
    contextManager.addToContextList(globalVarEntry);

    return contextManager;
}

//==========================
//virtual workspace methods
//==========================

/** This method makes a virtual workspace that contains a copy of the give folder
 * as the root folder. Optionally the context manager may be set. */
hax.core.Workspace.createVirtualWorkpaceFromFolder = function(name,origRootFolder,ownerInWorkspace) {
	//create a workspace json from the root folder json
	var workspaceJson = {};
    workspaceJson.name = name;
    workspaceJson.fileType = hax.core.Workspace.SAVE_FILE_TYPE;
    workspaceJson.version = hax.core.Workspace.SAVE_FILE_VERSION;
    workspaceJson.data = origRootFolder.toJson();

    return new hax.core.Workspace(workspaceJson,null,ownerInWorkspace);
}

//============================
// Save Functions
//============================

/** This is the supported file type. */
hax.core.Workspace.SAVE_FILE_TYPE = "hax workspace";

/** This is the supported file version. */
hax.core.Workspace.SAVE_FILE_VERSION = 0.1;

hax.core.Workspace.prototype.toJson = function() {
    var json = {};
    json.name = this.name;
    json.fileType = hax.core.Workspace.SAVE_FILE_TYPE;
    json.version = hax.core.Workspace.SAVE_FILE_VERSION;

    //components
    json.data = this.rootFolder.toJson();

    return json;
}

/** This is loads data from the given json into this workspace.
 * @private */
hax.core.Workspace.prototype.loadFromJson = function(json,actionResponse) {
    var fileType = json.fileType;
	if(fileType !== hax.core.Workspace.SAVE_FILE_TYPE) {
		throw hax.core.util.createError("Bad file format.",false);
	}
    if(json.version !== hax.core.Workspace.SAVE_FILE_VERSION) {
        throw hax.core.util.createError("Incorrect file version.",false);
    }

    this.name = json.name;

    if(!actionResponse) actionResponse = new hax.core.ActionResponse();

    hax.core.createmember.createMember(this,json.data,actionResponse);

    return actionResponse;
}

//================================
// Member generator functions
//================================

hax.core.Workspace.memberGenerators = {};

/** This methods retrieves the member generator for the given type. */
hax.core.Workspace.getMemberGenerator = function(type) {
    return hax.core.Workspace.memberGenerators[type];
}

/** This method registers the member generator for a given named type. */
hax.core.Workspace.addMemberGenerator = function(generator) {
    hax.core.Workspace.memberGenerators[generator.type] = generator;
}<|endoftext|>


<commit_before>'use strict';

/**
 * @description Returns a processed OpenAPI type name to handle array of objects [OpenAPI Type]
 * @param {String} openapiType The type
 * @return {String} The true OpenAPI type name
 */
function getOpenapiTypeName(openapiType) {
  return openapiType.replace('[', '').replace(']', '');
}

/**
 * @description Generate anchor (to find documentation in the specification) for OpenAPI type (handle [OpenAPI Type])
 * @param {String} openapiType The type
 * @return {String} The anchor
 */
function getAnchorForType(openapiType) {
  var typeName = openapiType.replace(/ /g, '').replace('[', '').replace(']', '');
  return typeName.charAt(0).toLowerCase() + typeName.slice(1);
}

/**
 * @description Generate documentation URL for OpenAPI type (handle [OpenAPI Type]) or anchor
 * @param {String} openapiType The type
 * @param {String} anchor The anchor
 * @param {String} specificationUrl The specification URL
 * @return {String} The documentation URL
 */
function getDocumentationUrl(openapiType, anchor, specificationUrl) {
  var documentationUrl;
  if (anchor !== undefined) {
    documentationUrl = specificationUrl + anchor;
  }
  else if (openapiType !== null) {
    documentationUrl = specificationUrl + getAnchorForType(openapiType);
  }
  return documentationUrl;
}

var pRegEx = new RegExp('^
.*');

/**
 * @description Generate HTML for Markdown
 * @param {String} md The Mardown
 * @return {String} The HTML
 */
function getHTMLFromMD(md) {
  var html;
  if (md !== undefined && md !== null) {
    html = marked(md);
    //if (pRegEx.test(html)) {
      //html = html.substring(3, html.length - 5);
    //}
    //if (html.startsWith('
')) {
    //  html = html.substring(3, html.length - 5);
    //}

  }
  else {
    html = md;
  }
  return html;
}

/**
 * @description Does an OpenAPI type allows extension
 * @param {Object} openapiTypeDefinition The OpenAPI type definition
 * @return {Boolean} Allow extension or not
 */
function allowExtension(openapiTypeDefinition) {
  var result;
  if (openapiTypeDefinition.allowExtension === undefined) {
    result = false;
  }
  else {
    result = openapiTypeDefinition.allowExtension;
  }
  return result;
}

/**
 * @description Does a property allows reference
 * @param {Object} property The property definition
 * @return {Boolean} Allow reference or not
 */
function allowReference(property) {
  var result;
  if (property.allowReference === undefined) {
    result = false;
  }
  else {
    result = property.allowReference;
  }
  return result;
}

/**
 * @description Is an OpenAPI definition a fields group (artificial group of fields within an OpenAPI type)
 * @param {Object} openapiTypeDefinition The OpenAPI type definition
 * @return {Boolean} Is a fields group or not
 */
function isFieldsGroup(openapiDocumentation, type) {
  var openapiTypeName = getOpenapiTypeName(type);
  var definition = openapiDocumentation[openapiTypeName];
  var result;
  if (definition === undefined || definition.fieldsGroup === undefined) {
    result = false;
  }
  else {
    result = definition.fieldsGroup;
  }
  return result;
}

function isOpenapiType(openapiDocumentation, type) {
  var openapiTypeName = getOpenapiTypeName(type);
  var definition = openapiDocumentation[openapiTypeName];
  var result;
  if (definition === undefined) {
    result = false;
  }
  else if (isFieldsGroup(openapiDocumentation, type)) {
    result = false;
  }
  else {
    result = true;
  }
  return result;
}

function isAtomicField(openapiDocumentation, field) {
  var result;
  if (field.type === undefined) {
    result = false;
  }
  else {
    var openapiTypeName = getOpenapiTypeName(field.type);
    var definition = openapiDocumentation[openapiTypeName];
    if (definition === undefined) {
      result = true;
    }
    else {
      result = false;
    }
  }
  return result;
}

function isArray(type) {
  return type.indexOf('[') >= 0;
}

function getFields(typeDefinition, openapiDocumentation) {
  var result = [];
  for (var i = 0; i < typeDefinition.fields.length; i++) {
    var field = typeDefinition.fields[i];
    if (isFieldsGroup(openapiDocumentation, field.type)) {
      var fieldsGroupDefinition = openapiDocumentation[field.type];
      result = result.concat(
        getFields(fieldsGroupDefinition, openapiDocumentation));
    }
    else {
      result.push(field);
    }
  }
  return result;
}

function getNewProperties(type, openapiDocumentation) {
  var result = [];
  var fields = getFields(type, openapiDocumentation);
  for (var i = 0; i < fields.length; i++) {
    var property = fields[i];
    if (property.changelog && property.changelog.isNew) {
      result.push({
        name: property.name,
        description: getHTMLFromMD(property.description)
      });
    }
  }
  return result;
}

function getModifiedProperties(type, openapiDocumentation) {
  var result = [];
  var fields = getFields(type, openapiDocumentation);
  for (var i = 0; i < fields.length; i++) {
    var property = fields[i];
    if (property.changelog && property.changelog.isModified) {
      result.push({
        name: property.name,
        description: getHTMLFromMD(property.changelog.details)
      });
    }
  }
  return result;
}

function getDeletedProperties(type, specificationUrl) {
  var result = [];
  if (type.changelog !== undefined && type.changelog.deletedProperties) {
    result = type.changelog.deletedProperties;
    for (var i = 0; i < result.length; i++) {
      if (result[i].see !== undefined) {
        result[i].documentationUrl = getDocumentationUrl(result[i].see, undefined, specificationUrl);
      }
    }
  }
  return result;
}

var mdUrls = {
  gfm: 'https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet',
  commonmark: 'http://commonmark.org/help/'
};
function getMd(field) {
  var md;
  if (field.md) {
    md = {
      syntax: field.md,
      url: mdUrls[field.md.toLowerCase()]
    };
  }
  return md;
}

function buildNodeFromOpenapiType(openapiDocumentation,
                                  openapiType,
                                  specificationUrl,
                                  parentNode,
                                  withChildren,
                                  allowReference) {
  var openapiTypeName = getOpenapiTypeName(openapiType);
  var definition = openapiDocumentation[openapiTypeName];
  var node = {
    name: definition.name,
    type: openapiTypeName,
    definition: definition,
    typeDocumentationUrl: getDocumentationUrl(
                            openapiTypeName,
                            definition.specificationAnchor,
                            specificationUrl),
    typeDescription: getHTMLFromMD(definition.description),
    typeChangelog: definition.changelog,
    allowExtension: allowExtension(definition),
    isFieldsGroup: isFieldsGroup(openapiDocumentation, openapiType),
    isOpenapiType: isOpenapiType(openapiDocumentation, openapiType),
    closedChildren: []
  };

  if (node.typeChangelog !== undefined &&
      node.typeChangelog.details !== undefined) {
    node.typeChangelog.details = getHTMLFromMD(node.typeChangelog.details);
  }

  var newProperties = getNewProperties(definition, openapiDocumentation);
  if (newProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {newProperties: newProperties};
    }
    else {
      node.typeChangelog.newProperties = newProperties;
    }
  }

  var modifiedProperties = getModifiedProperties(definition, openapiDocumentation);
  if (modifiedProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {modifiedProperties: modifiedProperties};
    }
    else {
      node.typeChangelog.modifiedProperties = modifiedProperties;
    }
  }

  var deletedProperties = getDeletedProperties(definition, specificationUrl);
  if (deletedProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {deletedProperties: deletedProperties};
    }
    else {
      node.typeChangelog.deletedProperties = deletedProperties;
    }
  }

  if (withChildren) {
    for (var index = 0; index < definition.fields.length; index++) {
      node.closedChildren.push(
        buildNodeFromField(
          openapiDocumentation,
          definition.fields[index],
          specificationUrl,
          node));
    }
    if (node.allowExtension) {
      var extensionNode = buildNodeFromField(
          openapiDocumentation,
          openapiDocumentation['Specification Extensions'],
          specificationUrl);
      extensionNode.isTechnical = true;
      node.closedChildren.push(extensionNode);
    }
    if (allowReference) {
      var referenceNode = buildNodeFromField(
          openapiDocumentation,
          openapiDocumentation['Reference Object'],
          specificationUrl);
      referenceNode.isTechnical = true;
      node.closedChildren.push(referenceNode);
    }
  }

  return node;
}

function buildNodeFromField(openapiDocumentation, field, specificationUrl, parentNode) {
  var node;
  if (!isAtomicField(openapiDocumentation, field)) {
    var withChildren;
    if (field.noFollow === true) {
      withChildren = false;
    }
    else {
      withChildren = true;
    }
    node = buildNodeFromOpenapiType(
            openapiDocumentation,
            field.type,
            specificationUrl,
            parentNode,
            withChildren,
            allowReference(field));
  }
  else {
    node = {
      type: field.type
    };
  }
  node.name = field.name;
  node.description = getHTMLFromMD(field.description);
  node.changelog = field.changelog;
  if (field.additionalType !== undefined) {
    node.additionalType = field.additionalType;
  }
  if (node.changelog !== undefined &&
      node.changelog.details !== undefined) {
    node.changelog.details = getHTMLFromMD(node.changelog.details);
  }
  if (parentNode) {
    node.parentChangelog = parentNode.changelog;
  }
  node.isArray = isArray(field.type);
  node.allowReference = allowReference(field);
  node.values = field.values;

  var md = getMd(field);
  if (md) {
    node.md = md;
  }

  if (field.required) {
    node.required = true;
  }
  else {
    node.required = false;
  }
  return node;
}

function buildTree(openapiDocumentation, root, specificationUrl) {
  var rootNode = buildNodeFromOpenapiType(
    openapiDocumentation, root, specificationUrl, null, true);
  // var rootNode = buildNodeFromOpenapiType(
  // openapiDocumentation, 'Paths Object', specificationUrl, null, true);
  return rootNode;
}
<commit_msg>Add target blank to links when transforming md to html<commit_after>'use strict';

/**
 * @description Returns a processed OpenAPI type name to handle array of objects [OpenAPI Type]
 * @param {String} openapiType The type
 * @return {String} The true OpenAPI type name
 */
function getOpenapiTypeName(openapiType) {
  return openapiType.replace('[', '').replace(']', '');
}

/**
 * @description Generate anchor (to find documentation in the specification) for OpenAPI type (handle [OpenAPI Type])
 * @param {String} openapiType The type
 * @return {String} The anchor
 */
function getAnchorForType(openapiType) {
  var typeName = openapiType.replace(/ /g, '').replace('[', '').replace(']', '');
  return typeName.charAt(0).toLowerCase() + typeName.slice(1);
}

/**
 * @description Generate documentation URL for OpenAPI type (handle [OpenAPI Type]) or anchor
 * @param {String} openapiType The type
 * @param {String} anchor The anchor
 * @param {String} specificationUrl The specification URL
 * @return {String} The documentation URL
 */
function getDocumentationUrl(openapiType, anchor, specificationUrl) {
  var documentationUrl;
  if (anchor !== undefined) {
    documentationUrl = specificationUrl + anchor;
  }
  else if (openapiType !== null) {
    documentationUrl = specificationUrl + getAnchorForType(openapiType);
  }
  return documentationUrl;
}

/**
 * @description Add target="_blank" to all links in html
 * @param {String} html
 * @returns {String} Modified html
 */
function addTargetBlankToURL(html) {
  var result = html;
  result = result.replace(/<a href=/g, '<a target="_blank" href=');
  return result;
}

/**
 * @description Generate HTML for Markdown
 * @param {String} md The Mardown
 * @return {String} The HTML
 */
function getHTMLFromMD(md) {
  var html;
  if (md !== undefined && md !== null) {
    html = marked(md);
    html = addTargetBlankToURL(html)
  }
  else {
    html = md;
  }
  return html;
}

/**
 * @description Does an OpenAPI type allows extension
 * @param {Object} openapiTypeDefinition The OpenAPI type definition
 * @return {Boolean} Allow extension or not
 */
function allowExtension(openapiTypeDefinition) {
  var result;
  if (openapiTypeDefinition.allowExtension === undefined) {
    result = false;
  }
  else {
    result = openapiTypeDefinition.allowExtension;
  }
  return result;
}

/**
 * @description Does a property allows reference
 * @param {Object} property The property definition
 * @return {Boolean} Allow reference or not
 */
function allowReference(property) {
  var result;
  if (property.allowReference === undefined) {
    result = false;
  }
  else {
    result = property.allowReference;
  }
  return result;
}

/**
 * @description Is an OpenAPI definition a fields group (artificial group of fields within an OpenAPI type)
 * @param {Object} openapiTypeDefinition The OpenAPI type definition
 * @return {Boolean} Is a fields group or not
 */
function isFieldsGroup(openapiDocumentation, type) {
  var openapiTypeName = getOpenapiTypeName(type);
  var definition = openapiDocumentation[openapiTypeName];
  var result;
  if (definition === undefined || definition.fieldsGroup === undefined) {
    result = false;
  }
  else {
    result = definition.fieldsGroup;
  }
  return result;
}

function isOpenapiType(openapiDocumentation, type) {
  var openapiTypeName = getOpenapiTypeName(type);
  var definition = openapiDocumentation[openapiTypeName];
  var result;
  if (definition === undefined) {
    result = false;
  }
  else if (isFieldsGroup(openapiDocumentation, type)) {
    result = false;
  }
  else {
    result = true;
  }
  return result;
}

function isAtomicField(openapiDocumentation, field) {
  var result;
  if (field.type === undefined) {
    result = false;
  }
  else {
    var openapiTypeName = getOpenapiTypeName(field.type);
    var definition = openapiDocumentation[openapiTypeName];
    if (definition === undefined) {
      result = true;
    }
    else {
      result = false;
    }
  }
  return result;
}

function isArray(type) {
  return type.indexOf('[') >= 0;
}

function getFields(typeDefinition, openapiDocumentation) {
  var result = [];
  for (var i = 0; i < typeDefinition.fields.length; i++) {
    var field = typeDefinition.fields[i];
    if (isFieldsGroup(openapiDocumentation, field.type)) {
      var fieldsGroupDefinition = openapiDocumentation[field.type];
      result = result.concat(
        getFields(fieldsGroupDefinition, openapiDocumentation));
    }
    else {
      result.push(field);
    }
  }
  return result;
}

function getNewProperties(type, openapiDocumentation) {
  var result = [];
  var fields = getFields(type, openapiDocumentation);
  for (var i = 0; i < fields.length; i++) {
    var property = fields[i];
    if (property.changelog && property.changelog.isNew) {
      result.push({
        name: property.name,
        description: getHTMLFromMD(property.description)
      });
    }
  }
  return result;
}

function getModifiedProperties(type, openapiDocumentation) {
  var result = [];
  var fields = getFields(type, openapiDocumentation);
  for (var i = 0; i < fields.length; i++) {
    var property = fields[i];
    if (property.changelog && property.changelog.isModified) {
      result.push({
        name: property.name,
        description: getHTMLFromMD(property.changelog.details)
      });
    }
  }
  return result;
}

function getDeletedProperties(type, specificationUrl) {
  var result = [];
  if (type.changelog !== undefined && type.changelog.deletedProperties) {
    result = type.changelog.deletedProperties;
    for (var i = 0; i < result.length; i++) {
      if (result[i].see !== undefined) {
        result[i].documentationUrl = getDocumentationUrl(result[i].see, undefined, specificationUrl);
      }
    }
  }
  return result;
}

var mdUrls = {
  gfm: 'https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet',
  commonmark: 'http://commonmark.org/help/'
};
function getMd(field) {
  var md;
  if (field.md) {
    md = {
      syntax: field.md,
      url: mdUrls[field.md.toLowerCase()]
    };
  }
  return md;
}

function buildNodeFromOpenapiType(openapiDocumentation,
                                  openapiType,
                                  specificationUrl,
                                  parentNode,
                                  withChildren,
                                  allowReference) {
  var openapiTypeName = getOpenapiTypeName(openapiType);
  var definition = openapiDocumentation[openapiTypeName];
  var node = {
    name: definition.name,
    type: openapiTypeName,
    definition: definition,
    typeDocumentationUrl: getDocumentationUrl(
                            openapiTypeName,
                            definition.specificationAnchor,
                            specificationUrl),
    typeDescription: getHTMLFromMD(definition.description),
    typeChangelog: definition.changelog,
    allowExtension: allowExtension(definition),
    isFieldsGroup: isFieldsGroup(openapiDocumentation, openapiType),
    isOpenapiType: isOpenapiType(openapiDocumentation, openapiType),
    closedChildren: []
  };

  if (node.typeChangelog !== undefined &&
      node.typeChangelog.details !== undefined) {
    node.typeChangelog.details = getHTMLFromMD(node.typeChangelog.details);
  }

  var newProperties = getNewProperties(definition, openapiDocumentation);
  if (newProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {newProperties: newProperties};
    }
    else {
      node.typeChangelog.newProperties = newProperties;
    }
  }

  var modifiedProperties = getModifiedProperties(definition, openapiDocumentation);
  if (modifiedProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {modifiedProperties: modifiedProperties};
    }
    else {
      node.typeChangelog.modifiedProperties = modifiedProperties;
    }
  }

  var deletedProperties = getDeletedProperties(definition, specificationUrl);
  if (deletedProperties.length > 0) {
    if (node.typeChangelog === undefined) {
      node.typeChangelog = {deletedProperties: deletedProperties};
    }
    else {
      node.typeChangelog.deletedProperties = deletedProperties;
    }
  }

  if (withChildren) {
    for (var index = 0; index < definition.fields.length; index++) {
      node.closedChildren.push(
        buildNodeFromField(
          openapiDocumentation,
          definition.fields[index],
          specificationUrl,
          node));
    }
    if (node.allowExtension) {
      var extensionNode = buildNodeFromField(
          openapiDocumentation,
          openapiDocumentation['Specification Extensions'],
          specificationUrl);
      extensionNode.isTechnical = true;
      node.closedChildren.push(extensionNode);
    }
    if (allowReference) {
      var referenceNode = buildNodeFromField(
          openapiDocumentation,
          openapiDocumentation['Reference Object'],
          specificationUrl);
      referenceNode.isTechnical = true;
      node.closedChildren.push(referenceNode);
    }
  }

  return node;
}

function buildNodeFromField(openapiDocumentation, field, specificationUrl, parentNode) {
  var node;
  if (!isAtomicField(openapiDocumentation, field)) {
    var withChildren;
    if (field.noFollow === true) {
      withChildren = false;
    }
    else {
      withChildren = true;
    }
    node = buildNodeFromOpenapiType(
            openapiDocumentation,
            field.type,
            specificationUrl,
            parentNode,
            withChildren,
            allowReference(field));
  }
  else {
    node = {
      type: field.type
    };
  }
  node.name = field.name;
  node.description = getHTMLFromMD(field.description);
  node.changelog = field.changelog;
  if (field.additionalType !== undefined) {
    node.additionalType = field.additionalType;
  }
  if (node.changelog !== undefined &&
      node.changelog.details !== undefined) {
    node.changelog.details = getHTMLFromMD(node.changelog.details);
  }
  if (parentNode) {
    node.parentChangelog = parentNode.changelog;
  }
  node.isArray = isArray(field.type);
  node.allowReference = allowReference(field);
  node.values = field.values;

  var md = getMd(field);
  if (md) {
    node.md = md;
  }

  if (field.required) {
    node.required = true;
  }
  else {
    node.required = false;
  }
  return node;
}

function buildTree(openapiDocumentation, root, specificationUrl) {
  var rootNode = buildNodeFromOpenapiType(
    openapiDocumentation, root, specificationUrl, null, true);
  // var rootNode = buildNodeFromOpenapiType(
  // openapiDocumentation, 'Paths Object', specificationUrl, null, true);
  return rootNode;
}
<|endoftext|>


<commit_before>const Constants = {
  DEFAULT_STATE: {
    request: {
      requestType: "",
      isFetching: false
    },
    flash: {
      flashType: "",
      message: ""
    },
    session: {
      signedIn: false,
      user: {}
    },
    sites: {
      siteList: []
    }
  },
  ACTIONS: {
    REQUEST_START:            "REQUEST_START",
    REQUEST_END:              "REQUEST_END",
    FLASH_SUCCESS:            "FLASH_SUCCESS",
    FLASH_ERROR:              "FLASH_ERROR",
    FLASH_CLEAR:              "FLASH_CLEAR",
    NEW_SESSION_SUCCESS:      "NEW_SESSION_SUCCESS",
    NEW_SESSION_FAILURE:      "NEW_SESSION_FAILURE",
    DESTROY_SESSION_SUCCESS:  "DESTROY_SESSION_SUCCESS",
    DESTROY_SESSION_FAILURE:  "DESTROY_SESSION_FAILURE",
    NEW_SITE_SUCCESS:         "NEW_SITE_SUCCESS",
    NEW_SITE_FAILURE:         "NEW_SITE_FAILURE",
    GET_SITES_SUCCESS:        "GET_SITES_SUCCESS",
    GET_SITES_FAILURE:        "GET_SITES_FAILURE"
  },
  ROUTES: {
    SESSION:      "/api/v1/sessions",
    CURRENT_USER: "/api/v1/current_user",
    SITES:        "/api/v1/sites"
  },
  PAGES: {
    SIGN_IN:  "/sign_in",
    SITES:    "/sites"
  }
};

export default Constants;
<commit_msg>add routing key to default store state<commit_after>const Constants = {
  DEFAULT_STATE: {
    request: {
      requestType: "",
      isFetching: false
    },
    flash: {
      flashType: "",
      message: ""
    },
    session: {
      signedIn: false,
      user: {}
    },
    sites: {
      siteList: []
    },
    routing: {}
  },
  ACTIONS: {
    REQUEST_START:            "REQUEST_START",
    REQUEST_END:              "REQUEST_END",
    FLASH_SUCCESS:            "FLASH_SUCCESS",
    FLASH_ERROR:              "FLASH_ERROR",
    FLASH_CLEAR:              "FLASH_CLEAR",
    NEW_SESSION_SUCCESS:      "NEW_SESSION_SUCCESS",
    NEW_SESSION_FAILURE:      "NEW_SESSION_FAILURE",
    DESTROY_SESSION_SUCCESS:  "DESTROY_SESSION_SUCCESS",
    DESTROY_SESSION_FAILURE:  "DESTROY_SESSION_FAILURE",
    NEW_SITE_SUCCESS:         "NEW_SITE_SUCCESS",
    NEW_SITE_FAILURE:         "NEW_SITE_FAILURE",
    GET_SITES_SUCCESS:        "GET_SITES_SUCCESS",
    GET_SITES_FAILURE:        "GET_SITES_FAILURE"
  },
  ROUTES: {
    SESSION:      "/api/v1/sessions",
    CURRENT_USER: "/api/v1/current_user",
    SITES:        "/api/v1/sites"
  },
  PAGES: {
    SIGN_IN:  "/sign_in",
    SITES:    "/sites"
  }
};

export default Constants;
<|endoftext|>