// Generated by CoffeeScript 1.12.7
(function() {
  var Settings, ref, root, storageArea,
    hasProp = {}.hasOwnProperty,
    slice = [].slice;

  if (window.chrome == null) {
    window.chrome = (ref = window.top) != null ? ref.chrome : void 0;
  }

  storageArea = chrome.storage.sync != null ? "sync" : "local";

  Settings = {
    debug: false,
    storage: chrome.storage[storageArea],
    cache: {},
    isLoaded: false,
    onLoadedCallbacks: [],
    init: function() {
      if (Utils.isExtensionPage() && Utils.isExtensionPage(window.top)) {
        this.cache = Utils.isBackgroundPage() ? localStorage : extend({}, localStorage);
        this.runOnLoadedCallbacks();
      }
      return chrome.storage.sync.get(null, (function(_this) {
        return function() {
          if (chrome.runtime.lastError) {
            storageArea = "local";
            _this.storage = chrome.storage[storageArea];
          }
          return chrome.storage.local.get(null, function(localItems) {
            if (chrome.runtime.lastError) {
              localItems = {};
            }
            return _this.storage.get(null, function(syncedItems) {
              var key, ref1, value;
              if (!chrome.runtime.lastError) {
                ref1 = extend(localItems, syncedItems);
                for (key in ref1) {
                  if (!hasProp.call(ref1, key)) continue;
                  value = ref1[key];
                  _this.handleUpdateFromChromeStorage(key, value);
                }
              }
              chrome.storage.onChanged.addListener(function(changes, area) {
                if (area === storageArea) {
                  return _this.propagateChangesFromChromeStorage(changes);
                }
              });
              return _this.runOnLoadedCallbacks();
            });
          });
        };
      })(this));
    },
    runOnLoadedCallbacks: function() {
      var results;
      this.log("runOnLoadedCallbacks: " + this.onLoadedCallbacks.length + " callback(s)");
      this.isLoaded = true;
      results = [];
      while (0 < this.onLoadedCallbacks.length) {
        results.push(this.onLoadedCallbacks.pop()());
      }
      return results;
    },
    onLoaded: function(callback) {
      if (this.isLoaded) {
        return callback();
      } else {
        return this.onLoadedCallbacks.push(callback);
      }
    },
    shouldSyncKey: function(key) {
      return (key in this.defaults) && (key !== "settingsVersion" && key !== "previousVersion");
    },
    propagateChangesFromChromeStorage: function(changes) {
      var change, key, results;
      results = [];
      for (key in changes) {
        if (!hasProp.call(changes, key)) continue;
        change = changes[key];
        results.push(this.handleUpdateFromChromeStorage(key, change != null ? change.newValue : void 0));
      }
      return results;
    },
    handleUpdateFromChromeStorage: function(key, value) {
      this.log("handleUpdateFromChromeStorage: " + key);
      if (this.shouldSyncKey(key)) {
        if (!(value && key in this.cache && this.cache[key] === value)) {
          if (value == null) {
            value = JSON.stringify(this.defaults[key]);
          }
          return this.set(key, JSON.parse(value), false);
        }
      }
    },
    get: function(key) {
      if (!this.isLoaded) {
        console.log("WARNING: Settings have not loaded yet; using the default value for " + key + ".");
      }
      if (key in this.cache && (this.cache[key] != null)) {
        return JSON.parse(this.cache[key]);
      } else {
        return this.defaults[key];
      }
    },
    set: function(key, value, shouldSetInSyncedStorage) {
      var setting;
      if (shouldSetInSyncedStorage == null) {
        shouldSetInSyncedStorage = true;
      }
      this.cache[key] = JSON.stringify(value);
      this.log("set: " + key + " (length=" + this.cache[key].length + ", shouldSetInSyncedStorage=" + shouldSetInSyncedStorage + ")");
      if (this.shouldSyncKey(key)) {
        if (shouldSetInSyncedStorage) {
          setting = {};
          setting[key] = this.cache[key];
          this.log("   chrome.storage." + storageArea + ".set(" + key + ")");
          this.storage.set(setting);
        }
        if (Utils.isBackgroundPage() && storageArea === "sync") {
          this.log("   chrome.storage.local.remove(" + key + ")");
          chrome.storage.local.remove(key);
        }
      }
      return this.performPostUpdateHook(key, value);
    },
    clear: function(key) {
      this.log("clear: " + key);
      return this.set(key, this.defaults[key]);
    },
    has: function(key) {
      return key in this.cache;
    },
    use: function(key, callback) {
      this.log("use: " + key + " (isLoaded=" + this.isLoaded + ")");
      return this.onLoaded((function(_this) {
        return function() {
          return callback(_this.get(key));
        };
      })(this));
    },
    postUpdateHooks: {},
    performPostUpdateHook: function(key, value) {
      var base;
      return typeof (base = this.postUpdateHooks)[key] === "function" ? base[key](value) : void 0;
    },
    nuke: function(key) {
      var ref1;
      delete localStorage[key];
      chrome.storage.local.remove(key);
      return (ref1 = chrome.storage.sync) != null ? ref1.remove(key) : void 0;
    },
    log: function() {
      var args;
      args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
      if (this.debug) {
        return console.log.apply(console, ["settings:"].concat(slice.call(args)));
      }
    },
    defaults: {
      scrollStepSize: 60,
      smoothScroll: true,
      keyMappings: "# Insert your preferred key mappings here.",
      linkHintCharacters: "sadfjklewcmpgh",
      linkHintNumbers: "0123456789",
      filterLinkHints: false,
      hideHud: false,
      userDefinedLinkHintCss: "div > .vimiumHintMarker {\n/* linkhint boxes */\nbackground: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFF785),\n  color-stop(100%,#FFC542));\nborder: 1px solid #E3BE23;\n}\n\ndiv > .vimiumHintMarker span {\n/* linkhint text */\ncolor: black;\nfont-weight: bold;\nfont-size: 12px;\n}\n\ndiv > .vimiumHintMarker > .matchingCharacter {\n}",
      exclusionRules: [
        {
          pattern: "https?://mail.google.com/*",
          passKeys: ""
        }
      ],
      previousPatterns: "prev,previous,back,older,<,\u2039,\u2190,\xab,\u226a,<<",
      nextPatterns: "next,more,newer,>,\u203a,\u2192,\xbb,\u226b,>>",
      searchUrl: "https://www.google.com/search?q=",
      searchEngines: "w: https://www.wikipedia.org/w/index.php?title=Special:Search&search=%s Wikipedia\n\n# More examples.\n#\n# (Vimium supports search completion Wikipedia, as\n# above, and for these.)\n#\n# g: https://www.google.com/search?q=%s Google\n# l: https://www.google.com/search?q=%s&btnI I'm feeling lucky...\n# y: https://www.youtube.com/results?search_query=%s Youtube\n# gm: https://www.google.com/maps?q=%s Google maps\n# b: https://www.bing.com/search?q=%s Bing\n# d: https://duckduckgo.com/?q=%s DuckDuckGo\n# az: https://www.amazon.com/s/?field-keywords=%s Amazon\n# qw: https://www.qwant.com/?q=%s Qwant",
      newTabUrl: "about:newtab",
      grabBackFocus: false,
      regexFindMode: false,
      waitForEnterForFilteredHints: false,
      settingsVersion: "",
      helpDialog_showAdvancedCommands: false,
      optionsPage_showAdvancedOptions: false,
      passNextKeyKeys: [],
      ignoreKeyboardLayout: false
    }
  };

  Settings.init();

  if (Utils.isBackgroundPage()) {
    Settings.onLoaded(function() {
      if (!Settings.get("settingsVersion")) {
        Settings.set("waitForEnterForFilteredHints", true);
      }
      Settings.set("settingsVersion", Utils.getCurrentVersion());
      return Settings.nuke("copyNonDefaultsToChromeStorage-20150717");
    });
  }

  root = typeof exports !== "undefined" && exports !== null ? exports : (window.root != null ? window.root : window.root = {});

  root.Settings = Settings;

  if (typeof exports === "undefined" || exports === null) {
    extend(window, root);
  }

}).call(this);
