<commit_before>// window.toggleTooltip = function (e) {
jQuery.fn.toggleTooltip = function (e) {
  var target = $(e.target);

  // dando problema em na hora de reconhecer o params, pois está reconhecendo como Function

  Singleton.saveState(target, 'handler');
  toggle();
}

// usar sintaxe de tabs para setar o tooltip
// window.closeAllTooltips = function (e) {
jQuery.fn.closeAllTooltips = function (e) {
  var target = $(e.target);

  if (!target.is(".tooltip-body") && target
    .children(".tooltip").length == 0) {
    alert('eee');
    closeAll();
  }

  // O próximo passo é testar se o evento é do mouse. Caso seja colocar um temporizador para desaparecer caso o ponteiro esteja fora do handler

  // $(document).click(function (e) {
  //   // interval(2);
  //   alert('eee');
  //   target = $(e.target)

  //   if (!target.is(".tooltip-body") && target
  //       .children(".tooltip").length == 0) {
  //     // é só multiplicar por mil lá no método
  //     closeAll();
  //   }

  });

}

var
  toggle = function () {
    var
      handler = Singleton.recover 'handler',
      // acho que é nessa linha que está dando ruim
      tooltip = handler.find(".tooltip");

    // {folowMouse: true}

    // mudar
    if (tooltip.visible()) {
      hide();
    }
    else {
      show();
    }
  },

  // dar a oportunidade de informar as classes para o efeito
  closeAll = function () {
    var tooltips = $(".tooltip");

    tooltips.removeClass("transition-in");
  },

  hide = function () {
    var
      handler = Singleton.recover('handler'),
      tooltip = handler.find(".tooltip");

    // antes de remover, ou mesmo inserir um classe, pegar os ms usado como parâmetro no transition e meter no interval
    tooltip.removeClass("transition-in");
  },

  show = function () {
    var
      handler = Singleton.recover('handler'),
      tooltip = handler.find(".tooltip");

    tooltip.addClass "transition-in"
  };
<commit_msg>ajusta sintaxe de tooltip<commit_after>//= require jquery

"use strict";

var
    jQuery;

(function ($) {

  var
    toggle = function () {
      var
        handler = Singleton.recover('handler'),
        // acho que é nessa linha que está dando ruim
        tooltip = handler.find(".tooltip");

      // {folowMouse: true}

      // mudar
      if (tooltip.visible()) {
        hide();
      }
      else {
        show();
      }
    },

    // dar a oportunidade de informar as classes para o efeito
    closeAll = function () {
      var tooltips = $(".tooltip");

      tooltips.removeClass("transition-in");
    },

    hide = function () {
      var
        handler = Singleton.recover('handler'),
        tooltip = handler.find(".tooltip");

      // antes de remover, ou mesmo inserir um classe, pegar os ms usado como parâmetro no transition e meter no interval
      tooltip.removeClass("transition-in");
    },

    show = function () {
      var
        handler = Singleton.recover('handler'),
        tooltip = handler.find(".tooltip");

      tooltip.addClass("transition-in");
    };

  // window.toggleTooltip = function (e) {
  $.fn.toggleTooltip = function (e) {
    var target = $(e.target);

    // dando problema em na hora de reconhecer o params, pois está reconhecendo como Function

    Singleton.saveState(target, 'handler');
    toggle();
  };

  // usar sintaxe de tabs para setar o tooltip
  // window.closeAllTooltips = function (e) {
  // O próximo passo é testar se o evento é do mouse. Caso seja colocar um temporizador para desaparecer caso o ponteiro esteja fora do handler
  $.fn.closeAllTooltips = function (e) {
    var target = $(e.target);

    if (target.children(".esphinx-ui-tooltip").length == 0 && !target
        .is(".esphinx-ui-tooltip-body")) {
      closeAll();
    }

  };

})(jQuery);
<|endoftext|>


<commit_before>(function () {
    "use strict";
    describe("Tests for Home controllers:", function () {
        var controller, scope, root, data, $state, $ctrl, $httpBackend, serverUrl;

        beforeEach(function () {
            module("mfl.home");
            module("mflAppConfig");
            module("templates-app");
            module("templates-common");
            inject(["$rootScope", "$controller","$state","$httpBackend","SERVER_URL",
                function ($rootScope, $controller, _$state, _$httpBackend, SERVER_URL) {
                    root = $rootScope;
                    $httpBackend = _$httpBackend;
                    serverUrl = SERVER_URL;
                    $state = _$state;
                    $ctrl = $controller;
                    scope = root.$new();
                    data = {
                        $scope: scope,
                        $state: $state
                    };
                    controller = function (cntrl) {
                        return $controller(cntrl, data);
                    };
                }]);
        });
        it("it should have `mfl.home.controllers.home` defined", function () {
            var ctrl = controller("mfl.home.controllers.home");
            expect(ctrl).toBeDefined();
        });

        it("should search facilites on `mfl.home.controllers.home`", function(){
            controller("mfl.home.controllers.home");
            scope.search("testing");
            expect(scope.loader).toBeTruthy();
        });

        it("should test auto-complete on `mfl.home.controllers.home`", function(){
            spyOn(_, "debounce");
            controller("mfl.home.controllers.home");
            scope.typeaheadFacilities();
            expect(_.debounce).toHaveBeenCalled();
        });

        it("it should have `mfl.home.controllers.header` defined", function () {
            var ctrl = controller("mfl.home.controllers.header");
            expect(ctrl).toBeDefined();
        });

        it("shuld have `mfl.home.controllers.facility_details`defined list facilities",function (){
            $httpBackend.expectGET(serverUrl+"api/facilities/facilities/10/")
            .respond(200, {results: "ok"});
            var cont = $ctrl(
                "mfl.home.controllers.facility_details",
                {
                    $scope: scope,
                    $state: {
                        params: {
                            fac_id: 10
                        }
                    }
                }
            );

            expect(cont).toBeDefined();
            $httpBackend.flush();
            expect(scope.oneFacility).toEqual({results: "ok"});
        });

        it("`mfl.home.controllers.facility_details`, list facilities: error",function (){
            $httpBackend.expectGET(serverUrl+"api/facilities/facilities/10/")
            .respond(500, {error: "error"});
            $ctrl(
                "mfl.home.controllers.facility_details",
                {
                    $scope: scope,
                    $state: {
                        params: {
                            fac_id: 10
                        }
                    }
                }
            );
            $httpBackend.flush();
            expect(scope.alert).toEqual("error");
        });

    });
})();
<commit_msg>Testing fix for search in homepage<commit_after>(function () {
    "use strict";
    describe("Tests for Home controllers:", function () {
        var controller, scope, root, data, $state, $ctrl, $httpBackend, serverUrl;

        beforeEach(function () {
            module("mfl.home");
            module("mflAppConfig");
            module("templates-app");
            module("templates-common");
            inject(["$rootScope", "$controller","$state","$httpBackend","SERVER_URL",
                function ($rootScope, $controller, _$state, _$httpBackend, SERVER_URL) {
                    root = $rootScope;
                    $httpBackend = _$httpBackend;
                    serverUrl = SERVER_URL;
                    $state = _$state;
                    $ctrl = $controller;
                    scope = root.$new();
                    data = {
                        $scope: scope,
                        $state: $state
                    };
                    controller = function (cntrl) {
                        return $controller(cntrl, data);
                    };
                }]);
        });
        it("it should have `mfl.home.controllers.home` defined", function () {
            var ctrl = controller("mfl.home.controllers.home");
            expect(ctrl).toBeDefined();
        });

        it("should search facilites on `mfl.home.controllers.home`", function(){
            spyOn($state, "go");
            controller("mfl.home.controllers.home");
            scope.search("testing");
            expect(scope.loader).toBeTruthy();
        });

        it("should test auto-complete on `mfl.home.controllers.home`", function(){
            spyOn(_, "debounce");
            controller("mfl.home.controllers.home");
            scope.typeaheadFacilities();
            expect(_.debounce).toHaveBeenCalled();
        });

        it("it should have `mfl.home.controllers.header` defined", function () {
            var ctrl = controller("mfl.home.controllers.header");
            expect(ctrl).toBeDefined();
        });

        it("shuld have `mfl.home.controllers.facility_details`defined list facilities",function (){
            $httpBackend.expectGET(serverUrl+"api/facilities/facilities/10/")
            .respond(200, {results: "ok"});
            var cont = $ctrl(
                "mfl.home.controllers.facility_details",
                {
                    $scope: scope,
                    $state: {
                        params: {
                            fac_id: 10
                        }
                    }
                }
            );

            expect(cont).toBeDefined();
            $httpBackend.flush();
            expect(scope.oneFacility).toEqual({results: "ok"});
        });

        it("`mfl.home.controllers.facility_details`, list facilities: error",function (){
            $httpBackend.expectGET(serverUrl+"api/facilities/facilities/10/")
            .respond(500, {error: "error"});
            $ctrl(
                "mfl.home.controllers.facility_details",
                {
                    $scope: scope,
                    $state: {
                        params: {
                            fac_id: 10
                        }
                    }
                }
            );
            $httpBackend.flush();
            expect(scope.alert).toEqual("error");
        });

    });
})();
<|endoftext|>


<commit_before>/**
 * @package assets
 */

(function($) {

	/**
	 * Create collapsible elements.
	 *
	 * @name $.symphonyCollapsible
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.items='.instance'] Selector to find collapsible items within the container
	 * @param {String} [options.handles='.header:first'] Selector to find clickable handles to trigger interaction
	 * @param {String} [options.content='.content'] Selector to find hideable content area
	 * @param {String} [options.save_state=true] Stores states of instances using local storage
	 * @param {String} [options.storage='symphony.collapsible.area.page.id'] Namespace used for local storage
	 *
	 * @example

			var collapsible = $('#duplicator').symphonyCollapsible({
				items:		'.instance',
				handles:	'.header span'
			});
			collapsible.collapseAll();
	 */
	$.fn.symphonyCollapsible = function(options) {
		var objects = this,
			settings = {
				items:				'.instance',
				handles:			'.header:first',
				content:			'.content',
				ignore:				'.ignore',
				save_state:			true,
				storage:			'symphony.collapsible.' + window.location.href.split(Symphony.Context.get('root') + '/')[1].replace(/\/(edit|new|created|saved)/g, '').replace(/\//g, '.')
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		objects.each(function collapsible(index) {
			var object = $(this),
				storage = settings.storage + index + '.collapsed';

		/*---------------------------------------------------------------------
			Events
		---------------------------------------------------------------------*/

			// Collapse item
			object.on('collapse.collapsible', settings.items, function collapse(event, duration) {
				var item = $(this),
					heightMin = item.data('heightMin') || item.find(settings.handles).outerHeight() - 1;

				// Check duration
				if(duration !== 0) {
					item.addClass('js-animate');
				}

				// Collapse item
				item.trigger('collapsestart.collapsible')
					.addClass('collapsed')
					.css('max-height', heightMin);
			});

			// Collapse all items
			object.on('collapseall.collapsible', function collapseAll(event) {
				var items = object.find(settings.items),
					visibles = Symphony.Utilities.inSight(items),
					invisibles = visibles.nextAll();

				invisibles.each(function() {
					var item = $(this);
					item.css('max-height', item.data('heightMin'));
				});
				visibles.trigger('collapse.collapsible');
				invisibles.trigger('collapsestop.collapsible');
			});

			// Expand item
			object.on('expand.collapsible', settings.items, function expand(event, duration) {
				var item = $(this),
					heightMax = item.data('heightMax') || item[0].scrollHeight;

				// Check duration
				if(duration !== 0) {
					item.addClass('js-animate');
				}

				// Collapse item
				item.trigger('expandstart.collapsible')
					.removeClass('collapsed')
					.css('max-height', heightMax);
			});

			// Expand all items
			object.on('expandall.collapsible', function expandAll(event) {
				var items = object.find(settings.items),
					firsts = items.filter('.collapsed:lt(2)');

				firsts.trigger('expand.collapsible');
				setTimeout(function() {
					items.not(firsts).each(function() {
						var item = $(this);
						item.css('max-height', item.data('heightMax'));
					}).trigger('expandstop.collapsible');
				}, 250);
			});

			// Finish animations
			object.on('webkitTransitionEnd transitionend oTransitionEnd otransitionend MSTransitionEnd', settings.items, function finish(event) {
				var item = $(this).removeClass('js-animate');

				// Trigger events
				if(item.is('.collapsed')) {
					item.trigger('collapsestop.collapsible');
				}
				else {
					item.trigger('expandstop.collapsible');
				}
			});

			// Toggle single item
			object.on('click.collapsible', settings.handles, function toggle(event) {
				var handle = $(this),
					item = handle.parents(settings.items);

				if(!handle.is(settings.ignore) && !$(event.target).is(settings.ignore) && !item.is('.locked')) {

					// Expand
					if(item.is('.collapsed')) {
						item.trigger('expand.collapsible');
					}

					// Collapse
					else {
						item.trigger('collapse.collapsible');
					}
				}
			});

			// Toggle all
			object.on('dblclick.collapsible', settings.handles, function toogleAll(event) {
				var handle = $(this),
					item = handle.parents(settings.items),
					items = object.find(settings.items);

				if(!handle.is(settings.ignore) && !$(event.target).is(settings.ignore)) {

					// Expand all
					if(item.is('.collapsed')) {
						items.trigger('expand.collapsible');
					}

					// Collaps all
					else {
						items.trigger('collapse.collapsible');
					}
				}
			});

			// Save states
			object.on('collapsestop.collapsible expandstop.collapsible store.collapsible', settings.items, function saveState(event) {
				if(settings.save_state === true && Symphony.Support.localStorage === true) {
					var collapsed = object.find(settings.items).map(function(index) {
						if($(this).is('.collapsed')) {
							return index;
						};
					});

					// Put in a try/catch incase something goes wrong (no space, privileges etc)
					try {
						window.localStorage[storage] = collapsed.get().join(',');
					}
					catch(e) {
						window.onerror(e.message);
					}
				}
			});

			// Restore states
			object.on('restore.collapsible', function restoreState(event) {
				if(settings.save_state === true && Symphony.Support.localStorage === true && window.localStorage[storage]) {
					$.each(window.localStorage[storage].split(','), function(index, value) {
						var collapsed = object.find(settings.items).eq(value);
						if(collapsed.has('.invalid').length == 0) {
							collapsed.trigger('collapse.collapsible', [0]);
						}
					});
				}
			});

			// Refresh state storage
			object.on('orderstop.orderable', function refreshState(event) {
				object.find(settings.items).trigger('store.collapsible');
			});

		/*---------------------------------------------------------------------
			Initialisation
		---------------------------------------------------------------------*/

			// Prepare interface
			object.addClass('collapsible');

			// Restore states
			object.trigger('restore.collapsible');
			object.find(settings.items).each(function() {
				var item = $(this),
					min = item.find(settings.handles).outerHeight() - 1,
					max = item[0].scrollHeight;

				item.css('max-height', max);
				item.data('heightMin', min);
				item.data('heightMax', max);
			});
			object.trigger('restore.collapsible');
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(window.jQuery);
<commit_msg>Remove .collapsed class after expanding all items<commit_after>/**
 * @package assets
 */

(function($) {

	/**
	 * Create collapsible elements.
	 *
	 * @name $.symphonyCollapsible
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.items='.instance'] Selector to find collapsible items within the container
	 * @param {String} [options.handles='.header:first'] Selector to find clickable handles to trigger interaction
	 * @param {String} [options.content='.content'] Selector to find hideable content area
	 * @param {String} [options.save_state=true] Stores states of instances using local storage
	 * @param {String} [options.storage='symphony.collapsible.area.page.id'] Namespace used for local storage
	 *
	 * @example

			var collapsible = $('#duplicator').symphonyCollapsible({
				items:		'.instance',
				handles:	'.header span'
			});
			collapsible.collapseAll();
	 */
	$.fn.symphonyCollapsible = function(options) {
		var objects = this,
			settings = {
				items:				'.instance',
				handles:			'.header:first',
				content:			'.content',
				ignore:				'.ignore',
				save_state:			true,
				storage:			'symphony.collapsible.' + window.location.href.split(Symphony.Context.get('root') + '/')[1].replace(/\/(edit|new|created|saved)/g, '').replace(/\//g, '.')
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		objects.each(function collapsible(index) {
			var object = $(this),
				storage = settings.storage + index + '.collapsed';

		/*---------------------------------------------------------------------
			Events
		---------------------------------------------------------------------*/

			// Collapse item
			object.on('collapse.collapsible', settings.items, function collapse(event, duration) {
				var item = $(this),
					heightMin = item.data('heightMin') || item.find(settings.handles).outerHeight() - 1;

				// Check duration
				if(duration !== 0) {
					item.addClass('js-animate');
				}

				// Collapse item
				item.trigger('collapsestart.collapsible')
					.addClass('collapsed')
					.css('max-height', heightMin);
			});

			// Collapse all items
			object.on('collapseall.collapsible', function collapseAll(event) {
				var items = object.find(settings.items),
					visibles = Symphony.Utilities.inSight(items),
					invisibles = visibles.nextAll();

				invisibles.each(function() {
					var item = $(this);
					item.css('max-height', item.data('heightMin'));
				});
				visibles.trigger('collapse.collapsible');
				invisibles.trigger('collapsestop.collapsible');
			});

			// Expand item
			object.on('expand.collapsible', settings.items, function expand(event, duration) {
				var item = $(this),
					heightMax = item.data('heightMax') || item[0].scrollHeight;

				// Check duration
				if(duration !== 0) {
					item.addClass('js-animate');
				}

				// Collapse item
				item.trigger('expandstart.collapsible')
					.removeClass('collapsed')
					.css('max-height', heightMax);
			});

			// Expand all items
			object.on('expandall.collapsible', function expandAll(event) {
				var items = object.find(settings.items),
					firsts = items.filter('.collapsed:lt(2)');

				firsts.trigger('expand.collapsible');
				setTimeout(function() {
					items.not(firsts).each(function() {
						var item = $(this);
						item.css('max-height', item.data('heightMax'));
					}).removeClass('collapsed').trigger('expandstop.collapsible');
				}, 250);
			});

			// Finish animations
			object.on('webkitTransitionEnd transitionend oTransitionEnd otransitionend MSTransitionEnd', settings.items, function finish(event) {
				var item = $(this).removeClass('js-animate');

				// Trigger events
				if(item.is('.collapsed')) {
					item.trigger('collapsestop.collapsible');
				}
				else {
					item.trigger('expandstop.collapsible');
				}
			});

			// Toggle single item
			object.on('click.collapsible', settings.handles, function toggle(event) {
				var handle = $(this),
					item = handle.parents(settings.items);

				if(!handle.is(settings.ignore) && !$(event.target).is(settings.ignore) && !item.is('.locked')) {

					// Expand
					if(item.is('.collapsed')) {
						item.trigger('expand.collapsible');
					}

					// Collapse
					else {
						item.trigger('collapse.collapsible');
					}
				}
			});

			// Toggle all
			object.on('dblclick.collapsible', settings.handles, function toogleAll(event) {
				var handle = $(this),
					item = handle.parents(settings.items),
					items = object.find(settings.items);

				if(!handle.is(settings.ignore) && !$(event.target).is(settings.ignore)) {

					// Expand all
					if(item.is('.collapsed')) {
						items.trigger('expand.collapsible');
					}

					// Collaps all
					else {
						items.trigger('collapse.collapsible');
					}
				}
			});

			// Save states
			object.on('collapsestop.collapsible expandstop.collapsible store.collapsible', settings.items, function saveState(event) {
				if(settings.save_state === true && Symphony.Support.localStorage === true) {
					var collapsed = object.find(settings.items).map(function(index) {
						if($(this).is('.collapsed')) {
							return index;
						};
					});

					// Put in a try/catch incase something goes wrong (no space, privileges etc)
					try {
						window.localStorage[storage] = collapsed.get().join(',');
					}
					catch(e) {
						window.onerror(e.message);
					}
				}
			});

			// Restore states
			object.on('restore.collapsible', function restoreState(event) {
				if(settings.save_state === true && Symphony.Support.localStorage === true && window.localStorage[storage]) {
					$.each(window.localStorage[storage].split(','), function(index, value) {
						var collapsed = object.find(settings.items).eq(value);
						if(collapsed.has('.invalid').length == 0) {
							collapsed.trigger('collapse.collapsible', [0]);
						}
					});
				}
			});

			// Refresh state storage
			object.on('orderstop.orderable', function refreshState(event) {
				object.find(settings.items).trigger('store.collapsible');
			});

		/*---------------------------------------------------------------------
			Initialisation
		---------------------------------------------------------------------*/

			// Prepare interface
			object.addClass('collapsible');

			// Restore states
			object.trigger('restore.collapsible');
			object.find(settings.items).each(function() {
				var item = $(this),
					min = item.find(settings.handles).outerHeight() - 1,
					max = item[0].scrollHeight;

				item.css('max-height', max);
				item.data('heightMin', min);
				item.data('heightMax', max);
			});
			object.trigger('restore.collapsible');
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(window.jQuery);
<|endoftext|>


<commit_before>/*
 * ! ${copyright}
 */

// ------------------------------------------------------------------------------------------
// Utility class used mdc table and chart
// ------------------------------------------------------------------------------------------
sap.ui.define(['sap/ui/mdc/util/IdentifierUtil', 'sap/ui/mdc/enum/ConditionValidated', "sap/ui/mdc/condition/ConditionConverter", 'sap/ui/mdc/condition/FilterConverter', 'sap/base/Log', 'sap/base/util/merge'],
		function(IdentifierUtil, ConditionValidated, ConditionConverter, FilterConverter, Log, merge) {
	"use strict";

	/**
	 * Utility class used by mdc controls to create the filter statement
	 *
	 * @namespace
	 * @private
	 * @ui5-restricted sap.ui.mdc, sap.fe
	 * @since 1.80.0
	 * @alias sap.ui.mdc.util.FilterUtil
	 */
		var FilterUtil = {

				/**
				 * Returns a specific PropertyInfo object by a given name

				 *
				 * @param {array} aPropertiesMetadata - array with all the property metadata
				 * @param {string} sKey - name of the property
				 * @returns {object}  PropertyInfo object for a given name, or null
				 * @private
				 * @ui5-restricted sap.ui.mdc, sap.fe
				 */
				getPropertyByKey : function(aPropertiesMetadata, sKey) {
					var oPropertyInfo = null;

					aPropertiesMetadata.some(function(oProp) {
						if (IdentifierUtil.getPropertyPath(oProp) === sKey) {
							oPropertyInfo = oProp;
						}

						return oPropertyInfo != null;
					});

					if (!oPropertyInfo) {
						aPropertiesMetadata.some(function(oProp) {
							if (IdentifierUtil.getPropertyKey(oProp) === sKey) {
								oPropertyInfo = oProp;
							}

							return oPropertyInfo != null;
						});
					}

					return oPropertyInfo;
				},

				/**
				 * Returns internal conditions for a set of properties. Properties without a condition will be ignored.
				 * The resulting conditions are represented by the operation and by the values array.
				 * Note:
The operation information will be returned as they are contained in the internal conditions model.
				 * This has to be considered, in case custom operations are used.
				 *
				 * @param {sap.ui.mdc.FilterBar} oFilterBar instance of the filter bar
				 * @param {array} aPropertyNames list of property names to be considered
				 * @returns {map} mResultingConditions with property names as key and a list of internal conditions for each property
				 * @returns {array} mResultingConditions.["propertyName"] conditions addressed by the property name
				 * @returns {string} mResultingConditions.["propertyName"].operator operator for a single condition
				 * @returns {array} mResultingConditions.["propertyName"].values values for a single condition
				 * @private
				 * @ui5-restricted sap.ui.mdc, sap.fe
				 * @MDC_PUBLIC_CANDIDATE
				 */
				getConditionsMap : function(oFilterBar, aPropertyNames) {
					var aPropertyConditions, oPropertyCondition, mResultingConditions = {};

					if (!oFilterBar || !oFilterBar.isA("sap.ui.mdc.FilterBar")) {
						Log.error("instance of sap.ui.mdc.FilterBar expected");
						return mResultingConditions;
					}

					var mConditions = oFilterBar.getInternalConditions();
					for (var sPropertyName in mConditions) {
						if (aPropertyNames.indexOf(sPropertyName) >= 0) {
							aPropertyConditions = [];
							if (mConditions[sPropertyName]) {
								for (var i = 0; i < mConditions[sPropertyName].length; i++) {
									oPropertyCondition = {};
									oPropertyCondition.operator = mConditions[sPropertyName][i].operator;

									if ((oPropertyCondition.operator === "EQ") && (mConditions[sPropertyName][i].validated === ConditionValidated.Validated)) {
										oPropertyCondition.values = [mConditions[sPropertyName][i].values[0]];
									} else {
										oPropertyCondition.values = mConditions[sPropertyName][i].values;
									}

									aPropertyConditions.push(oPropertyCondition);
								}

								mResultingConditions[sPropertyName] = aPropertyConditions;
							}
						}
					}

					return mResultingConditions;
				},

				/**
				 * Creates the filter statements based on the externalize conditions.

				 *
				 * @param {sap.ui.mdc.Control|sap.ui.mdc.util.TypeUtil} vTypeProvider the MDC control instance or TypeUtil
				 * @param {map} mConditions - map with externalized conditions
				 * @param {array} aPropertiesMetadata - array with all the property metadata
				 * @param {array} aIgnoreProperties - an array of property names which should be not considered for filtering
				 * @returns {object} Object with filters
				 * @private
				 * @ui5-restricted sap.ui.mdc
				 */
				getFilterInfo: function(vTypeProvider, mConditions, aPropertiesMetadata, aIgnoreProperties) {

					var oFilterInfo = {};

					aIgnoreProperties = aIgnoreProperties ? aIgnoreProperties : [];

					var i, sFieldPath, mInternalFilterConditions = {}, oConditionInternal;
					var mFilterTypes = {};

					if (aPropertiesMetadata && aPropertiesMetadata.length > 0) {
						for (sFieldPath in mConditions) {
							if (aIgnoreProperties.indexOf(sFieldPath) < 0) {

								var oProperty = FilterUtil.getPropertyByKey(aPropertiesMetadata, sFieldPath);
								if (oProperty) {

									mFilterTypes[sFieldPath] = { type: oProperty.typeConfig.typeInstance, caseSensitive: oProperty.caseSensitive, baseType: oProperty.typeConfig.baseType };
									mInternalFilterConditions[sFieldPath] = [];

									//convert from externalized to model-specific value representation
									for (i = 0; i < mConditions[sFieldPath].length; i++) {
										oConditionInternal = merge({}, mConditions[sFieldPath][i]);
										mInternalFilterConditions[sFieldPath].push(ConditionConverter.toType(oConditionInternal, oProperty.typeConfig, vTypeProvider.getTypeUtil ? vTypeProvider.getTypeUtil() : vTypeProvider));
									}

								} else {
									Log.error("no such property: " + sFieldPath);
								}
							}
						}

						if (Object.keys(mInternalFilterConditions).length > 0) {
							// create filter statement
							oFilterInfo.filters = FilterConverter.createFilters(mInternalFilterConditions, mFilterTypes);
						}
					}

					return oFilterInfo;
				}

		};

		return FilterUtil;
});
<commit_msg>[INTERNAL] FilterUtil.js : giving a more precise log error<commit_after>/*
 * ! ${copyright}
 */

// ------------------------------------------------------------------------------------------
// Utility class used mdc table and chart
// ------------------------------------------------------------------------------------------
sap.ui.define(['sap/ui/mdc/util/IdentifierUtil', 'sap/ui/mdc/enum/ConditionValidated', "sap/ui/mdc/condition/ConditionConverter", 'sap/ui/mdc/condition/FilterConverter', 'sap/base/Log', 'sap/base/util/merge'],
		function(IdentifierUtil, ConditionValidated, ConditionConverter, FilterConverter, Log, merge) {
	"use strict";

	/**
	 * Utility class used by mdc controls to create the filter statement
	 *
	 * @namespace
	 * @private
	 * @ui5-restricted sap.ui.mdc, sap.fe
	 * @since 1.80.0
	 * @alias sap.ui.mdc.util.FilterUtil
	 */
		var FilterUtil = {

				/**
				 * Returns a specific PropertyInfo object by a given name

				 *
				 * @param {array} aPropertiesMetadata - array with all the property metadata
				 * @param {string} sKey - name of the property
				 * @returns {object}  PropertyInfo object for a given name, or null
				 * @private
				 * @ui5-restricted sap.ui.mdc, sap.fe
				 */
				getPropertyByKey : function(aPropertiesMetadata, sKey) {
					var oPropertyInfo = null;

					aPropertiesMetadata.some(function(oProp) {
						if (IdentifierUtil.getPropertyPath(oProp) === sKey) {
							oPropertyInfo = oProp;
						}

						return oPropertyInfo != null;
					});

					if (!oPropertyInfo) {
						aPropertiesMetadata.some(function(oProp) {
							if (IdentifierUtil.getPropertyKey(oProp) === sKey) {
								oPropertyInfo = oProp;
							}

							return oPropertyInfo != null;
						});
					}

					return oPropertyInfo;
				},

				/**
				 * Returns internal conditions for a set of properties. Properties without a condition will be ignored.
				 * The resulting conditions are represented by the operation and by the values array.
				 * Note:
The operation information will be returned as they are contained in the internal conditions model.
				 * This has to be considered, in case custom operations are used.
				 *
				 * @param {sap.ui.mdc.FilterBar} oFilterBar instance of the filter bar
				 * @param {array} aPropertyNames list of property names to be considered
				 * @returns {map} mResultingConditions with property names as key and a list of internal conditions for each property
				 * @returns {array} mResultingConditions.["propertyName"] conditions addressed by the property name
				 * @returns {string} mResultingConditions.["propertyName"].operator operator for a single condition
				 * @returns {array} mResultingConditions.["propertyName"].values values for a single condition
				 * @private
				 * @ui5-restricted sap.ui.mdc, sap.fe
				 * @MDC_PUBLIC_CANDIDATE
				 */
				getConditionsMap : function(oFilterBar, aPropertyNames) {
					var aPropertyConditions, oPropertyCondition, mResultingConditions = {};

					if (!oFilterBar || !oFilterBar.isA("sap.ui.mdc.FilterBar")) {
						Log.error("instance of sap.ui.mdc.FilterBar expected");
						return mResultingConditions;
					}

					var mConditions = oFilterBar.getInternalConditions();
					for (var sPropertyName in mConditions) {
						if (aPropertyNames.indexOf(sPropertyName) >= 0) {
							aPropertyConditions = [];
							if (mConditions[sPropertyName]) {
								for (var i = 0; i < mConditions[sPropertyName].length; i++) {
									oPropertyCondition = {};
									oPropertyCondition.operator = mConditions[sPropertyName][i].operator;

									if ((oPropertyCondition.operator === "EQ") && (mConditions[sPropertyName][i].validated === ConditionValidated.Validated)) {
										oPropertyCondition.values = [mConditions[sPropertyName][i].values[0]];
									} else {
										oPropertyCondition.values = mConditions[sPropertyName][i].values;
									}

									aPropertyConditions.push(oPropertyCondition);
								}

								mResultingConditions[sPropertyName] = aPropertyConditions;
							}
						}
					}

					return mResultingConditions;
				},

				/**
				 * Creates the filter statements based on the externalize conditions.

				 *
				 * @param {sap.ui.mdc.Control|sap.ui.mdc.util.TypeUtil} vTypeProvider the MDC control instance or TypeUtil
				 * @param {map} mConditions - map with externalized conditions
				 * @param {array} aPropertiesMetadata - array with all the property metadata
				 * @param {array} aIgnoreProperties - an array of property names which should be not considered for filtering
				 * @returns {object} Object with filters
				 * @private
				 * @ui5-restricted sap.ui.mdc
				 */
				getFilterInfo: function(vTypeProvider, mConditions, aPropertiesMetadata, aIgnoreProperties) {

					var oFilterInfo = {};

					aIgnoreProperties = aIgnoreProperties ? aIgnoreProperties : [];

					var i, sFieldPath, mInternalFilterConditions = {}, oConditionInternal;
					var mFilterTypes = {};

					if (aPropertiesMetadata && aPropertiesMetadata.length > 0) {
						for (sFieldPath in mConditions) {
							if (aIgnoreProperties.indexOf(sFieldPath) < 0) {

								var oProperty = FilterUtil.getPropertyByKey(aPropertiesMetadata, sFieldPath);
								if (oProperty) {

									mFilterTypes[sFieldPath] = { type: oProperty.typeConfig.typeInstance, caseSensitive: oProperty.caseSensitive, baseType: oProperty.typeConfig.baseType };
									mInternalFilterConditions[sFieldPath] = [];

									//convert from externalized to model-specific value representation
									for (i = 0; i < mConditions[sFieldPath].length; i++) {
										oConditionInternal = merge({}, mConditions[sFieldPath][i]);
										mInternalFilterConditions[sFieldPath].push(ConditionConverter.toType(oConditionInternal, oProperty.typeConfig, vTypeProvider.getTypeUtil ? vTypeProvider.getTypeUtil() : vTypeProvider));
									}

								} else {
									Log.error("sap.ui.mdc.util.FilterUitl.js :", "could not find propertyMetadata of : " + sFieldPath);
								}
							}
						}

						if (Object.keys(mInternalFilterConditions).length > 0) {
							// create filter statement
							oFilterInfo.filters = FilterConverter.createFilters(mInternalFilterConditions, mFilterTypes);
						}
					}

					return oFilterInfo;
				}

		};

		return FilterUtil;
});
<|endoftext|>


<commit_before>import BoundingSphere from "../../Core/BoundingSphere.js";
import Matrix4 from "../../Core/Matrix4.js";

var ModelMatrixUpdateStage = {};

ModelMatrixUpdateStage.update = function (runtimeNode, sceneGraph, frameState) {
  if (runtimeNode._transformDirty) {
    updateRuntimeNode(runtimeNode, sceneGraph);
    runtimeNode._transformDirty = false;
  }
};

/**
 * Recursively update runtime nodes.
 */
function updateRuntimeNode(runtimeNode, sceneGraph) {
  var i, j;

  // Update the DrawCommand's model matrix and bounding volume for each runtime primitive that belongs to this runtime node.
  for (i = 0; i < runtimeNode.runtimePrimitives.length; i++) {
    var runtimePrimitive = runtimeNode.runtimePrimitives[i];
    for (j = 0; j < runtimePrimitive.drawCommands.length; j++) {
      var drawCommand = runtimePrimitive.drawCommands[j];

      Matrix4.clone(runtimeNode.computedTransform, drawCommand.modelMatrix);

      BoundingSphere.transform(
        runtimePrimitive.boundingSphere,
        drawCommand.modelMatrix,
        drawCommand.boundingVolume
      );
    }
  }

  // Update all children runtime nodes.
  for (i = 0; i < runtimeNode.children.length; i++) {
    var childRuntimeNode = sceneGraph.runtimeNodes[runtimeNode.children[i]];

    Matrix4.multiply(
      runtimeNode.transform,
      childRuntimeNode.transform,
      childRuntimeNode.transform
    );

    updateRuntimeNode(childRuntimeNode, sceneGraph);
  }
}

export default ModelMatrixUpdateStage;
<commit_msg>Documenation pass on ModelMatrixUpdateStage<commit_after>import BoundingSphere from "../../Core/BoundingSphere.js";
import defined from "../../Core/defined.js";
import Matrix4 from "../../Core/Matrix4.js";

/**
 * The model matrix update stage is responsible for updating the model matrices and bounding volumes of the draw commands.
 *
 * @namespace ModelMatrixUpdateStage
 *
 * @private
 */
var ModelMatrixUpdateStage = {};
ModelMatrixUpdateStage.name = "ModelMatrixUpdateStage"; // Helps with debugging

/**
 * Processes a runtime node. This modifies the following parts of the scene graph and draw commands:
 *

 *
updates the transforms the children of any nodes with a dirty transform

 *
updates the model matrix of each draw command in each primitive of the the dirty nodes and their children

 *
updates the bounding volume of each draw command in each primitive of the the dirty nodes and their children

 *

 *
 * @param {ModelExperimentalNode} runtimeNode
 * @param {ModelExperimentalSceneGraph} sceneGraph
 * @param {FrameState} frameState
 *
 * @private
 */
ModelMatrixUpdateStage.update = function (runtimeNode, sceneGraph, frameState) {
  if (runtimeNode._transformDirty) {
    updateRuntimeNode(runtimeNode, sceneGraph);
    runtimeNode._transformDirty = false;
  }
};

/**
 * Recursively update runtime nodes.
 */
function updateRuntimeNode(runtimeNode, sceneGraph) {
  var i, j;

  if (defined(runtimeNode.runtimePrimitives)) {
    // Update the DrawCommand's model matrix and bounding volume for each runtime primitive that belongs to this runtime node.
    for (i = 0; i < runtimeNode.runtimePrimitives.length; i++) {
      var runtimePrimitive = runtimeNode.runtimePrimitives[i];
      for (j = 0; j < runtimePrimitive.drawCommands.length; j++) {
        var drawCommand = runtimePrimitive.drawCommands[j];

        Matrix4.clone(runtimeNode.computedTransform, drawCommand.modelMatrix);

        BoundingSphere.transform(
          runtimePrimitive.boundingSphere,
          drawCommand.modelMatrix,
          drawCommand.boundingVolume
        );
      }
    }
  }

  if (defined(runtimeNode.children)) {
    // Update all children runtime nodes.
    for (i = 0; i < runtimeNode.children.length; i++) {
      var childRuntimeNode = sceneGraph._runtimeNodes[runtimeNode.children[i]];

      Matrix4.multiplyTransformation(
        runtimeNode.transform,
        childRuntimeNode.transform,
        childRuntimeNode.transform
      );

      updateRuntimeNode(childRuntimeNode, sceneGraph);
    }
  }
}

export default ModelMatrixUpdateStage;
<|endoftext|>


<commit_before>'use strict';
require('pmx').init({
                        http:          true, // HTTP routes logging (default: true)
                        errors:        true, // Exceptions loggin (default: true)
                        custom_probes: true, // Auto expose JS Loop Latency and HTTP req/s as custom metrics
                        network:       true, // Network monitoring at the application level
                        ports:         false // Shows which ports your app is listening on (default: false)
                    });
var https         = require('https'),
    onHeaders     = require('on-headers'),
    fs            = require('fs'),
    tls           = require('tls'),
    url           = require('url'),
    os            = require('os'),
    Redis         = require('ioredis'),
    hostname      = os.hostname(),
    net           = os.networkInterfaces(),
    netIf         = (net.eth1 === undefined) ? '127.0.0.1' : net.eth1[0].address,
    pid           = process.pid,
    redisReady    = false,
    rmOK          = 'OK',
    rmERROR       = 'ERR',
    raSET         = 'SET',
    raGET         = 'GET',
    raTRANSACTION = 'TRN',
    raPIPELINE    = 'PPL',
    hdREDIS       = 'X-Redis-Time',
    hdNODE        = 'X-Node-Time';
// Defines certificates for enabling TLSv1.2
//
var sslCerts = {
    key:  fs.readFileSync('./nginx-selfsigned.key'),
    cert: fs.readFileSync('./nginx-selfsigned.crt')
};
//
// Create redis cluster client
//
var cluster = new Redis.Cluster(
    [
        {port: 6379, host: "127.0.0.1"},
        {port: 6378, host: "127.0.0.1"},
        {port: 6377, host: "127.0.0.1"},
        {port: 6376, host: "127.0.0.1"},
        {port: 6375, host: "127.0.0.1"},
        {port: 6374, host: "127.0.0.1"}
    ],
    {
        enableReadyCheck:        true,
        maxRedirections:         6,
        retryDelayOnFailover:    1000,
        retryDelayOnClusterDown: 1000,
        scaleReads:              'all',
        redisOptions:            {
            connectionName:         'H' + hostname + 'P' + pid,
            parser:                 'hiredis',
            dropBufferSupport:      true,
            prefix:                 'cn:',
            showFriendlyErrorStack: true
        }
    }
);
//
// Set redis events listeners
//
cluster.on("ready", function() {
    redisReady = true;
    console.log("redis.io cluster connections opened - ready to serve");
});
cluster.on("end", function() {
    redisReady = false;
    console.log("redis.io cluster connections closed");
});
cluster.on("error", function(err) {
    console.log("redis.io Error: " + err);
});
cluster.on("node error", function(err) {
    console.log("redis.io node Error: " + err);
});
//
// Create diff hrtime header
//
var createDiffHrtimeHeader = function(headerLabel, startHRTime, httpResponse) {
    var diffR = process.hrtime(startHRTime),
        timeR = diffR[0] * 1e3 + diffR[1] * 1e-6;
    httpResponse.setHeader(headerLabel, timeR.toFixed(3));
};
//
// Message handlers
//
var messageHandler = function(jsonMsg, httpResponse, redisAction, redisValue) {
    jsonMsg.redisAction = redisAction;
    jsonMsg.redisObject = redisValue;
    httpResponse.end(JSON.stringify(jsonMsg));
};
//
// Send default ERR response due to a Redis error
//
var sendRedisError = function(jsonMsg, redisError, httpResponse, startHRTime) {
    createDiffHrtimeHeader(hdREDIS, startHRTime, httpResponse);
    messageHandler(jsonMsg, httpResponse, rmERROR, {});
    console.log(redisError);
};
//
// Send composite message based on Redis results
//
var sendRedisResults = function(jsonMsg, httpResponse, redisAction, redisValue, startHRTime) {
    createDiffHrtimeHeader(hdREDIS, startHRTime, httpResponse);
    messageHandler(jsonMsg, httpResponse, redisAction, redisValue);
};
//
// Create jsonObject
//
var jsonObject = function() {
    return {hostname: hostname, pid: pid, ts: Date.now()};
};
//
// Generic call wrapper
//
var genericCallWrapper = function(jM, hR, p, prCb, okCb) {
    var src = process.hrtime();
    prCb(p).then(
        okCb(jM, hR, src),
        function(rE) { sendRedisError(jM, rE, hR, src); }
    );
};
//
// Prepare multicommand pipeline (for PIPELINE and TRANSACTION)
//
var prepareCommands = function(p) {
    return [
        ['hgetall',
         p],
        ['hmset',
         p,
         jsonObject()]
    ];
};
//
// Prepare execution function stack
//
var executionMatrix = [
    //
    // HGETALL call
    //
    [
        function(p) {
            return cluster.hgetall(p);
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raGET, (rM === '') ? {} : rM, src);
            };
        }
    ],
    //
    // HMSET call
    //
    [
        function(p) {
            return cluster.hmset(p, jsonObject());
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, (rM === rmOK) ? raSET : rmERROR, {}, src);
            };
        }
    ],
    //
    // PIPELINE call
    //
    [
        function(p) {
            return cluster.pipeline(prepareCommands(p)).exec();
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raPIPELINE, (rM.length === 0) ? {} : rM[0][1], src);
            };
        }
    ],
    //
    // TRANSACTION call
    //
    [
        function(p) {
            return cluster.multi(prepareCommands(p)).exec();
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raTRANSACTION, (rM.length === 0) ? {} : rM[0][1], src);
            };
        }
    ]
];
//
// Set HTTP headers
//
var setAllHeaders = function(hRq, hR) {
    hR.setHeader("Access-Control-Allow-Origin", "*");
    hR.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Pragma, Cache-Control, If-Modified-Since, X-ReqId");
    hR.setHeader("Content-Type", "application/json");
};
//
// Main HTTPS server handler
//
var server = https.createServer(sslCerts, function(hRq, hR) {
    var startNodeCall = process.hrtime(),
        jM            = {
            hostname: hostname,
            pid:      pid
        },
        params        = url.parse(hRq.url, true).query,
        o             = params.o || 0,
        p             = params.p || 0;
    onHeaders(hR, function onHeaders () {
        createDiffHrtimeHeader(hdNODE, startNodeCall, hR);
    });
    setAllHeaders(hRq, hR);
    if (redisReady) {
        genericCallWrapper(jM, hR, p, executionMatrix[o][0], executionMatrix[o][1]);
    }
    else {
        hR.setHeader(hdREDIS, 0);
        messageHandler(jM, hR, rmERROR, {});
    }
}).listen(process.env.NODEPORT, netIf);
//
// Enables graceful stop/reload - nicely closes connections to redis and closes HTTPS server
// enabling last transactions, both on redis and HTTPS server to be completed before exiting
//
process.on('SIGINT', function() {
    //
    // finishes all redis transactions and closes connection with redis
    //
    cluster.quit();
    //
    // finishes all HTTP/2 responses and close server
    //
    server.close();
    //
    // nicely exit node after 0.3 seconds
    //
    setTimeout(function() { process.exit(0); }, 300);
});
<commit_msg>V8 deoptimization prevention updates<commit_after>'use strict';
require('pmx').init({
                        http:          true, // HTTP routes logging (default: true)
                        errors:        true, // Exceptions loggin (default: true)
                        custom_probes: true, // Auto expose JS Loop Latency and HTTP req/s as custom metrics
                        network:       true, // Network monitoring at the application level
                        ports:         false // Shows which ports your app is listening on (default: false)
                    });
var https         = require('https'),
    onHeaders     = require('on-headers'),
    fs            = require('fs'),
    tls           = require('tls'),
    url           = require('url'),
    os            = require('os'),
    Redis         = require('ioredis'),
    hostname      = os.hostname(),
    net           = os.networkInterfaces(),
    netIf         = (net.eth1 === undefined) ? '127.0.0.1' : net.eth1[0].address,
    pid           = process.pid,
    redisReady    = false,
    rmOK          = 'OK',
    rmERROR       = 'ERR',
    raSET         = 'SET',
    raGET         = 'GET',
    raTRANSACTION = 'TRN',
    raPIPELINE    = 'PPL',
    hdREDIS       = 'X-Redis-Time',
    hdNODE        = 'X-Node-Time';
// Defines certificates for enabling TLSv1.2
//
var sslCerts = {
    key:  fs.readFileSync('./nginx-selfsigned.key'),
    cert: fs.readFileSync('./nginx-selfsigned.crt')
};
//
// Create redis cluster client
//
var cluster = new Redis.Cluster(
    [
        {port: 6379, host: "127.0.0.1"},
        {port: 6378, host: "127.0.0.1"},
        {port: 6377, host: "127.0.0.1"},
        {port: 6376, host: "127.0.0.1"},
        {port: 6375, host: "127.0.0.1"},
        {port: 6374, host: "127.0.0.1"}
    ],
    {
        enableReadyCheck:        true,
        maxRedirections:         6,
        retryDelayOnFailover:    1000,
        retryDelayOnClusterDown: 1000,
        scaleReads:              'all',
        redisOptions:            {
            connectionName:         'H' + hostname + 'P' + pid,
            parser:                 'hiredis',
            dropBufferSupport:      true,
            prefix:                 'cn:',
            showFriendlyErrorStack: true
        }
    }
);
//
// Set redis events listeners
//
cluster.on("ready", function() {
    redisReady = true;
    console.log("redis.io cluster connections opened - ready to serve");
});
cluster.on("end", function() {
    redisReady = false;
    console.log("redis.io cluster connections closed");
});
cluster.on("error", function(err) {
    console.log("redis.io Error: " + err);
});
cluster.on("node error", function(err) {
    console.log("redis.io node Error: " + err);
});
//
// Create diff hrtime header
//
var createDiffHrtimeHeader = function(headerLabel, startHRTime, httpResponse) {
    var diffR = process.hrtime(startHRTime),
        timeR = diffR[0] * 1e3 + diffR[1] * 1e-6;
    httpResponse.setHeader(headerLabel, timeR.toFixed(3));
};
//
// Message handlers
//
var messageHandler = function(jsonMsg, httpResponse, redisAction, redisValue) {
    jsonMsg.redisAction = redisAction;
    jsonMsg.redisObject = redisValue;
    httpResponse.end(JSON.stringify(jsonMsg));
};
//
// Send default ERR response due to a Redis error
//
var sendRedisError = function(jsonMsg, redisError, httpResponse, startHRTime) {
    createDiffHrtimeHeader(hdREDIS, startHRTime, httpResponse);
    messageHandler(jsonMsg, httpResponse, rmERROR, {});
    console.log(redisError);
};
//
// Send composite message based on Redis results
//
var sendRedisResults = function(jsonMsg, httpResponse, redisAction, redisValue, startHRTime) {
    createDiffHrtimeHeader(hdREDIS, startHRTime, httpResponse);
    messageHandler(jsonMsg, httpResponse, redisAction, redisValue);
};
//
// Create jsonObject
//
var jsonObject = function() {
    return {hostname: hostname, pid: pid, ts: Date.now()};
};
//
// Generic call wrapper
//
var genericCallWrapper = function(jM, hR, p, prCb, okCb) {
    var src = process.hrtime();
    prCb(p).then(
        okCb(jM, hR, src),
        function(rE) { sendRedisError(jM, rE, hR, src); }
    );
};
//
// Prepare multicommand pipeline (for PIPELINE and TRANSACTION)
//
var prepareCommands = function(p) {
    return [
        ['hgetall',
         p],
        ['hmset',
         p,
         jsonObject()]
    ];
};
//
// Prepare execution function stack
//
var executionMatrix = [
    //
    // HGETALL call
    //
    [
        function(p) {
            return cluster.hgetall(p);
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raGET, (rM === '') ? {} : rM, src);
            };
        }
    ],
    //
    // HMSET call
    //
    [
        function(p) {
            return cluster.hmset(p, jsonObject());
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, (rM === rmOK) ? raSET : rmERROR, {}, src);
            };
        }
    ],
    //
    // PIPELINE call
    //
    [
        function(p) {
            return cluster.pipeline(prepareCommands(p)).exec();
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raPIPELINE, (rM.length === 0) ? {} : rM[0][1], src);
            };
        }
    ],
    //
    // TRANSACTION call
    //
    [
        function(p) {
            return cluster.multi(prepareCommands(p)).exec();
        },
        function(jM, hR, src) {
            return function(rM) {
                sendRedisResults(jM, hR, raTRANSACTION, (rM.length === 0) ? {} : rM[0][1], src);
            };
        }
    ]
];
//
// Set HTTP headers
//
var setAllHeaders = function(hRq, hR) {
    hR.setHeader("Access-Control-Allow-Origin", "*");
    hR.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Pragma, Cache-Control, If-Modified-Since, x-reqid");
    hR.setHeader("Content-Type", "application/json");
};
//
// Main HTTPS server handler
//
var server = https.createServer(sslCerts, function(hRq, hR) {
    var startNodeCall = process.hrtime(),
        jM            = {
            hostname: hostname,
            pid:      pid
        },
        params        = url.parse(hRq.url, true).query,
        o             = params.o || 0,
        p             = params.p || 0;
    onHeaders(hR, function onHeaders () {
        createDiffHrtimeHeader(hdNODE, startNodeCall, hR);
    });
    setAllHeaders(hRq, hR);
    if (redisReady) {
        genericCallWrapper(jM, hR, p, executionMatrix[o][0], executionMatrix[o][1]);
    }
    else {
        hR.setHeader(hdREDIS, 0);
        messageHandler(jM, hR, rmERROR, {});
    }
}).listen(process.env.NODEPORT, netIf);
//
// Enables graceful stop/reload - nicely closes connections to redis and closes HTTPS server
// enabling last transactions, both on redis and HTTPS server to be completed before exiting
//
process.on('SIGINT', function() {
    //
    // finishes all redis transactions and closes connection with redis
    //
    cluster.quit();
    //
    // finishes all HTTP/2 responses and close server
    //
    server.close();
    //
    // nicely exit node after 0.3 seconds
    //
    setTimeout(function() { process.exit(0); }, 300);
});
<|endoftext|>


<commit_before>What is AJAX? (Asynchronous Javascript And Xml)

AJAX is an acronym which stands for Asynchronous JavaScript and XML.
It is a programming technology which is used to create more interactive web pages.
Using AJAX, you can create web pages which can update their content without reloading.
AJAX enables a web page to communicate directly with the server, retrieve information, and update itself.
All this happens without the page actually reloading.

To understand AJAX, there are two things which you need to know from the outset.
First of all, AJAX is not a programming language. Neither is it a software.
AJAX is a programming paradigm – a technique.
It is a technique for using web technologies including CSS, HTML, JavaScript, DOM and XML or JSON.
Basically, to use AJAX in your web applications, you need to have a basic grasp of those technologies.

Secondly, you need a basic understanding of how web browsers interact with a web server.
Traditionally, web browsers interact with a web-server in a synchronous manner.
The interaction mostly takes place in three steps, repeated over and over again:
  1. A Web browser requests a page from the server
  2. The server sends the page to the browser
  3. The browser displays the page to the user

In AJAX model, based on user actions (clicking on a button, or image for example)
JavaScript code sends request to the web server, receives the response and updates the web page.

A good example of AJAX in action is the Facebook or Twitter pages.
When you scroll down to your Facebook page, it keeps fetching your previous news feeds and displaying them.
It does this without reloading the page. You get the impression of scrolling down to one endless, very long web page.

An AJAX request model isn’t as easy to implement as the traditional model.
It requires a web developer to do some JavaScript programming on the web page.
The JavaScript sends a request to the server; reads the response and displays the results by updating the page’s DOM.
This may sound complicated, but it isn’t really. Modern browsers have an inbuilt object called the XMLHttpRequest object.
This object makes it quite easy for a JavaScript to communicate with the server.

AJAX using Pure JavaScript

Implementing some sample code using pure JavaScript will help you understand AJAX better.

We can use the XMLHttpRequest (also referred to as the XHR) object to communicate with the server.
Using XHR object, a web page can interact with interact with PHP scripts, databases, applications
and even text files located on the server.
By “interact” we mean that it can both send and retrieve data from those various sources.
This interaction is typically driven by JavaScript, and a simple Ajax implementation takes place in four steps:

  1. Create an instance of the XMLHttpRequest object

      To create an instance of XHR, you simply get a variable name,
      and use the new XMLHttpRequest() method to crate the instance.

        var xhr = new XMLHttpRequest();

  2. Use open() method of the XHR to specify what kind of data you want

      The XHR’s open() is used to specify the kind of data an object wants from the server.
      You basically use it to describe what you want from the server.
      It takes three arguments i.e. the type of request, the location of the file on the server, and a synchronous indicator.

      Calling it looks like this:
        xhr.open(request, url, async)

        request ‐ this is the type of request you are sending to the server.
                  It takes one of two values: GET or POST. In simple terms,
                  GET is for retrieving something from the server.
                  POST is for sending something to the server.

        url ‐ this is the URL of the file on the server.
              It is can be static or relative URL or simply the path from the folder which contains the web page.

        async ‐ this is used to determine whether or not the request should be executed asynchronously.
        It takes the value “true” or “false”. True is for asynchronous execution. False is for synchronous execution.

        In our case, we shall call the open() method as follows:

          xhr.open("GET", "ajax_data.txt", true);

  3. Create a function to utilize the results

      An XHR object has many inbuilt variables in which it stores data retrieved from the server.
      One of these variables is called responseText.

      When we call xhr.open(), it will fetch the text information stored “ajax_data.txt”
      and store it in its responseText variable. So, to access the data, we simply have to call xhr.responseText

        function() {
          document.getElementByID("myContent").innerHTML = xhr.responseText;
        }

      This function basically replaces the HTML found in the <div> “myContent” with the text fetched from the server.

  4. Use the XHR’s send() method to send the request

      The send() method is used to send the request to the server.
      It doesn’t take any parameters, so you simply call it as follows:

        xhr.send();

  5. Receive the response

    How do you know when a response has come from the server?
    XHR has two properties are used to indicate a response from the server.
    The first is “readyState”, and the second is “status”.

      The “readyState” property records how the request is progressing.
      It returns a numerical value, numbered 0 to 4 which indicate different states of progress.
      The numbers translate as follows:

        0 ‐ request not initialized
        1 ‐ connection to server established
        2 ‐ request received by server
        3 ‐ server is processing the request
        4 ‐ the request has been processed, and the response is ready

      The “status” property indicates whether or not the request was successfully executed.

        200 ‐ request successfully executed and response delivered
        404 ‐ page not found

    You can access these properties by referencing them from the XHR variable as follows:

      xhr.readyState or xhr.status

    So, our function code has to be rewritten as follows :

      function () {
          if( xhr.readyState==4 && xhr.status==200 ){
              document.getElementById("myContent").innerHTML = xhr.responseText;
          }
      }

    So, how do we know that a response has come from the server?

    Well, XHR has an event has an event which is triggered every time the “readyState” changes.
    This event is called “onreadystatechange” event.
    This event is the perfect way to execute any function designed to utilize the results retrieved from the server.
    You simply assign the function to respond to this event like so: onreadystatechange = function_name;

    Since we are using an anonymous function, we attach it as follows:

      xhr.onreadystatechange = function () {
          if( xhr.readyState==4 && xhr.status==200 ) {
              document.getElementById("myContent").innerHTML = xhr.responseText;
          }
      }

We have completed the five steps, and our AJAX implementation is ready to go.
We simply have to bring it all together under a function. So, it all comes together like this:

  document.getElementById('actbutton').onclick = function(){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://codepen.io/prasanthmj/pen/ICgxE.html", true);

    xhr.onreadystatechange = function (){
      if ( xhr.readyState==4 && xhr.status==200 ){
          document.getElementById("myContent").innerHTML = xhr.responseText;
      }
    }
    xhr.send();
  }

This is how to work with AJAX using pure Javascript.
You use JavaScript to send requests to the server using an XMLHttpRequest object.
You still use JavaScript to display the results on the web page.
In most cases, you use JSON or XML to exchange data between the browser and the server.
However, irrespective of how complicated your AJAX application is, the steps are as outlined above.

<commit_msg>change file into Markdown file<commit_after>What is AJAX? (Asynchronous Javascript And Xml)
================================================

AJAX is an acronym which stands for Asynchronous JavaScript and XML.
It is a programming technology which is used to create more interactive web pages.
Using AJAX, you can create web pages which can update their content without reloading.
AJAX enables a web page to communicate directly with the server, retrieve information, and update itself.
All this happens without the page actually reloading.

To understand AJAX, there are two things which you need to know from the outset.
First of all, AJAX is not a programming language. Neither is it a software.
AJAX is a programming paradigm – a technique.
It is a technique for using web technologies including CSS, HTML, JavaScript, DOM and XML or JSON.
Basically, to use AJAX in your web applications, you need to have a basic grasp of those technologies.

Secondly, you need a basic understanding of how web browsers interact with a web server.
Traditionally, web browsers interact with a web-server in a synchronous manner.
The interaction mostly takes place in three steps, repeated over and over again:
  1. A Web browser requests a page from the server
  2. The server sends the page to the browser
  3. The browser displays the page to the user

In AJAX model, based on user actions (clicking on a button, or image for example)
JavaScript code sends request to the web server, receives the response and updates the web page.

A good example of AJAX in action is the Facebook or Twitter pages.
When you scroll down to your Facebook page, it keeps fetching your previous news feeds and displaying them.
It does this without reloading the page. You get the impression of scrolling down to one endless, very long web page.

An AJAX request model isn’t as easy to implement as the traditional model.
It requires a web developer to do some JavaScript programming on the web page.
The JavaScript sends a request to the server; reads the response and displays the results by updating the page’s DOM.
This may sound complicated, but it isn’t really. Modern browsers have an inbuilt object called the XMLHttpRequest object.
This object makes it quite easy for a JavaScript to communicate with the server.

## AJAX using Pure JavaScript

  Implementing some sample code using pure JavaScript will help you understand AJAX better.

  We can use the XMLHttpRequest (also referred to as the XHR) object to communicate with the server.
  Using XHR object, a web page can interact with interact with PHP scripts, databases, applications
  and even text files located on the server.
  By “interact” we mean that it can both send and retrieve data from those various sources.
  This interaction is typically driven by JavaScript, and a simple Ajax implementation takes place in four steps:

    1. Create an instance of the XMLHttpRequest object

        To create an instance of XHR, you simply get a variable name,
        and use the new XMLHttpRequest() method to crate the instance.

          var xhr = new XMLHttpRequest();

    2. Use open() method of the XHR to specify what kind of data you want

        The XHR’s open() is used to specify the kind of data an object wants from the server.
        You basically use it to describe what you want from the server.
        It takes three arguments i.e. the type of request, the location of the file on the server, and a synchronous indicator.

        Calling it looks like this:
          xhr.open(request, url, async)

          request ‐ this is the type of request you are sending to the server.
                    It takes one of two values: GET or POST. In simple terms,
                    GET is for retrieving something from the server.
                    POST is for sending something to the server.

          url ‐ this is the URL of the file on the server.
                It is can be static or relative URL or simply the path from the folder which contains the web page.

          async ‐ this is used to determine whether or not the request should be executed asynchronously.
          It takes the value “true” or “false”. True is for asynchronous execution. False is for synchronous execution.

          In our case, we shall call the open() method as follows:

            xhr.open("GET", "ajax_data.txt", true);

    3. Create a function to utilize the results

        An XHR object has many inbuilt variables in which it stores data retrieved from the server.
        One of these variables is called responseText.

        When we call xhr.open(), it will fetch the text information stored “ajax_data.txt”
        and store it in its responseText variable. So, to access the data, we simply have to call xhr.responseText

          function() {
            document.getElementByID("myContent").innerHTML = xhr.responseText;
          }

        This function basically replaces the HTML found in the <div> “myContent” with the text fetched from the server.

    4. Use the XHR’s send() method to send the request

        The send() method is used to send the request to the server.
        It doesn’t take any parameters, so you simply call it as follows:

          xhr.send();

    5. Receive the response

      How do you know when a response has come from the server?
      XHR has two properties are used to indicate a response from the server.
      The first is “readyState”, and the second is “status”.

        The “readyState” property records how the request is progressing.
        It returns a numerical value, numbered 0 to 4 which indicate different states of progress.
        The numbers translate as follows:

          0 ‐ request not initialized
          1 ‐ connection to server established
          2 ‐ request received by server
          3 ‐ server is processing the request
          4 ‐ the request has been processed, and the response is ready

        The “status” property indicates whether or not the request was successfully executed.

          200 ‐ request successfully executed and response delivered
          404 ‐ page not found

      You can access these properties by referencing them from the XHR variable as follows:

        xhr.readyState or xhr.status

      So, our function code has to be rewritten as follows :

        function () {
            if( xhr.readyState==4 && xhr.status==200 ){
                document.getElementById("myContent").innerHTML = xhr.responseText;
            }
        }

      So, how do we know that a response has come from the server?

      Well, XHR has an event has an event which is triggered every time the “readyState” changes.
      This event is called “onreadystatechange” event.
      This event is the perfect way to execute any function designed to utilize the results retrieved from the server.
      You simply assign the function to respond to this event like so: onreadystatechange = function_name;

      Since we are using an anonymous function, we attach it as follows:

        xhr.onreadystatechange = function () {
            if( xhr.readyState==4 && xhr.status==200 ) {
                document.getElementById("myContent").innerHTML = xhr.responseText;
            }
        }

  We have completed the five steps, and our AJAX implementation is ready to go.
  We simply have to bring it all together under a function. So, it all comes together like this:

    document.getElementById('actbutton').onclick = function(){
      var xhr = new XMLHttpRequest();
      xhr.open("GET", "http://codepen.io/prasanthmj/pen/ICgxE.html", true);

      xhr.onreadystatechange = function (){
        if ( xhr.readyState==4 && xhr.status==200 ){
            document.getElementById("myContent").innerHTML = xhr.responseText;
        }
      }
      xhr.send();
    }

  This is how to work with AJAX using pure Javascript.
  You use JavaScript to send requests to the server using an XMLHttpRequest object.
  You still use JavaScript to display the results on the web page.
  In most cases, you use JSON or XML to exchange data between the browser and the server.
  However, irrespective of how complicated your AJAX application is, the steps are as outlined above.

## AJAX using jQuery

<|endoftext|>


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

  var mixin = {
    initCaptcha: function () {
      var $parentForm,
        $wrapper,
        $reCaptcha,
        widgetId,
        parameters;

      if (this.captchaInitialized) {
        return;
      }

      // SNOWDOG CHANGES
      // Halt function if Recaptcha is disabled
      if (typeof this.settings === 'undefined') {
        return;
      }

      this.captchaInitialized = true;

      /*
       * Workaround for data-bind issue:
       * We cannot use data-bind to link a dynamic id to our component
       * See:
       * https://stackoverflow.com/questions/46657573/recaptcha-the-bind-parameter-must-be-an-element-or-id
       *
       * We create a wrapper element with a wrapping id and we inject the real ID with jQuery.
       * In this way we have no data-bind attribute at all in our reCAPTCHA div
       */
      $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');
      $reCaptcha = $wrapper.find('.g-recaptcha');
      $reCaptcha.attr('id', this.getReCaptchaId());

      $parentForm = $wrapper.parents('form');

      parameters = _.extend(
        {
          'callback': function (token) { // jscs:ignore jsDoc
            this.reCaptchaCallback(token);
            this.validateReCaptcha(true);
          }.bind(this),
          'expired-callback': function () {
            this.validateReCaptcha(false);
          }.bind(this)
        },
        this.settings.rendering
      );

      if (parameters.size === 'invisible' && parameters.badge !== 'inline') {
        nonInlineReCaptchaRenderer.add($reCaptcha, parameters);
      }

      // eslint-disable-next-line no-undef
      widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);
      this.initParentForm($parentForm, widgetId);

      registry.ids.push(this.getReCaptchaId());
      registry.captchaList.push(widgetId);
      registry.tokenFields.push(this.tokenField);

    },
  };

  return function (target) {
    return target.extend(mixin);
  }

});
<commit_msg>#81212: Add additional check in recaptcha mixin<commit_after>define([
  'jquery',
  'underscore',
  'Magento_ReCaptchaFrontendUi/js/registry',
],
  function ($, _, registry) {
  'use strict';

  var mixin = {

    // SNOWDOG CHANGES
    // Add check if Recaptcha is disabled
    getIsInvisibleRecaptcha: function () {
      if (this.settings) {
        return this.settings.invisible;
      }
    },

    initCaptcha: function () {
      var $parentForm,
        $wrapper,
        $reCaptcha,
        widgetId,
        parameters;

      if (this.captchaInitialized) {
        return;
      }

      // SNOWDOG CHANGES
      // Add check if Recaptcha is disabled
      if (typeof this.settings === 'undefined') {
        return;
      }

      this.captchaInitialized = true;

      /*
       * Workaround for data-bind issue:
       * We cannot use data-bind to link a dynamic id to our component
       * See:
       * https://stackoverflow.com/questions/46657573/recaptcha-the-bind-parameter-must-be-an-element-or-id
       *
       * We create a wrapper element with a wrapping id and we inject the real ID with jQuery.
       * In this way we have no data-bind attribute at all in our reCAPTCHA div
       */
      $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');
      $reCaptcha = $wrapper.find('.g-recaptcha');
      $reCaptcha.attr('id', this.getReCaptchaId());

      $parentForm = $wrapper.parents('form');

      parameters = _.extend(
        {
          'callback': function (token) { // jscs:ignore jsDoc
            this.reCaptchaCallback(token);
            this.validateReCaptcha(true);
          }.bind(this),
          'expired-callback': function () {
            this.validateReCaptcha(false);
          }.bind(this)
        },
        this.settings.rendering
      );

      if (parameters.size === 'invisible' && parameters.badge !== 'inline') {
        nonInlineReCaptchaRenderer.add($reCaptcha, parameters);
      }

      // eslint-disable-next-line no-undef
      widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);
      this.initParentForm($parentForm, widgetId);

      registry.ids.push(this.getReCaptchaId());
      registry.captchaList.push(widgetId);
      registry.tokenFields.push(this.tokenField);

    },
  };

  return function (target) {
    return target.extend(mixin);
  }

});
<|endoftext|>


<commit_before>var Constants = require('../constants/constants.js');

var json_handler = {}

//TODO : Agregar los intereses a los archivos JSON generados

/*
 * Recibo el resultado de una query sobre la tabla users
 * que me devuelve todos los usuarios de la tabla
 * y armo un objeto JSON con los campos necesarios para devolver
 * segun la especificacion de la API
 */
json_handler.armarJsonListaUsuarios = function(result) {
  var jsonObject = { "users" : [] , metadata : { version : Constants.METADATA_VERSION , count : result.rowCount}}
  for (var i = 0; i < result.rowCount; i++) {
    var oneUser = {
      user : {
        name : result.rows[i].name,
        alias : result.rows[i].alias,
        email : result.rows[i].email,
        sex : result.rows[i].sex,
        //photo_profile: result.rows[i].photo_profile,
        photo_profile: "http://t2shared.herokuapp.com/users/id_user/photo",
        interests: [],
        location : {
          latitude : result.rows[i].latitude,
          longitude : result.rows[i].longitude
        }
      }
    }
    jsonObject.users.push(oneUser);
  }
  return jsonObject;
}

/*
 * Una vez que se da de alta un usuario nuevo, necesito devolver
 * un JSON que contenga los campos que especifica la API que
 * hay que devolver del usuario recien creado
 */
json_handler.armarJsonUsuarioNuevo = function(req,id_user) {
  var jsonObject = {
    user : {
      id : id_user,
      name : req.body.user.name,
      alias : req.body.user.alias,
      email : req.body.user.email,
      sex : req.body.user.sex,
      location : {
        latitude : req.body.user.location.latitude,
        longitude : req.body.user.location.longitude
      }
    },
    metadata : {
      version : Constants.METADATA_VERSION
    }
  }
  return jsonObject;
}

/*
 * Recibo el resultado de una query sobre la tabla users
 * que me devuelve un usuario de la tabla
 * y armo un objeto JSON con los campos necesarios para devolver
 * segun la especificacion de la API
 */
json_handler.armarJsonUsuarioConsultado = function (result) {
  var jsonObject = {
    user : {
      name : result.rows[0].name,
      alias : result.rows[0].alias,
      email : result.rows[0].email,
      sex : result.rows[0].sex,
      photo_profile : result.rows[0].photo_profile,
      location : {
        latitude : result.rows[0].latitude,
        longitude : result.rows[0].longitude
      }
    },
    metadata : {
      version : Constants.METADATA_VERSION
    }
  }
  return jsonObject;
}

module.exports = json_handler;
<commit_msg>Close #10 - Cierro Modularizar Json<commit_after>var Constants = require('../constants/constants.js');

var json_handler = {}

//TODO : Agregar los intereses a los archivos JSON generados
//TODO : Recibir el id_user en la funcion armarJsonListaUsuarios
/*
 * Recibo el resultado de una query sobre la tabla users
 * que me devuelve todos los usuarios de la tabla
 * y armo un objeto JSON con los campos necesarios para devolver
 * segun la especificacion de la API
 */
json_handler.armarJsonListaUsuarios = function(result) {
  var jsonObject = { "users" : [] , metadata : { version : Constants.METADATA_VERSION , count : result.rowCount}}
  for (var i = 0; i < result.rowCount; i++) {
    var oneUser = {
      user : {
        name : result.rows[i].name,
        alias : result.rows[i].alias,
        email : result.rows[i].email,
        sex : result.rows[i].sex,
        //photo_profile: result.rows[i].photo_profile,
        photo_profile: "http://t2shared.herokuapp.com/users/id_user/photo",
        interests: [],
        location : {
          latitude : result.rows[i].latitude,
          longitude : result.rows[i].longitude
        }
      }
    }
    jsonObject.users.push(oneUser);
  }
  return jsonObject;
}

/*
 * Una vez que se da de alta un usuario nuevo, necesito devolver
 * un JSON que contenga los campos que especifica la API que
 * hay que devolver del usuario recien creado
 */
json_handler.armarJsonUsuarioNuevo = function(req,id_user) {
  var jsonObject = {
    user : {
      id : id_user,
      name : req.body.user.name,
      alias : req.body.user.alias,
      email : req.body.user.email,
      sex : req.body.user.sex,
      location : {
        latitude : req.body.user.location.latitude,
        longitude : req.body.user.location.longitude
      }
    },
    metadata : {
      version : Constants.METADATA_VERSION
    }
  }
  return jsonObject;
}

/*
 * Recibo el resultado de una query sobre la tabla users
 * que me devuelve un usuario de la tabla
 * y armo un objeto JSON con los campos necesarios para devolver
 * segun la especificacion de la API
 */
json_handler.armarJsonUsuarioConsultado = function (result) {
  var jsonObject = {
    user : {
      name : result.rows[0].name,
      alias : result.rows[0].alias,
      email : result.rows[0].email,
      sex : result.rows[0].sex,
      photo_profile : result.rows[0].photo_profile,
      location : {
        latitude : result.rows[0].latitude,
        longitude : result.rows[0].longitude
      }
    },
    metadata : {
      version : Constants.METADATA_VERSION
    }
  }
  return jsonObject;
}

module.exports = json_handler;
<|endoftext|>