<commit_before>angular.module('dailynk.controllers', [])

.controller('dailynkCtrl', function(
	$scope,
	$ionicPopup,
	$timeout,
	$ionicNavBarDelegate,
	$ionicSideMenuDelegate,
	$ionicListDelegate,
	$filter) {

	console.log("Creating dailynkCtrl");

	/* Initializing UI */
	$scope.initUI = function() {
		$scope.UIproperty = {
			windowWidth: window.innerWidth,
			windowHeight: window.innerHeight
		};
	};

	/* Initializing DB */
	$scope.initDB = function() {
		$scope.db = (localStorage.getItem("db") !== null) ?  angular.fromJson(localStorage.getItem("db")) : {} ;
		$scope.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
		$scope.doWeekView();
	};

	$scope.getNewLink = function() {
		return {
			id: "",
			oldId: "",
			title: "",
			days: [false, false, false, false, false, false, false],
			isDayValid: "",	// for form validation (required) ["" : "valid"]
			favorite: false,
		};
	}

	/* Initializing App */
	$scope.initApp = function() {

		$scope.newLink = $scope.getNewLink();

		var d = new Date();
		// 0 = Monday, 1 = Tuesday ...
		$scope.selectedDay = (d.getDay() == 0) ? 6:  (d.getDay() - 1);
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

	};

	$scope.onresize = function() {
		console.log("Resizing");
		$scope.UIproperty = {
			windowWidth: window.innerWidth,
			windowHeight: window.innerHeight
		};
		$timeout(function() { $scope.$apply() });
	};

	/* Number of records stored */
	$scope.dbLength = function() {
		return Object.keys($scope.db).length;
	};

	/* Back in history - NOT WORKING */
	$scope.goBack = function() {
    $ionicNavBarDelegate.back();
	};

	$scope.doWeekView = function() {

		$scope.weekView = [[],[],[],[],[],[],[]];
		var links = Object.keys($scope.db);

		// Cicle through links
		for (var ii=0; ii<links.length; ii++) {
			var link = $scope.db[links[ii]];
			// Cicle through days
			for (var jj=0; jj<link.days.length; jj++) {
				if (link.days[jj]) {
					$scope.weekView[jj].push({
						id: links[ii],
						title: link.title
					});
				}
			}
		}
	}

	/* Check one day at least for saving link */
	$scope.checkValidationDays = function() {
		var check = false;
		for (var ii=0; ii<$scope.newLink.days.length; ii++) {
			if ($scope.newLink.days[ii]) {
				check = true;
				break;
			}
		}
		$scope.newLink.isDayValid = check ? "valid" : "";
	}

	/* After tapping on plus icon */
	$scope.addLink = function() {

		// Clean newLink object
		$scope.newLink = $scope.getNewLink();
		// Show form
		$scope.toggleRight();

	};

	$scope.closeOptionButtons = function() {
		$ionicListDelegate.$getByHandle("link-list-handler").closeOptionButtons();
	}

	/* Toggle right and show form for editing link */
	$scope.editLink = function(item) {
		// Close option buttons
		$scope.closeOptionButtons();

		var link = $scope.db[item.id];
		$scope.newLink.oldId = item.id;
		$scope.newLink.id = item.id;
		$scope.newLink.title = link.title;
		$scope.newLink.days = link.days;
		$scope.newLink.favorite = link.favorite;
		$scope.checkValidationDays();
		$scope.toggleRight();
	};

	/* When deleting, remove only day selected check */
	$scope.deleteLink = function(item) {

		$scope.db[item.id].days[$scope.selectedDay] = false;

		// If all days are false delete link
		var checkActive = false;
		for (var ii=0; ii<$scope.days.length; ii++) {
			if ($scope.db[item.id].days[ii]) checkActive = true;
		}
		if (!checkActive) delete $scope.db[item.id];

		// Close option buttons
		$scope.closeOptionButtons();

		// Update storage
		$scope.updateStorage();

		// Update View
		$scope.doWeekView();
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

	};

	// Add or edit link
	$scope.saveLink = function() {

		// Check if editing
		if ($scope.newLink.oldId != "") {
			delete $scope.db[$scope.newLink.oldId]
		}
		// Update scope
		var newLink = {
			title: $scope.newLink.title,
			days: $scope.newLink.days,
			favorite: $scope.newLink.favorite,
		};

		// Update DB
		$scope.db[$scope.newLink.id] = newLink;
		// Update storage
		$scope.updateStorage();

		// Clean new Link
		$scope.newLink = $scope.getNewLink();

		// Update View
		$scope.doWeekView();
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

		$scope.toggleRight();

	};

	/* Update storage */
	$scope.updateStorage = function() {
		localStorage.setItem("db", angular.toJson($scope.db));
	};

	/* Open Link In App Browser */
	$scope.openLink = function(url, event) {

		// Check if http:// missing
		var url = url.indexOf("http://") == -1 ? "http://" + url : url;
		$scope.wRef = window.open(url, "_blank", "location=no");

		// Change style
		var item = angular.element(event.currentTarget).addClass("visited");

	};

	$scope.chooseDay = function(day) {
		$scope.selectedDay = day;
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];
		$scope.toggleLeft();
	}

	$scope.toggleLeft = function() {
		$ionicSideMenuDelegate.toggleLeft();
	};

	$scope.toggleRight = function() {
		$ionicSideMenuDelegate.toggleRight();
	};

	/* Ask for confirmation for clearing data */
	$scope.confirmClearData = function() {
		var confirmPopup = $ionicPopup.confirm({
			title: "Clear Data",
			template: "Are you sure you want to delete all your links?"
		});
		confirmPopup.then(function(res){
			if (res) {
				try {
					$scope.db = {};
					$scope.selectedDayLinks = [];
					$scope.doWeekView();
					$scope.updateStorage();
					var alertPopup = $ionicPopup.alert({
						title: "Clear Data",
						template: "All data has been cleared."
					});
				} catch (e) {
					var alertPopup = $ionicPopup.alert({
						title: "Clear Data",
						template: "Something went wrong."
					});
				}
			} else {
				console.log("KO");
			}
		});
	};

	$scope.favoritesFilter = function() {
		var favorites = {};
		angular.forEach($scope.db, function(value, key) {
			if (value.favorite) {
				favorites[key] = value;
			}
    });
		return favorites;
	}

	/* At the end, init application */
	$scope.initUI();
	$scope.initDB();
	$scope.initApp();
	window.onresize = $scope.onresize;

	/* Utility */
	window.scope = $scope;
});
<commit_msg>Fixed #3 - Back Navigation<commit_after>angular.module('dailynk.controllers', [])

.controller('dailynkCtrl', function(
	$scope,
	$ionicPopup,
	$timeout,
	$ionicSideMenuDelegate,
	$ionicListDelegate,
	$filter) {

	console.log("Creating dailynkCtrl");

	/* Initializing UI */
	$scope.initUI = function() {
		$scope.UIproperty = {
			windowWidth: window.innerWidth,
			windowHeight: window.innerHeight
		};
	};

	/* Initializing DB */
	$scope.initDB = function() {
		$scope.db = (localStorage.getItem("db") !== null) ?  angular.fromJson(localStorage.getItem("db")) : {} ;
		$scope.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
		$scope.doWeekView();
	};

	$scope.getNewLink = function() {
		return {
			id: "",
			oldId: "",
			title: "",
			days: [false, false, false, false, false, false, false],
			isDayValid: "",	// for form validation (required) ["" : "valid"]
			favorite: false,
		};
	}

	/* Initializing App */
	$scope.initApp = function() {

		$scope.newLink = $scope.getNewLink();

		var d = new Date();
		// 0 = Monday, 1 = Tuesday ...
		$scope.selectedDay = (d.getDay() == 0) ? 6:  (d.getDay() - 1);
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

	};

	$scope.onresize = function() {
		console.log("Resizing");
		$scope.UIproperty = {
			windowWidth: window.innerWidth,
			windowHeight: window.innerHeight
		};
		$timeout(function() { $scope.$apply() });
	};

	/* Number of records stored */
	$scope.dbLength = function() {
		return Object.keys($scope.db).length;
	};

	/* Back in history */
	$scope.goBack = function() {
    history.back();
	};

	$scope.doWeekView = function() {

		$scope.weekView = [[],[],[],[],[],[],[]];
		var links = Object.keys($scope.db);

		// Cicle through links
		for (var ii=0; ii<links.length; ii++) {
			var link = $scope.db[links[ii]];
			// Cicle through days
			for (var jj=0; jj<link.days.length; jj++) {
				if (link.days[jj]) {
					$scope.weekView[jj].push({
						id: links[ii],
						title: link.title
					});
				}
			}
		}
	}

	/* Check one day at least for saving link */
	$scope.checkValidationDays = function() {
		var check = false;
		for (var ii=0; ii<$scope.newLink.days.length; ii++) {
			if ($scope.newLink.days[ii]) {
				check = true;
				break;
			}
		}
		$scope.newLink.isDayValid = check ? "valid" : "";
	}

	/* After tapping on plus icon */
	$scope.addLink = function() {

		// Clean newLink object
		$scope.newLink = $scope.getNewLink();
		// Show form
		$scope.toggleRight();

	};

	$scope.closeOptionButtons = function() {
		$ionicListDelegate.$getByHandle("link-list-handler").closeOptionButtons();
	}

	/* Toggle right and show form for editing link */
	$scope.editLink = function(item) {
		// Close option buttons
		$scope.closeOptionButtons();

		var link = $scope.db[item.id];
		$scope.newLink.oldId = item.id;
		$scope.newLink.id = item.id;
		$scope.newLink.title = link.title;
		$scope.newLink.days = link.days;
		$scope.newLink.favorite = link.favorite;
		$scope.checkValidationDays();
		$scope.toggleRight();
	};

	/* When deleting, remove only day selected check */
	$scope.deleteLink = function(item) {

		$scope.db[item.id].days[$scope.selectedDay] = false;

		// If all days are false delete link
		var checkActive = false;
		for (var ii=0; ii<$scope.days.length; ii++) {
			if ($scope.db[item.id].days[ii]) checkActive = true;
		}
		if (!checkActive) delete $scope.db[item.id];

		// Close option buttons
		$scope.closeOptionButtons();

		// Update storage
		$scope.updateStorage();

		// Update View
		$scope.doWeekView();
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

	};

	// Add or edit link
	$scope.saveLink = function() {

		// Check if editing
		if ($scope.newLink.oldId != "") {
			delete $scope.db[$scope.newLink.oldId]
		}
		// Update scope
		var newLink = {
			title: $scope.newLink.title,
			days: $scope.newLink.days,
			favorite: $scope.newLink.favorite,
		};

		// Update DB
		$scope.db[$scope.newLink.id] = newLink;
		// Update storage
		$scope.updateStorage();

		// Clean new Link
		$scope.newLink = $scope.getNewLink();

		// Update View
		$scope.doWeekView();
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];

		$scope.toggleRight();

	};

	/* Update storage */
	$scope.updateStorage = function() {
		localStorage.setItem("db", angular.toJson($scope.db));
	};

	/* Open Link In App Browser */
	$scope.openLink = function(url, event) {

		// Check if http:// missing
		var url = url.indexOf("http://") == -1 ? "http://" + url : url;
		$scope.wRef = window.open(url, "_blank", "location=no");

		// Change style
		var item = angular.element(event.currentTarget).addClass("visited");

	};

	$scope.chooseDay = function(day) {
		$scope.selectedDay = day;
		$scope.selectedDayLinks = $scope.weekView[$scope.selectedDay];
		$scope.toggleLeft();
	}

	$scope.toggleLeft = function() {
		$ionicSideMenuDelegate.toggleLeft();
	};

	$scope.toggleRight = function() {
		$ionicSideMenuDelegate.toggleRight();
	};

	/* Ask for confirmation for clearing data */
	$scope.confirmClearData = function() {
		var confirmPopup = $ionicPopup.confirm({
			title: "Clear Data",
			template: "Are you sure you want to delete all your links?"
		});
		confirmPopup.then(function(res){
			if (res) {
				try {
					$scope.db = {};
					$scope.selectedDayLinks = [];
					$scope.doWeekView();
					$scope.updateStorage();
					var alertPopup = $ionicPopup.alert({
						title: "Clear Data",
						template: "All data has been cleared."
					});
				} catch (e) {
					var alertPopup = $ionicPopup.alert({
						title: "Clear Data",
						template: "Something went wrong."
					});
				}
			} else {
				console.log("KO");
			}
		});
	};

	$scope.favoritesFilter = function() {
		var favorites = {};
		angular.forEach($scope.db, function(value, key) {
			if (value.favorite) {
				favorites[key] = value;
			}
    });
		return favorites;
	}

	/* At the end, init application */
	$scope.initUI();
	$scope.initDB();
	$scope.initApp();
	window.onresize = $scope.onresize;

	/* Utility */
	window.scope = $scope;
});
<|endoftext|>


<commit_before>var App, logs, originalLogger, visit;

module("Ember.Application – logging of generated classes", {
  setup: function(){
    logs = {};

    originalLogger = Ember.Logger.info;

    Ember.Logger.info = function(){
      var fullName = arguments[1].fullName;

      logs[fullName] = logs[fullName] || 0;
      logs[fullName]++;
    };

    Ember.run(function(){
      App = Ember.Application.create({
        LOG_ACTIVE_GENERATION: true
      });

      App.Router.reopen({
        location: 'none'
      });

      App.Router.map(function() {
        this.resource("posts");
      });

      App.deferReadiness();
      App.injectTestHelpers();
      visit = App.testHelpers.visit;
    });
  },

  teardown: function(){
    App.removeTestHelpers();
    Ember.Logger.info = originalLogger;

    Ember.run(App, 'destroy');

    logs = App = null;
  }
});

test("log class generation if logging enabled", function() {
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 6, 'expected logs');
  });
});

test("do NOT log class generation if logging disabled", function() {
  App.reopen({
    LOG_ACTIVE_GENERATION: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});

test("actively generated classes get logged", function() {
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['controller:application'], 1, 'expected: ApplicationController was generated');
    equal(logs['controller:posts'], 1, 'expected: PostsController was generated');

    equal(logs['route:application'], 1, 'expected: ApplicationRoute was generated');
    equal(logs['route:posts'], 1, 'expected: PostsRoute was generated');
  });
});

test("predefined classes do not get logged", function() {
  App.ApplicationController = Ember.Controller.extend();
  App.PostsController = Ember.Controller.extend();

  App.ApplicationRoute = Ember.Route.extend();
  App.PostsRoute = Ember.Route.extend();

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    ok(!logs['controller:application'], 'did not expect: ApplicationController was generated');
    ok(!logs['controller:posts'], 'did not expect: PostsController was generated');

    ok(!logs['route:application'], 'did not expect: ApplicationRoute was generated');
    ok(!logs['route:posts'], 'did not expect: PostsRoute was generated');
  });
});

module("Ember.Application – logging of view lookups", {
  setup: function(){
    logs = {};

    originalLogger = Ember.Logger.info;

    Ember.Logger.info = function(){
      var fullName = arguments[1].fullName;

      logs[fullName] = logs[fullName] || 0;
      logs[fullName]++;
    };

    Ember.run(function(){
      App = Ember.Application.create({
        LOG_VIEW_LOOKUPS: true
      });

      App.Router.reopen({
        location: 'none'
      });

      App.Router.map(function() {
        this.resource("posts");
      });

      App.deferReadiness();
      App.injectTestHelpers();
      visit = App.testHelpers.visit;
    });
  },

  teardown: function(){
    App.removeTestHelpers();
    Ember.Logger.info = originalLogger;

    Ember.run(App, 'destroy');

    logs = App = null;
  }
});

test("log when template and view are missing when flag is active", function() {
  App.register('template:application', function(){ return ''; });
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['template:application'], undefined, 'expected: Should not log template:application since it exists.');
    equal(logs['template:index'], 1, 'expected: Could not find "index" template or view.');
    equal(logs['template:posts'], 1, 'expected: Could not find "posts" template or view.');
  });
});

test("do not log when template and view are missing when flag is not true", function() {
  App.reopen({
    LOG_VIEW_LOOKUPS: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});

test("log which view is used with a template", function() {
  App.register('template:application', function(){ return 'Template with default view'; });
  App.register('template:foo', function(){ return 'Template with custom view'; });
  App.register('view:posts', Ember.View.extend({templateName: 'foo'}));
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['view:application'], 1, 'expected: Should log use of default view');
    equal(logs['view:index'], undefined, 'expected: Should not log when index is not present.');
    equal(logs['view:posts'], 1, 'expected: Rendering posts with PostsView.');
  });
});

test("do not log which views are used with templates when flag is not true", function() {
  App.reopen({
    LOG_VIEW_LOOKUPS: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});

<commit_msg>remove logging tests dependency on ember-testing<commit_after>var App, logs, originalLogger;

module("Ember.Application – logging of generated classes", {
  setup: function(){
    logs = {};

    originalLogger = Ember.Logger.info;

    Ember.Logger.info = function(){
      var fullName = arguments[1].fullName;

      logs[fullName] = logs[fullName] || 0;
      logs[fullName]++;
    };

    Ember.run(function(){
      App = Ember.Application.create({
        LOG_ACTIVE_GENERATION: true
      });

      App.Router.reopen({
        location: 'none'
      });

      App.Router.map(function() {
        this.resource("posts");
      });

      App.deferReadiness();
    });
  },

  teardown: function(){
    Ember.Logger.info = originalLogger;

    Ember.run(App, 'destroy');

    logs = App = null;
  }
});

function visit(path) {
  stop();

  var promise = new Ember.RSVP.Promise(function(resolve, reject){
    var router = App.__container__.lookup('router:main');

    Ember.run(App, 'handleURL', path);
    Ember.run(router, router.location.setURL, path);

    Ember.run(resolve);
    start();
  });

  return {
    then: function(resolve, reject){
      Ember.run(promise, 'then', resolve, reject);
    }
  };
}

test("log class generation if logging enabled", function() {
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 6, 'expected logs');
  });
});

test("do NOT log class generation if logging disabled", function() {
  App.reopen({
    LOG_ACTIVE_GENERATION: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});

test("actively generated classes get logged", function() {
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['controller:application'], 1, 'expected: ApplicationController was generated');
    equal(logs['controller:posts'], 1, 'expected: PostsController was generated');

    equal(logs['route:application'], 1, 'expected: ApplicationRoute was generated');
    equal(logs['route:posts'], 1, 'expected: PostsRoute was generated');
  });
});

test("predefined classes do not get logged", function() {
  App.ApplicationController = Ember.Controller.extend();
  App.PostsController = Ember.Controller.extend();

  App.ApplicationRoute = Ember.Route.extend();
  App.PostsRoute = Ember.Route.extend();

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    ok(!logs['controller:application'], 'did not expect: ApplicationController was generated');
    ok(!logs['controller:posts'], 'did not expect: PostsController was generated');

    ok(!logs['route:application'], 'did not expect: ApplicationRoute was generated');
    ok(!logs['route:posts'], 'did not expect: PostsRoute was generated');
  });
});

module("Ember.Application – logging of view lookups", {
  setup: function(){
    logs = {};

    originalLogger = Ember.Logger.info;

    Ember.Logger.info = function(){
      var fullName = arguments[1].fullName;

      logs[fullName] = logs[fullName] || 0;
      logs[fullName]++;
    };

    Ember.run(function(){
      App = Ember.Application.create({
        LOG_VIEW_LOOKUPS: true
      });

      App.Router.reopen({
        location: 'none'
      });

      App.Router.map(function() {
        this.resource("posts");
      });

      App.deferReadiness();
    });
  },

  teardown: function(){
    Ember.Logger.info = originalLogger;

    Ember.run(App, 'destroy');

    logs = App = null;
  }
});

test("log when template and view are missing when flag is active", function() {
  App.register('template:application', function(){ return ''; });
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['template:application'], undefined, 'expected: Should not log template:application since it exists.');
    equal(logs['template:index'], 1, 'expected: Could not find "index" template or view.');
    equal(logs['template:posts'], 1, 'expected: Could not find "posts" template or view.');
  });
});

test("do not log when template and view are missing when flag is not true", function() {
  App.reopen({
    LOG_VIEW_LOOKUPS: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});

test("log which view is used with a template", function() {
  App.register('template:application', function(){ return 'Template with default view'; });
  App.register('template:foo', function(){ return 'Template with custom view'; });
  App.register('view:posts', Ember.View.extend({templateName: 'foo'}));
  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(logs['view:application'], 1, 'expected: Should log use of default view');
    equal(logs['view:index'], undefined, 'expected: Should not log when index is not present.');
    equal(logs['view:posts'], 1, 'expected: Rendering posts with PostsView.');
  });
});

test("do not log which views are used with templates when flag is not true", function() {
  App.reopen({
    LOG_VIEW_LOOKUPS: false
  });

  Ember.run(App, 'advanceReadiness');

  visit('/posts').then(function(){
    equal(Ember.keys(logs).length, 0, 'expected no logs');
  });
});
<|endoftext|>


<commit_before>export class UIDatabase {

  constructor(database) {
    this.database = database;
  }

  objects(type) {
    let results = this.database.objects(translateToCoreDatabaseType(type));
    switch (type) {
      case 'Customer':
        results = results.filtered('isVisible == true AND isCustomer == true');
        break;
      case 'Item':
        results = results.filtered('isVisible == true');
        break;
      case 'Name':
        results = results.filtered('isVisible == true OR type == "inventory_adjustment"');
        break;
      default:
        break;
    }
    return results;
  }

  addListener(...args) { return this.database.addListener(...args); }
  removeListener(...args) { return this.database.removeListener(...args); }
  alertListeners(...args) { return this.database.alertListeners(...args); }
  create(...args) { return this.database.create(...args); }
  delete(...args) { return this.database.delete(...args); }
  deleteAll(...args) { return this.database.deleteAll(...args); }
  save(...args) { return this.database.save(...args); }
  update(...args) { return this.database.update(...args); }
  write(...args) { return this.database.write(...args); }

}

function translateToCoreDatabaseType(type) {
  switch (type) {
    case 'Customer':
      return 'Name';
    default:
      return type;
  }
}
<commit_msg>Allow queries of names without visibility<commit_after>export class UIDatabase {

  constructor(database) {
    this.database = database;
  }

  objects(type) {
    let results = this.database.objects(translateToCoreDatabaseType(type));
    switch (type) {
      case 'Customer':
        results = results.filtered('isVisible == true AND isCustomer == true');
        break;
      case 'Item':
        results = results.filtered('isVisible == true');
        break;
      default:
        break;
    }
    return results;
  }

  addListener(...args) { return this.database.addListener(...args); }
  removeListener(...args) { return this.database.removeListener(...args); }
  alertListeners(...args) { return this.database.alertListeners(...args); }
  create(...args) { return this.database.create(...args); }
  delete(...args) { return this.database.delete(...args); }
  deleteAll(...args) { return this.database.deleteAll(...args); }
  save(...args) { return this.database.save(...args); }
  update(...args) { return this.database.update(...args); }
  write(...args) { return this.database.write(...args); }

}

function translateToCoreDatabaseType(type) {
  switch (type) {
    case 'Customer':
      return 'Name';
    default:
      return type;
  }
}
<|endoftext|>


<commit_before>angular.module('umbraco.resources').factory('archetypePropertyEditorResource', function($q, $http, umbRequestHelper){
    return {
        getAllDataTypes: function() {
            // Hack - grab DataTypes from Tree API, as `dataTypeService.getAll()` isn't implemented yet
            return umbRequestHelper.resourcePromise(
                $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAll", { cache: true }), 'Failed to retrieve datatypes from tree service'
            );
        },
        getDataType: function (guid, useDeepDatatypeLookup, contentTypeAlias, propertyTypeAlias, archetypeAlias, nodeId) {
            if(useDeepDatatypeLookup) {
            	return umbRequestHelper.resourcePromise(
            		$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid + "&contentTypeAlias=" + contentTypeAlias + "&propertyTypeAlias=" + propertyTypeAlias + "&archetypeAlias=" + archetypeAlias + "&nodeId=" + nodeId), 'Failed to retrieve datatype'
        		);
            }
            else {
                return umbRequestHelper.resourcePromise(
                    $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid , { cache: true }), 'Failed to retrieve datatype'
                );
            }
        },
        getPropertyEditorMapping: function(alias) {
            return umbRequestHelper.resourcePromise(
                $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAllPropertyEditors", { cache: true }), 'Failed to retrieve datatype mappings'
            ).then(function (data) {
                var result = _.find(data, function(d) {
                    return d.alias === alias;
                });

                if (result != null)
                    return result;

                return "";
            });
        }
    }
});
<commit_msg>Remove caching for property datatype dropdowns<commit_after>angular.module('umbraco.resources').factory('archetypePropertyEditorResource', function($q, $http, umbRequestHelper){
    return {
        getAllDataTypes: function() {
            // Hack - grab DataTypes from Tree API, as `dataTypeService.getAll()` isn't implemented yet
            return umbRequestHelper.resourcePromise(
                $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAll"), 'Failed to retrieve datatypes from tree service'
            );
        },
        getDataType: function (guid, useDeepDatatypeLookup, contentTypeAlias, propertyTypeAlias, archetypeAlias, nodeId) {
            if(useDeepDatatypeLookup) {
            	return umbRequestHelper.resourcePromise(
            		$http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid + "&contentTypeAlias=" + contentTypeAlias + "&propertyTypeAlias=" + propertyTypeAlias + "&archetypeAlias=" + archetypeAlias + "&nodeId=" + nodeId), 'Failed to retrieve datatype'
        		);
            }
            else {
                return umbRequestHelper.resourcePromise(
                    $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid , { cache: true }), 'Failed to retrieve datatype'
                );
            }
        },
        getPropertyEditorMapping: function(alias) {
            return umbRequestHelper.resourcePromise(
                $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAllPropertyEditors", { cache: true }), 'Failed to retrieve datatype mappings'
            ).then(function (data) {
                var result = _.find(data, function(d) {
                    return d.alias === alias;
                });

                if (result != null)
                    return result;

                return "";
            });
        }
    }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node modules */
  var exec = require('child_process').exec,
      fs = require('fs'),
      https = require('https'),
      path = require('path'),
      tar = require('../vendor/tar/tar.js'),
      zlib = require('zlib');

  /** The path of the directory that is the base of the repository */
  var basePath = fs.realpathSync(path.join(__dirname, '..'));

  /** The path of the `vendor` directory */
  var vendorPath = path.join(basePath, 'vendor');

  /** The Git object ID of `closure-compiler.tar.gz` */
  var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';

  /** The Git object ID of `uglifyjs.tar.gz` */
  var uglifyId = '3390b259e04829538e4d3635d12b317dd6103eca';

  /** The media type for raw blob data */
  var mediaType = 'application/vnd.github.v3.raw';

  /** Used to reference parts of the blob href */
  var location = (function() {
    var host = 'api.github.com',
        origin = 'https://api.github.com',
        pathname = '/repos/bestiejs/lodash/git/blobs';

    return {
      'host': host,
      'href': host + origin + pathname,
      'origin': origin,
      'pathname': pathname
    };
  }());

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

  /**
   * Fetches a required `.tar.gz` dependency with the given Git object ID from
   * the Lo-Dash repo on GitHub. The object ID may be obtained by running
   * `git hash-object path/to/dependency.tar.gz`.
   *
   * @private
   * @param {Object} options The options object.
   *  id - The Git object ID of the `.tar.gz` file.
   *  onComplete - The function, invoked with one argument (exception),
   *   called once the extraction has finished.
   *  path - The path of the extraction directory.
   *  title - The dependency's title used in status updates logged to the console.
   */
  function getDependency(options) {
    options || (options = {});

    var id = options.id,
        onComplete = options.onComplete,
        path = options.path,
        title = options.title;

    function callback(exception) {
      if (exception) {
        console.error([
          'There was a problem installing ' + title + '. To manually install, run:',
          '',
          "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
        ].join('\n'));
      }
      onComplete(exception);
    }

    console.log('Downloading ' + title + '...');

    https.get({
      'host': location.host,
      'path': location.pathname + '/' + id,
      'headers': {
        // By default, all GitHub blob API endpoints return a JSON document
        // containing Base64-encoded blob data. Overriding the `Accept` header
        // with the GitHub raw media type returns the blob data directly.
        // See http://developer.github.com/v3/media/.
        'Accept': mediaType
      }
    }, function(response) {
      var decompressor = zlib.createUnzip(),
          parser = new tar.Extract({ 'path': path });

      decompressor.on('error', callback)
      parser.on('end', callback).on('error', callback);
      response.pipe(decompressor).pipe(parser);
    })
    .on('error', callback);
  }

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

  exec('npm -g root', function(exception, stdout) {
    if (exception) {
      console.error([
        'There was a problem loading the npm registry. If you’re installing the Lo-Dash',
        'command-line executable (via `npm install -g lodash`), you’ll need to manually',
        'install UglifyJS and the Closure Compiler by running:',
        '',
        "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
        "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId  + " | tar xvz -C '" + vendorPath + "'",
        '',
        'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url + '.'
      ].join('\n'));
      console.error(exception);
      process.exit();
    }
    // exit early if not a global install
    if (path.resolve(basePath, '..') != fs.realpathSync(stdout.trim())) {
      return;
    }
    // download the Closure Compiler
    getDependency({
      'title': 'the Closure Compiler',
      'id': closureId,
      'path': vendorPath,
      'onComplete': function() {
        // download UglifyJS
        getDependency({
          'title': 'UglifyJS',
          'id': uglifyId,
          'path': vendorPath,
          'onComplete': function() {
            process.exit();
          }
        });
      }
    });
  });
}());
<commit_msg>Fallback to the local `npm` install if there are problems resolving the `npm -g root` path. [closes #122]<commit_after>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node modules */
  var exec = require('child_process').exec,
      fs = require('fs'),
      https = require('https'),
      path = require('path'),
      tar = require('../vendor/tar/tar.js'),
      zlib = require('zlib');

  /** The path of the directory that is the base of the repository */
  var basePath = fs.realpathSync(path.join(__dirname, '..'));

  /** The path of the `vendor` directory */
  var vendorPath = path.join(basePath, 'vendor');

  /** The Git object ID of `closure-compiler.tar.gz` */
  var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';

  /** The Git object ID of `uglifyjs.tar.gz` */
  var uglifyId = '3390b259e04829538e4d3635d12b317dd6103eca';

  /** The media type for raw blob data */
  var mediaType = 'application/vnd.github.v3.raw';

  /** Used to reference parts of the blob href */
  var location = (function() {
    var host = 'api.github.com',
        origin = 'https://api.github.com',
        pathname = '/repos/bestiejs/lodash/git/blobs';

    return {
      'host': host,
      'href': host + origin + pathname,
      'origin': origin,
      'pathname': pathname
    };
  }());

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

  /**
   * Fetches a required `.tar.gz` dependency with the given Git object ID from
   * the Lo-Dash repo on GitHub. The object ID may be obtained by running
   * `git hash-object path/to/dependency.tar.gz`.
   *
   * @private
   * @param {Object} options The options object.
   *  id - The Git object ID of the `.tar.gz` file.
   *  onComplete - The function, invoked with one argument (exception),
   *   called once the extraction has finished.
   *  path - The path of the extraction directory.
   *  title - The dependency's title used in status updates logged to the console.
   */
  function getDependency(options) {
    options || (options = {});

    var id = options.id,
        onComplete = options.onComplete,
        path = options.path,
        title = options.title;

    function callback(exception) {
      if (exception) {
        console.error([
          'There was a problem installing ' + title + '. To manually install, run:',
          '',
          "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
        ].join('\n'));
      }
      onComplete(exception);
    }

    console.log('Downloading ' + title + '...');

    https.get({
      'host': location.host,
      'path': location.pathname + '/' + id,
      'headers': {
        // By default, all GitHub blob API endpoints return a JSON document
        // containing Base64-encoded blob data. Overriding the `Accept` header
        // with the GitHub raw media type returns the blob data directly.
        // See http://developer.github.com/v3/media/.
        'Accept': mediaType
      }
    }, function(response) {
      var decompressor = zlib.createUnzip(),
          parser = new tar.Extract({ 'path': path });

      decompressor.on('error', callback)
      parser.on('end', callback).on('error', callback);
      response.pipe(decompressor).pipe(parser);
    })
    .on('error', callback);
  }

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

  exec('npm -g root', function(exception, stdout) {
    if (!exception) {
      try {
        var isGlobal = path.resolve(basePath, '..') == fs.realpathSync(stdout.trim());
      } catch(e) {
        exception = e;
      }
    }
    if (exception) {
      console.error([
        'Oops! There was a problem detecting the install mode. If you’re installing the',
        'Lo-Dash command-line executable (via `npm install -g lodash`), you’ll need to',
        'manually install UglifyJS and the Closure Compiler by running:',
        '',
        "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
        "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId  + " | tar xvz -C '" + vendorPath + "'",
        '',
        'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
      ].join('\n'));

      console.error(exception);
    }
    if (!isGlobal) {
      return;
    }
    // download the Closure Compiler
    getDependency({
      'title': 'the Closure Compiler',
      'id': closureId,
      'path': vendorPath,
      'onComplete': function() {
        // download UglifyJS
        getDependency({
          'title': 'UglifyJS',
          'id': uglifyId,
          'path': vendorPath,
          'onComplete': function() {
            process.exit();
          }
        });
      }
    });
  });
}());
<|endoftext|>


<commit_before>import * as I from 'infestines'
import * as R from 'ramda'

export function lazy(ty2ty) {
  let memo = x => {
    memo = ty2ty(rec)
    return memo(x)
  }
  const rec = x => memo(x)
  return rec
}

export const any = I.id

export const and = R.pipe

export const or = (...ps) => x => {
  const es = [],
    n = ps.length
  for (let i = 0; i < n; ++i) {
    try {
      return ps[i](x)
    } catch (e) {
      es.push([ps[i], e])
    }
  }
  throw Error(`or(${ps}): ${x}`)
}

export const fromPredicate = p => x => {
  if (p(x)) return x
  throw Error(`fromPredicate(${p}): ${x}`)
}

const type = t => fromPredicate(x => typeof x === t)
export const instanceOf = c => fromPredicate(x => x instanceof c)

const isFreezable = x => I.isArray(x) || I.isObject(x)
const isFrozen = x => !isFreezable(x) || Object.isFrozen(x)
const isDeepFrozen = x =>
  !isFreezable(x) ||
  (Object.isFrozen(x) &&
    !Object.getOwnPropertyNames(x).find(x => !isDeepFrozen(x)))

export const frozen = fromPredicate(isFrozen)

export const deepFrozen = fromPredicate(isDeepFrozen)

export const deepFreeze = x =>
  isFrozen(x)
    ? x
    : (Object.getOwnPropertyNames(x).forEach(k => deepFreeze(x[k])),
      Object.freeze(x))

export const integer = fromPredicate(Number.isInteger)
export const nonNegative = and(integer, fromPredicate(x => 0 <= x))

export const boolean = type('boolean')
export const number = type('number')
export const string = type('string')
export const undef = fromPredicate(x => x === undefined)
export const def = fromPredicate(x => x !== undefined)

export const array = ty => and(instanceOf(Array), R.map(ty))

export const arity = n => fromPredicate(x => x.length === n)

export const props = R.map

const isThenable = x => null != x && I.isFunction(x.then)

export const maybeThenable = t => v => (isThenable(v) ? v.then(t) : t(v))

export const thenable = t => v => {
  if (!isThenable(v)) throw Error(`Expected thenable, but got ${v}`)
  return v.then(t)
}

export const object = template => object => {
  const result = {}
  if (!I.isObject(object)) throw Error(`Expected object, got ${object}`)
  if (!I.hasKeysOfU(template, object))
    throw Error(
      `Expected object with keys ${I.keys(template)}, got ${I.keys(object)}`
    )
  for (const k in template) result[k] = template[k](object[k])
  return result
}

export function fn(argTys, resultTy) {
  if (!(argTys instanceof Array))
    throw Error(`fn arg types must be an array, given ${argTys}`)
  return fn => {
    if (!I.isFunction(fn)) throw Error(`Expected function, got ${fn}`)
    if (argTys.length < fn.length)
      throw Error(`Expected arity ${argTys.length}, but got ${fn.length}`)
    return I.arityN(argTys.length, (...argIns) => {
      const n = argIns.length,
        args = Array(n)
      for (let i = 0; i < n; ++i) args[i] = argTys[i](argIns[i])
      return resultTy(fn.apply(this, args))
    })
  }
}

export const fnVarN = (minArity, argsTy, resultTy) => fn => {
  if (!I.isFunction(fn)) throw Error(`Expected function, got ${fn}`)
  return R.curryN(minArity, (...argIns) => {
    const n = argIns.length,
      args = Array(n)
    for (let i = 0; i < n; ++i) args[i] = argsTy(argIns[i])
    return resultTy(fn.apply(this, args))
  })
}
<commit_msg>Fix to check property values<commit_after>import * as I from 'infestines'
import * as R from 'ramda'

export function lazy(ty2ty) {
  let memo = x => {
    memo = ty2ty(rec)
    return memo(x)
  }
  const rec = x => memo(x)
  return rec
}

export const any = I.id

export const and = R.pipe

export const or = (...ps) => x => {
  const es = [],
    n = ps.length
  for (let i = 0; i < n; ++i) {
    try {
      return ps[i](x)
    } catch (e) {
      es.push([ps[i], e])
    }
  }
  throw Error(`or(${ps}): ${x}`)
}

export const fromPredicate = p => x => {
  if (p(x)) return x
  throw Error(`fromPredicate(${p}): ${x}`)
}

const type = t => fromPredicate(x => typeof x === t)
export const instanceOf = c => fromPredicate(x => x instanceof c)

const isFreezable = x => I.isArray(x) || I.isObject(x)
const isFrozen = x => !isFreezable(x) || Object.isFrozen(x)
const isDeepFrozen = x =>
  !isFreezable(x) ||
  (Object.isFrozen(x) &&
    !Object.getOwnPropertyNames(x).find(k => !isDeepFrozen(x[k])))

export const frozen = fromPredicate(isFrozen)

export const deepFrozen = fromPredicate(isDeepFrozen)

export const deepFreeze = x =>
  isFrozen(x)
    ? x
    : (Object.getOwnPropertyNames(x).forEach(k => deepFreeze(x[k])),
      Object.freeze(x))

export const integer = fromPredicate(Number.isInteger)
export const nonNegative = and(integer, fromPredicate(x => 0 <= x))

export const boolean = type('boolean')
export const number = type('number')
export const string = type('string')
export const undef = fromPredicate(x => x === undefined)
export const def = fromPredicate(x => x !== undefined)

export const array = ty => and(instanceOf(Array), R.map(ty))

export const arity = n => fromPredicate(x => x.length === n)

export const props = R.map

const isThenable = x => null != x && I.isFunction(x.then)

export const maybeThenable = t => v => (isThenable(v) ? v.then(t) : t(v))

export const thenable = t => v => {
  if (!isThenable(v)) throw Error(`Expected thenable, but got ${v}`)
  return v.then(t)
}

export const object = template => object => {
  const result = {}
  if (!I.isObject(object)) throw Error(`Expected object, got ${object}`)
  if (!I.hasKeysOfU(template, object))
    throw Error(
      `Expected object with keys ${I.keys(template)}, got ${I.keys(object)}`
    )
  for (const k in template) result[k] = template[k](object[k])
  return result
}

export function fn(argTys, resultTy) {
  if (!(argTys instanceof Array))
    throw Error(`fn arg types must be an array, given ${argTys}`)
  return fn => {
    if (!I.isFunction(fn)) throw Error(`Expected function, got ${fn}`)
    if (argTys.length < fn.length)
      throw Error(`Expected arity ${argTys.length}, but got ${fn.length}`)
    return I.arityN(argTys.length, (...argIns) => {
      const n = argIns.length,
        args = Array(n)
      for (let i = 0; i < n; ++i) args[i] = argTys[i](argIns[i])
      return resultTy(fn.apply(this, args))
    })
  }
}

export const fnVarN = (minArity, argsTy, resultTy) => fn => {
  if (!I.isFunction(fn)) throw Error(`Expected function, got ${fn}`)
  return R.curryN(minArity, (...argIns) => {
    const n = argIns.length,
      args = Array(n)
    for (let i = 0; i < n; ++i) args[i] = argsTy(argIns[i])
    return resultTy(fn.apply(this, args))
  })
}
<|endoftext|>


<commit_before>;(function() {
    // 화면 상단의 해시태그에 링크를 걸어준다.
    var tags = document.querySelectorAll('.post-tag');
    if(tags == null || tags.length < 1) {
        return;
    }

    for (var i = 0; i < tags.length; i++) {
        var item = tags[i];
        var tagList = item.innerHTML.trim();

        if(/^\s*$/.test(tagList)) {
            continue;
        }
        tagList = tagList.split(/\s+/)
            .map(function(tag) {
                return `<a href="/tag/#${tag}">#${tag}</a>`;
            })
            .join(' ');
        tags[i].innerHTML = tagList;
    }
    return;
})();
;(function() {
    // 본문 전체의 vimwiki 링크를 html 링크로 변환한다.
    var post = document.querySelector('article.post-content');

    if(post == null) {
        return;
    }

    (function iterate_node(node) {

        if (/^(?:p|ul|h\d|table)$/i.test(node.tagName)) {

            node.innerHTML = link(node.innerHTML);

        } else { // Node.ELEMENT_NODE
            for (var i = 0; i < node.childNodes.length; i++) {
                iterate_node(node.childNodes[i]);
            }
        }
    })(post);

    function link(content) {
        // (주석처리) "\[[escape]]" 와 같이 앞에 "\"가 있다면 "\[\[escape\]\]" 로 바꾸기만 하고 링크는 생성하지 않는다.
        //                            \[[      ]]
        content = content.replace(/\\\[\[(.+?)\]\]/g, '\\[\\[$1\\]\\]');

        // (태그, 타이틀 처리) "[[#tagName#]]{text}"를 text 로 replace하여 링크를 만든다.
        //                           [[#           #]]      {            }
        content = content.replace(/\[\[#([^\[\]]+?)#\s*\]\]\{([^\{\}]+?)\}/g,
            '$2');

        // (태그 처리) "[[#tagName#]]"을 tagName 로 replace하여 링크를 만든다.
        //                           [[#           #]]      {            }
        content = content.replace(/\[\[#([^\[\]]+?)#\s*\]\]/g,
            '$1');

        // (추가 타이틀 처리) 다음과 같은 문자열을 document-name 으로 replace하여 링크를 만든다.
        //  [[document]]{document-name}       => document-name
        //  [[/document]]{document-name}      => document-name
        //  [[/dir/document]]{document-name}  => document-name
        content = content.replace(/\[\[\/?([^\[\]]+?)\s*\]\]\{([^\{\}]+?)\}/g,
            '$2');

        // "[[document]]"가 있다면 document 와 같이 replace하여 링크를 만든다.
        //  예제는 (추가 타이틀 처리)와 거의 비슷하다.
        content = content.replace(/\[\[\/?(.+?)\s*\]\]/g,
            '$1');

        // (주석처리)에서 이스케이프한 문자열을 본래 표현하려 한 형식으로 되돌린다.
        content = content.replace(/\\\[\\\[(.+?)\\\]\\\]/g, '[[$1]]');

        return content;
    }

})();

;(function() {
    // 파일 이름이 링크 텍스트로 드러난 것을 문서의 타이틀로 교체해준다.
    const list = document.querySelectorAll('.no-labeled-link');

    for (var i = 0; i < list.length; i++) {
        insertTitle(i, list);
    }
    /**
     * 타이틀이 누락된 문서의 타이틀을 가져와 입력해 줍니다.
     */
    function insertTitle(index, list) {
        const item = list[index];
        if (item == undefined) {
            return;
        }
        const target = item.getAttribute('data-name')
            .replace(/#.*$/, '');

        let status = undefined;
        fetch(`/data/metadata/${target}.json`)
            .then(response => {
                status = response.status;
                return response.json()
            })
            .then(function(data) {
                if (data == null) {
                    return;
                }
                item.innerText = data.title;
                return;
            })
            .catch(function(error) {
                item.classList.add('broken-link');
                item.innerHTML += `<sub class="link-${status}"></sub>`
                console.log(target, status);
            });
    }
})();

;(function() {
    // 외부 링크에 표시를 달아준다.
    const links = document.links;

    for (let i = 0; i < links.length; i++) {
        const link = links[i];
        const url = link.getAttribute('href');
        if (/^(https?:\/\/)?johngrib\.github\.io/.test(url) || /^[\/#]/.test(url)) {
            // inner link
        } else {
            // external link
            link.classList.add('external-link')
        }

    }
})();

;(function footnoteToolTip() {
    // 주석에 툴팁을 붙인다
    const noteList = document.querySelectorAll('.footnote');

    for (let i = 0; i < noteList.length; i++) {
        const note = noteList[i];
        const id = note.getAttribute('href')
            .replace(/^#/, "");
        const text = document.getElementById(id).innerText
            .replace(/ ↩.*$/, "");
        note.setAttribute('title', text);
    }
})();
<commit_msg>잘못된 주석 교정<commit_after>;(function() {
    // 화면 상단의 해시태그에 링크를 걸어준다.
    var tags = document.querySelectorAll('.post-tag');
    if(tags == null || tags.length < 1) {
        return;
    }

    for (var i = 0; i < tags.length; i++) {
        var item = tags[i];
        var tagList = item.innerHTML.trim();

        if(/^\s*$/.test(tagList)) {
            continue;
        }
        tagList = tagList.split(/\s+/)
            .map(function(tag) {
                return `<a href="/tag/#${tag}">#${tag}</a>`;
            })
            .join(' ');
        tags[i].innerHTML = tagList;
    }
    return;
})();
;(function() {
    // 본문 전체의 vimwiki 링크를 html 링크로 변환한다.
    var post = document.querySelector('article.post-content');

    if(post == null) {
        return;
    }

    (function iterate_node(node) {

        if (/^(?:p|ul|h\d|table)$/i.test(node.tagName)) {

            node.innerHTML = link(node.innerHTML);

        } else { // Node.ELEMENT_NODE
            for (var i = 0; i < node.childNodes.length; i++) {
                iterate_node(node.childNodes[i]);
            }
        }
    })(post);

    function link(content) {
        // (주석처리) "\[[escape]]" 와 같이 앞에 "\"가 있다면 "\[\[escape\]\]" 로 바꾸기만 하고 링크는 생성하지 않는다.
        //                            \[[      ]]
        content = content.replace(/\\\[\[(.+?)\]\]/g, '\\[\\[$1\\]\\]');

        // (태그, 타이틀 처리) "[[#tagName#]]{text}"를 text 로 replace하여 링크를 만든다.
        //                           [[#           #]]      {            }
        content = content.replace(/\[\[#([^\[\]]+?)#\s*\]\]\{([^\{\}]+?)\}/g,
            '$2');

        // (태그 처리) "[[#tagName#]]"을 tagName 로 replace하여 링크를 만든다.
        //                           [[#           #]]
        content = content.replace(/\[\[#([^\[\]]+?)#\s*\]\]/g,
            '$1');

        // (추가 타이틀 처리) 다음과 같은 문자열을 document-name 으로 replace하여 링크를 만든다.
        //  [[document]]{document-name}       => document-name
        //  [[/document]]{document-name}      => document-name
        //  [[/dir/document]]{document-name}  => document-name
        content = content.replace(/\[\[\/?([^\[\]]+?)\s*\]\]\{([^\{\}]+?)\}/g,
            '$2');

        // "[[document]]"가 있다면 document 와 같이 replace하여 링크를 만든다.
        //  예제는 (추가 타이틀 처리)와 거의 비슷하다.
        content = content.replace(/\[\[\/?(.+?)\s*\]\]/g,
            '$1');

        // (주석처리)에서 이스케이프한 문자열을 본래 표현하려 한 형식으로 되돌린다.
        content = content.replace(/\\\[\\\[(.+?)\\\]\\\]/g, '[[$1]]');

        return content;
    }

})();

;(function() {
    // 파일 이름이 링크 텍스트로 드러난 것을 문서의 타이틀로 교체해준다.
    const list = document.querySelectorAll('.no-labeled-link');

    for (var i = 0; i < list.length; i++) {
        insertTitle(i, list);
    }
    /**
     * 타이틀이 누락된 문서의 타이틀을 가져와 입력해 줍니다.
     */
    function insertTitle(index, list) {
        const item = list[index];
        if (item == undefined) {
            return;
        }
        const target = item.getAttribute('data-name')
            .replace(/#.*$/, '');

        let status = undefined;
        fetch(`/data/metadata/${target}.json`)
            .then(response => {
                status = response.status;
                return response.json()
            })
            .then(function(data) {
                if (data == null) {
                    return;
                }
                item.innerText = data.title;
                return;
            })
            .catch(function(error) {
                item.classList.add('broken-link');
                item.innerHTML += `<sub class="link-${status}"></sub>`
                console.log(target, status);
            });
    }
})();

;(function() {
    // 외부 링크에 표시를 달아준다.
    const links = document.links;

    for (let i = 0; i < links.length; i++) {
        const link = links[i];
        const url = link.getAttribute('href');
        if (/^(https?:\/\/)?johngrib\.github\.io/.test(url) || /^[\/#]/.test(url)) {
            // inner link
        } else {
            // external link
            link.classList.add('external-link')
        }

    }
})();

;(function footnoteToolTip() {
    // 주석에 툴팁을 붙인다
    const noteList = document.querySelectorAll('.footnote');

    for (let i = 0; i < noteList.length; i++) {
        const note = noteList[i];
        const id = note.getAttribute('href')
            .replace(/^#/, "");
        const text = document.getElementById(id).innerText
            .replace(/ ↩.*$/, "");
        note.setAttribute('title', text);
    }
})();
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   Ember Handlebar Views
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

var button, application;

var get = Ember.get, set = Ember.set;

module("Ember.Button", {
  setup: function() {
    application = Ember.Application.create();
    button = Ember.Button.create();
  },

  teardown: function() {
    button.destroy();
    application.destroy();
  }
});

function synthesizeEvent(type, view) {
  view.$().trigger(type);
}

function append() {
  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });
}

test("should become disabled if the disabled attribute is true", function() {
  button.set('disabled', true);
  append();

  ok(button.$().is(":disabled"));
});

test("should become disabled if the disabled attribute is true", function() {
  append();
  ok(button.$().is(":not(:disabled)"));

  Ember.run(function() { button.set('disabled', true); });
  ok(button.$().is(":disabled"));

  Ember.run(function() { button.set('disabled', false); });
  ok(button.$().is(":not(:disabled)"));
});

test("should trigger an action when clicked", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('click', button);

  ok(wasClicked);
});

test("should trigger an action on a String target when clicked", function() {
  var wasClicked = false;

  window.MyApp = {
    myActionObject: Ember.Object.create({
      myAction: function() {
        wasClicked = true;
      }
    })
  };

  var button = Ember.Button.create({
    target: 'MyApp.myActionObject',
    action: 'myAction'
  });

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('click', button);

  ok(wasClicked);

  window.MyApp = undefined;
});

test("should not trigger action if mouse leaves area before mouseup", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('mousedown', button);
  ok(get(button, 'isActive'), "becomes active when hovered");
  ok(button.$().hasClass('is-active'));
  synthesizeEvent('mouseleave', button);
  ok(!get(button, 'isActive'), "loses active state if mouse exits");
  ok(!button.$().hasClass('is-active'));
  synthesizeEvent('mouseup', button);

  ok(!wasClicked);

  wasClicked = false;

  synthesizeEvent('mousedown', button);
  synthesizeEvent('mouseleave', button);
  synthesizeEvent('mouseenter', button);
  synthesizeEvent('mouseup', button);
  synthesizeEvent('click', button);

  ok(wasClicked);
});

test("should not trigger action if disabled and a non-standard input", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('tagName', 'span');
  button.set('disabled', true);
  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('mousedown', button);
  ok(!get(button, 'isActive'), "button does not become active when pushed");
});

test("should by default be of type='button'", function() {
  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  equals(button.$().attr('type'), 'button');
});

test("should have a configurable type", function() {
  button.set('type', 'submit');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  equals(button.$().attr('type'), 'submit');
});

test("should allow the target to be the parentView", function() {
  button.set('target', 'parentView');

  equals(get(button, 'parentView'), button.get('targetObject'));
});
<commit_msg>Fixed more duplicate test names<commit_after>// ==========================================================================
// Project:   Ember Handlebar Views
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

var button, application;

var get = Ember.get, set = Ember.set;

module("Ember.Button", {
  setup: function() {
    application = Ember.Application.create();
    button = Ember.Button.create();
  },

  teardown: function() {
    button.destroy();
    application.destroy();
  }
});

function synthesizeEvent(type, view) {
  view.$().trigger(type);
}

function append() {
  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });
}

test("should begin disabled if the disabled attribute is true", function() {
  button.set('disabled', true);
  append();

  ok(button.$().is(":disabled"));
});

test("should become disabled if the disabled attribute is changed", function() {
  append();
  ok(button.$().is(":not(:disabled)"));

  Ember.run(function() { button.set('disabled', true); });
  ok(button.$().is(":disabled"));

  Ember.run(function() { button.set('disabled', false); });
  ok(button.$().is(":not(:disabled)"));
});

test("should trigger an action when clicked", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('click', button);

  ok(wasClicked);
});

test("should trigger an action on a String target when clicked", function() {
  var wasClicked = false;

  window.MyApp = {
    myActionObject: Ember.Object.create({
      myAction: function() {
        wasClicked = true;
      }
    })
  };

  var button = Ember.Button.create({
    target: 'MyApp.myActionObject',
    action: 'myAction'
  });

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('click', button);

  ok(wasClicked);

  window.MyApp = undefined;
});

test("should not trigger action if mouse leaves area before mouseup", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('mousedown', button);
  ok(get(button, 'isActive'), "becomes active when hovered");
  ok(button.$().hasClass('is-active'));
  synthesizeEvent('mouseleave', button);
  ok(!get(button, 'isActive'), "loses active state if mouse exits");
  ok(!button.$().hasClass('is-active'));
  synthesizeEvent('mouseup', button);

  ok(!wasClicked);

  wasClicked = false;

  synthesizeEvent('mousedown', button);
  synthesizeEvent('mouseleave', button);
  synthesizeEvent('mouseenter', button);
  synthesizeEvent('mouseup', button);
  synthesizeEvent('click', button);

  ok(wasClicked);
});

test("should not trigger action if disabled and a non-standard input", function() {
  var wasClicked = false;

  var actionObject = Ember.Object.create({
    myAction: function() {
      wasClicked = true;
    }
  });

  button.set('tagName', 'span');
  button.set('disabled', true);
  button.set('target', actionObject);
  button.set('action', 'myAction');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  synthesizeEvent('mousedown', button);
  ok(!get(button, 'isActive'), "button does not become active when pushed");
});

test("should by default be of type='button'", function() {
  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  equals(button.$().attr('type'), 'button');
});

test("should have a configurable type", function() {
  button.set('type', 'submit');

  Ember.run(function() {
    button.appendTo('#qunit-fixture');
  });

  equals(button.$().attr('type'), 'submit');
});

test("should allow the target to be the parentView", function() {
  button.set('target', 'parentView');

  equals(get(button, 'parentView'), button.get('targetObject'));
});
<|endoftext|>


<commit_before>'use babel';
'use strict';

import Character from './character';
import ModRolesDatabase from './mod-roles';
import storage from './local-storage';
import search from '../util/search';
import logger from '../util/logger';

export default class CharacterDatabase {
	static loadDatabase() {
		this.serversMap = JSON.parse(storage.getItem('characters'));
		if(!this.serversMap) this.serversMap = {};
	}

	static saveDatabase() {
		logger.debug('Saving characters database...', this.serversMap);
		storage.setItem('characters', JSON.stringify(this.serversMap));
	}

	static saveCharacter(character, allowNonOwner = false) {
		if(!character) throw new Error('A character must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[character.server]) this.serversMap[character.server] = [];
		const serverCharacters = this.serversMap[character.server];

		const normalizedName = character.name.normalize('NFKD').toLowerCase();
		const characterIndex = serverCharacters.findIndex(element => element.name.normalize('NFKD').toLowerCase() === normalizedName);
		if(characterIndex >= 0) {
			if(allowNonOwner || character.owner === serverCharacters[characterIndex].owner) {
				character.owner = serverCharacters[characterIndex].owner;
				serverCharacters[characterIndex] = character;
				logger.info('Updated existing character.', character);
				this.saveDatabase();
				return 2;
			} else {
				logger.info('Not updating existing character, because the owner isn\'t the original owner.', { character: character, original: serverCharacters[characterIndex] });
				return 0;
			}
		} else {
			serverCharacters.push(character);
			logger.info('Added new character.', character);
			this.saveDatabase();
			return 1;
		}
	}

	static deleteCharacter(character, allowNonOwner = false) {
		if(!character) throw new Error('A character must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[character.server]) return false;
		const serverCharacters = this.serversMap[character.server];

		const characterIndex = serverCharacters.findIndex(element => element.name === character.name);
		if(characterIndex >= 0) {
			if(allowNonOwner || character.owner === serverCharacters[characterIndex].owner) {
				serverCharacters.splice(characterIndex, 1);
				logger.info('Removed character.', character);
			} else {
				logger.info('Not removing character, because the owner isn\'t the original owner.', { character: character, original: serverCharacters[characterIndex] });
				return false;
			}
		} else {
			logger.info('Not removing character, because it doesn\'t exist.', character);
			return false;
		}

		this.saveDatabase();
		return true;
	}

	static findCharactersInServer(server, searchString = null, searchExact = true) {
		if(!server) throw new Error('A server must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[server.id]) return [];
		let characters;

		if(search) {
			characters = search(this.serversMap[server.id], searchString, { useStartsWith: true, searchExact: searchExact });
		} else {
			characters = this.serversMap[server.id];
		}

		// Make sure they're all Character instances
		for(const [index, character] of characters.entries()) {
			if(!(character instanceof Character)) characters[index] = new Character(character.name, character.info, character.owner, character.server);
		}

		return characters;
	}

	static userCanModerateInServer(server, user) {
		if(!user) throw new Error('A user must be specified.');
		const userRoles = server.rolesOfUser(user);
		if(userRoles.some(role => role.hasPermission('administrator'))) return true;
		if(!ModRolesDatabase.serverHasRoles(server)) return userRoles.some(role => role.hasPermission('manageMessages'));
		return ModRolesDatabase.findRolesInServer(server).some(element => userRoles.some(element2 => element.id === element2.id));
	}
}
<commit_msg>Cleanup<commit_after>'use babel';
'use strict';

import Character from './character';
import ModRolesDatabase from './mod-roles';
import storage from './local-storage';
import search from '../util/search';
import logger from '../util/logger';

export default class CharacterDatabase {
	static loadDatabase() {
		this.serversMap = JSON.parse(storage.getItem('characters'));
		if(!this.serversMap) this.serversMap = {};
	}

	static saveDatabase() {
		logger.debug('Saving characters database...', this.serversMap);
		storage.setItem('characters', JSON.stringify(this.serversMap));
	}

	static saveCharacter(character, allowNonOwner = false) {
		if(!character) throw new Error('A character must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[character.server]) this.serversMap[character.server] = [];
		const serverCharacters = this.serversMap[character.server];

		const normalizedName = character.name.normalize('NFKD').toLowerCase();
		const characterIndex = serverCharacters.findIndex(element => element.name.normalize('NFKD').toLowerCase() === normalizedName);
		if(characterIndex >= 0) {
			if(allowNonOwner || character.owner === serverCharacters[characterIndex].owner) {
				character.owner = serverCharacters[characterIndex].owner;
				serverCharacters[characterIndex] = character;
				logger.info('Updated existing character.', character);
				this.saveDatabase();
				return 2;
			} else {
				logger.info('Not updating existing character, because the owner isn\'t the original owner.', { character: character, original: serverCharacters[characterIndex] });
				return 0;
			}
		} else {
			serverCharacters.push(character);
			logger.info('Added new character.', character);
			this.saveDatabase();
			return 1;
		}
	}

	static deleteCharacter(character, allowNonOwner = false) {
		if(!character) throw new Error('A character must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[character.server]) return false;
		const serverCharacters = this.serversMap[character.server];

		const characterIndex = serverCharacters.findIndex(element => element.name === character.name);
		if(characterIndex >= 0) {
			if(allowNonOwner || character.owner === serverCharacters[characterIndex].owner) {
				serverCharacters.splice(characterIndex, 1);
				logger.info('Removed character.', character);
			} else {
				logger.info('Not removing character, because the owner isn\'t the original owner.', { character: character, original: serverCharacters[characterIndex] });
				return false;
			}
		} else {
			logger.info('Not removing character, because it doesn\'t exist.', character);
			return false;
		}

		this.saveDatabase();
		return true;
	}

	static findCharactersInServer(server, searchString = null, searchExact = true) {
		if(!server) throw new Error('A server must be specified.');
		if(!this.serversMap) this.loadDatabase();
		if(!this.serversMap[server.id]) return [];

		const characters = search(this.serversMap[server.id], searchString, { useStartsWith: true, searchExact: searchExact });

		// Make sure they're all Character instances
		for(const [index, character] of characters.entries()) {
			if(!(character instanceof Character)) characters[index] = new Character(character.name, character.info, character.owner, character.server);
		}

		return characters;
	}

	static userCanModerateInServer(server, user) {
		if(!user) throw new Error('A user must be specified.');
		const userRoles = server.rolesOfUser(user);
		if(userRoles.some(role => role.hasPermission('administrator'))) return true;
		if(!ModRolesDatabase.serverHasRoles(server)) return userRoles.some(role => role.hasPermission('manageMessages'));
		return ModRolesDatabase.findRolesInServer(server).some(element => userRoles.some(element2 => element.id === element2.id));
	}
}
<|endoftext|>


<commit_before>import 'whatwg-fetch';
import {
  DATASET_LIST_RECEIVED,
  DATASET_LIST_RESET,
  DATASET_FETCH_ERROR,
  // DATASET_LAYER_FETCH_ERROR,
  DATASET_WIDGET_RECEIVED,
  DATASET_DETAIL_RECEIVED,
  DATASET_METADATA_RECEIVED,
  DATASET_LAYER_RECEIVED,
  DATASET_SET_FILTER
} from '../constants';

import { updateURL } from './links';

export function getDatasetLayer(dataset) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/layers/${dataset.layers[0].layer_id}`)
      .then(response => {
        if (!response.ok) {
          throw new Error(response.statusText);
        }
        return response.json();
      })
      .then(data => {
        dispatch({
          type: DATASET_LAYER_RECEIVED,
          payload: data
        });
        dispatch(updateURL());
      });
    /**
     *  Error is always thrown, because the dataset load is async and the instruction
     *  dataset.setOpacity is evaluated before dataset is loaded. This means that the instruction
     *  is evaluated as undefined.setOpacity. However, when the dataset is indeed loaded the layer
     *  renders just fine.
     */
    /*
    .catch((err) => {
     dispatch({
     type: DATASET_LAYER_FETCH_ERROR,
     payload: {
     id: dataset.id,
     error: err
     }
     });

     });
     */
  };
}

export function getActiveDatasetLayers(datasets) {
  return dispatch => {
    for (let i = 0, dsLength = datasets.length; i < dsLength; i++) {
      if (datasets[i].active) {
        dispatch(getDatasetLayer(datasets[i]));
      }
    }
  };
}

export function setDatasetsTagFilter(filter, tag) {
  return {
    type: DATASET_SET_FILTER,
    payload: { filter, tag }
  };
}

export function getDatasets(defaultActiveLayers) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/datasets?app=prep&includes=metadata`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        const datasets = data || [];
        if (datasets.length) {
          for (let i = datasets.length - 1; i > 0; i--) {
            if (defaultActiveLayers) {
              const index = defaultActiveLayers.indexOf(datasets[i].id);
              if (index > -1) {
                datasets[i].active = true;
                datasets[i].index = index + 1;
                datasets[i].opacity = 1;
              }
            }
          }
        }
        dispatch({
          type: DATASET_LIST_RECEIVED,
          payload: {
            data: datasets
          }
        });
        dispatch(getActiveDatasetLayers(datasets));
        dispatch({
          type: DATASET_SET_FILTER,
          payload: {}
        });
        dispatch(updateURL());
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}
export function resetDatasetList() {
  return {
    type: DATASET_LIST_RESET
  };
}

export function getDatasetById(datasetId, includesData) {
  const includes = includesData || [];
  const includeQuery = includes.length > 0 ?
    `&includes=${includes.join(',')}` :
    '';

  return dispatch => {
    fetch(`${config.apiUrlRW}/datasets/${datasetId}?app=prep${includeQuery}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data) {
          dispatch({
            type: DATASET_DETAIL_RECEIVED,
            payload: { data }
          });
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}

export function getDatasetDefaultWidget(datasetId) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/widgets?app=prep&default=true&dataset=${datasetId}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data.data.length) {
          for (let i = 0, wLength = data.data.length; i < wLength; i++) {
            fetch(`${config.apiUrlRW}/widgets/${data.data[i].id}`)
              .then(response => {
                if (response.ok) return response.json();
                throw new Error(response.statusText);
              })
              .then(widget => {
                dispatch({
                  type: DATASET_WIDGET_RECEIVED,
                  payload: { data: widget.data }
                });
              });
          }
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}

export function getDatasetMetadata(datasetId) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/metadata/${datasetId}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data.data[0]) {
          dispatch({
            type: DATASET_METADATA_RECEIVED,
            payload: data.data[0]
          });
        } else {
          dispatch({
            type: DATASET_METADATA_RECEIVED,
            payload: {
              id: datasetId,
              attributes: {
                dataset: datasetId,
                info: {
                  attributes: {
                    title: 'Dataset detail',
                    message: 'There is not metadata for this dataset'
                  }
                }
              }
            }
          });
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}
<commit_msg>fix issue where the 1st dataset could not be loaded as a default dataset layer<commit_after>import 'whatwg-fetch';
import {
  DATASET_LIST_RECEIVED,
  DATASET_LIST_RESET,
  DATASET_FETCH_ERROR,
  // DATASET_LAYER_FETCH_ERROR,
  DATASET_WIDGET_RECEIVED,
  DATASET_DETAIL_RECEIVED,
  DATASET_METADATA_RECEIVED,
  DATASET_LAYER_RECEIVED,
  DATASET_SET_FILTER
} from '../constants';

import { updateURL } from './links';

export function getDatasetLayer(dataset) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/layers/${dataset.layers[0].layer_id}`)
      .then(response => {
        if (!response.ok) {
          throw new Error(response.statusText);
        }
        return response.json();
      })
      .then(data => {
        dispatch({
          type: DATASET_LAYER_RECEIVED,
          payload: data
        });
      });
    /**
     *  Error is always thrown, because the dataset load is async and the instruction
     *  dataset.setOpacity is evaluated before dataset is loaded. This means that the instruction
     *  is evaluated as undefined.setOpacity. However, when the dataset is indeed loaded the layer
     *  renders just fine.
     */
    /*
    .catch((err) => {
     dispatch({
     type: DATASET_LAYER_FETCH_ERROR,
     payload: {
     id: dataset.id,
     error: err
     }
     });

     });
     */
  };
}

export function getActiveDatasetLayers(datasets) {
  return dispatch => {
    for (let i = 0, dsLength = datasets.length; i < dsLength; i++) {
      if (datasets[i].active) {
        dispatch(getDatasetLayer(datasets[i]));
      }
    }
  };
}

export function setDatasetsTagFilter(filter, tag) {
  return {
    type: DATASET_SET_FILTER,
    payload: { filter, tag }
  };
}

export function getDatasets(defaultActiveLayers) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/datasets?app=prep&includes=metadata`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        const datasets = data || [];
        if (datasets.length) {
          for (let i = datasets.length - 1; i >= 0; i--) {
            if (defaultActiveLayers) {
              const index = defaultActiveLayers.indexOf(datasets[i].id);
              if (index > -1) {
                datasets[i].active = true;
                datasets[i].index = index + 1;
                datasets[i].opacity = 1;
              }
            }
          }
        }
        dispatch({
          type: DATASET_LIST_RECEIVED,
          payload: {
            data: datasets
          }
        });
        dispatch(getActiveDatasetLayers(datasets));
        dispatch({
          type: DATASET_SET_FILTER,
          payload: {}
        });
        dispatch(updateURL());
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}
export function resetDatasetList() {
  return {
    type: DATASET_LIST_RESET
  };
}

export function getDatasetById(datasetId, includesData) {
  const includes = includesData || [];
  const includeQuery = includes.length > 0 ?
    `&includes=${includes.join(',')}` :
    '';

  return dispatch => {
    fetch(`${config.apiUrlRW}/datasets/${datasetId}?app=prep${includeQuery}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data) {
          dispatch({
            type: DATASET_DETAIL_RECEIVED,
            payload: { data }
          });
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}

export function getDatasetDefaultWidget(datasetId) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/widgets?app=prep&default=true&dataset=${datasetId}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data.data.length) {
          for (let i = 0, wLength = data.data.length; i < wLength; i++) {
            fetch(`${config.apiUrlRW}/widgets/${data.data[i].id}`)
              .then(response => {
                if (response.ok) return response.json();
                throw new Error(response.statusText);
              })
              .then(widget => {
                dispatch({
                  type: DATASET_WIDGET_RECEIVED,
                  payload: { data: widget.data }
                });
              });
          }
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}

export function getDatasetMetadata(datasetId) {
  return dispatch => {
    fetch(`${config.apiUrlRW}/metadata/${datasetId}`)
      .then(response => {
        if (response.ok) return response.json();
        throw new Error(response.statusText);
      })
      .then(data => {
        if (data.data[0]) {
          dispatch({
            type: DATASET_METADATA_RECEIVED,
            payload: data.data[0]
          });
        } else {
          dispatch({
            type: DATASET_METADATA_RECEIVED,
            payload: {
              id: datasetId,
              attributes: {
                dataset: datasetId,
                info: {
                  attributes: {
                    title: 'Dataset detail',
                    message: 'There is not metadata for this dataset'
                  }
                }
              }
            }
          });
        }
      })
      .catch((err) => {
        dispatch({
          type: DATASET_FETCH_ERROR,
          payload: err.message
        });
      });
  };
}
<|endoftext|>


<commit_before>const
  type = process.argv[2],
  { createFolder } = require('./build.utils')

/*
  Build:
  * all: npm run build
  * js:  npm run build js
  * css: npm run build css
 */

console.log()

if (!type) {
  require('./script.clean.js')
}

console.log(` 📦 Building Quasar v${require('../package.json').version}...\n`)

createFolder('dist')
createFolder('dist/umd')

if (!type || type === 'js') {
  createFolder('dist/helper-json')
  createFolder('dist/babel-transforms')
  require('./script.build.javascript')
}
if (!type || type === 'css') {
  require('./script.build.stylus')
}
<commit_msg>chore: Multi thread build of Quasar<commit_after>process.env.NODE_ENV = 'production'

const
  type = process.argv[2],
  parallel = !type && require('os').cpus().length > 1,
  { join } = require('path'),
  { createFolder } = require('./build.utils'),
  runJob = parallel ? require('child_process').fork : require,
  { green, blue } = require('chalk')

/*
  Build:
  * all: npm run build
  * js:  npm run build js
  * css: npm run build css
 */

console.log()

if (!type) {
  require('./script.clean.js')
}

console.log(` 📦 Building Quasar ${green('v' + require('../package.json').version)}...${parallel ? blue(' [multi-threaded]') : ''}\n`)

createFolder('dist')
createFolder('dist/umd')

if (!type || type === 'js') {
  createFolder('dist/helper-json')
  createFolder('dist/babel-transforms')
  runJob(join(__dirname, './script.build.javascript'))
}
if (!type || type === 'css') {
  runJob(join(__dirname, './script.build.stylus'))
}
<|endoftext|>