<commit_before>class OptionsPage {
  constructor() {
    this.findElements()
    this.errors = {}
  }

  anyErrors() {
    return Object.keys(this.errors).length > 0
  }

  isValidRepo(repo) {
    if (repo.length < 1) {
      return true
    }
    const slashIndex = repo.indexOf('/')
    return slashIndex > 0 && slashIndex < repo.length - 1
  }

  checkFormValidity() {
    for (let i of REPO_SHORTCUTS) {
      const repo = (this[`repoInput${i}`].value || '').trim()
      if (this.isValidRepo(repo)) {
        delete this.errors[`repository${i}`]
      } else {
        this.errors[`repository${i}`] = true
        this.flashErrorMessage(`Invalid repository: #${i}`)
      }
    }

    if (this.anyErrors()) {
      this.optionsForm.classList.add('error')
    } else {
      this.optionsForm.classList.remove('error')
      this.saveOptions()
    }
  }

  findElements() {
    for (let i of REPO_SHORTCUTS) {
      this[`repoInput${i}`] = document.getElementById(`repository${i}`)
      this[`defaultBranchInput${i}`] = document.getElementById(`default-branch${i}`)
      this[`repoLogo${i}`] = document.getElementById(`repo-logo${i}`)
    }
    for (let i of USER_SHORTCUTS) {
      this[`userInput${i}`] = document.getElementById(`user${i}`)
      this[`userLogo${i}`] = document.getElementById(`user-logo${i}`)
      this[`userIsOrg${i}`] = document.getElementById(`user${i}-is-org`)
    }
    this.shortcutTipContainer = document.getElementById('shortcut-tip-container')
    this.shortcut = document.getElementById('shortcut')
    this.optionsForm = document.getElementById('options-form')
    this.notification = document.getElementById('notification')
    this.versionEl = document.getElementById('extension-version')
    this.closedIssues = document.getElementById('closed-issues')
    this.newIssue = document.getElementById('new-issue')
    this.mergedPullRequests = document.getElementById('merged-pull-requests')
    this.newPullRequest = document.getElementById('new-pull-request')
  }

  flashNotification(message, isError) {
    if (this.notificationTimer) {
      clearTimeout(this.notificationTimer)
    }
    this.notification.classList.toggle('error', isError)
    this.notification.textContent = message
    this.notification.style.display = 'block'
    this.notificationTimer = setTimeout(() => {
      this.notification.style.display = 'none'
    }, 2000)
  }

  flashSaveNotice() {
    this.flashNotification('Saved!', false)
  }

  flashErrorMessage(message) {
    this.flashNotification(message, true)
  }

  hookUpHandlers() {
    for (let i of REPO_SHORTCUTS) {
      this[`repoInput${i}`].addEventListener('keyup', e => this.onRepoKeyup(e, i))
      this[`defaultBranchInput${i}`].addEventListener('keyup', e => this.onDefaultBranchKeyup(e, i))
      this[`repoLogo${i}`].addEventListener('load', () => this.onRepoLogoLoad(i))
      this[`repoLogo${i}`].addEventListener('error', () => this.onRepoLogoError(i))
    }
    for (let i of USER_SHORTCUTS) {
      this[`userInput${i}`].addEventListener('keyup', e => this.onUserKeyup(e, i))
      this[`userLogo${i}`].addEventListener('load', () => this.onUserLogoLoad(i))
      this[`userLogo${i}`].addEventListener('error', () => this.onUserLogoError(i))
      this[`userIsOrg${i}`].addEventListener('change', () => this.checkFormValidity())
    }
    this.optionsForm.addEventListener('submit', e => this.onSubmit(e))
    this.closedIssues.addEventListener('change', () => this.checkFormValidity())
    this.newIssue.addEventListener('change', () => this.checkFormValidity())
    this.mergedPullRequests.addEventListener('change', () => this.checkFormValidity())
    this.newPullRequest.addEventListener('change', () => this.checkFormValidity())
  }

  loadRepoLogo(rawRepo, i) {
    let user = rawRepo.split('/')[0]
    if (user && user.length > 0) {
      user = encodeURIComponent(user)
      this[`repoLogo${i}`].src = `https://github.com/${user}.png?size=72`
      this[`repoLogo${i}`].alt = user
    }
  }

  loadUserLogo(rawUser, i) {
    const user = encodeURIComponent(rawUser)
    this[`userLogo${i}`].src = `https://github.com/${user}.png?size=72`
    this[`userLogo${i}`].alt = user
  }

  showBadRepoLogo(i) {
    this[`repoLogo${i}`].src = 'bad-user.png'
    this[`repoLogo${i}`].alt = ''
  }

  showBadUserLogo(i) {
    this[`userLogo${i}`].src = 'bad-user.png'
    this[`userLogo${i}`].alt = ''
  }

  showDefaultUserLogo(i) {
    this[`userLogo${i}`].src = 'unknown-user.png'
    this[`userLogo${i}`].alt = ''
  }

  showDefaultRepoLogo(i) {
    this[`repoLogo${i}`].src = 'unknown-user.png'
    this[`repoLogo${i}`].alt = ''
  }

  onDefaultBranchKeyup(event, i) {
    if (this[`defaultBranchTimer${i}`]) {
      clearTimeout(this[`defaultBranchTimer${i}`])
    }
    this[`defaultBranchTimer${i}`] = setTimeout(() => {
      this.checkFormValidity()
    }, 750)
  }

  onUserKeyup(event, i) {
    if (this[`userInput${i}Timer`]) {
      clearTimeout(this[`userInput${i}Timer`])
    }
    this[`userInput${i}Timer`] = setTimeout(() => {
      this.setUserLogoSource(i)
      this.checkFormValidity()
    }, 750)
  }

  onRepoKeyup(event, i) {
    if (this[`repoInput${i}Timer`]) {
      clearTimeout(this[`repoInput${i}Timer`])
    }
    this[`repoInput${i}Timer`] = setTimeout(() => {
      this.setRepoLogoSource(i)
      this.checkFormValidity()
    }, 750)
  }

  onUserLogoLoad(i) {
    if (this.isBadLogo(this[`userLogo${i}`].src)) {
      return
    }
    delete this.errors[`userLogo${i}`]
    if (!this.anyErrors()) {
      this.optionsForm.classList.remove('error')
    }
  }

  onRepoLogoLoad(i) {
    if (this.isBadLogo(this[`repoLogo${i}`].src)) {
      return
    }
    delete this.errors[`repositoryLogo${i}`]
    if (!this.anyErrors()) {
      this.optionsForm.classList.remove('error')
    }
  }

  onUserLogoError(i) {
    this.showBadUserLogo(i)
    this.errors[`userLogo${i}`] = true
    const user = encodeURIComponent((this[`userInput${i}`].value || '').trim())
    this.flashErrorMessage(`Invalid user: can't find "${user}"`)
    this.checkFormValidity()
  }

  onRepoLogoError(i) {
    this.showBadRepoLogo(i)
    this.errors[`repositoryLogo${i}`] = true
    const repo = (this[`repoInput${i}`].value || '').trim()
    const user = encodeURIComponent(repo.split('/')[0] || '')
    this.flashErrorMessage(`Invalid repository #${i}: can't find "${user}"`)
    this.checkFormValidity()
  }

  isBadLogo(url) {
    return url === `chrome-extension://${chrome.runtime.id}/bad-user.png`
  }

  setUserLogoSource(i) {
    const user = (this[`userInput${i}`].value || '').trim()
    if (user.length < 1) {
      this.showDefaultUserLogo(i)
    } else {
      this.loadUserLogo(user, i)
    }
  }

  setRepoLogoSource(i) {
    const repo = (this[`repoInput${i}`].value || '').trim()
    if (repo.length < 1) {
      this.showDefaultRepoLogo(i)
    } else {
      this.loadRepoLogo(repo, i)
    }
  }

  onSubmit(event) {
    event.preventDefault()
    this.saveOptions()
  }

  saveOptions() {
    if (this.optionsForm.classList.contains('error')) {
      return
    }
    HubnavStorage.load().then(currentOptions => {
      const repository1 = (this.repoInput1.value || '').trim()
      const repository2 = (this.repoInput2.value || '').trim()
      const repository3 = (this.repoInput3.value || '').trim()
      const repository4 = (this.repoInput4.value || '').trim()
      let repository = currentOptions.repository
      if (!repository || repository.length < 1) {
        if (repository1.length > 0) {
          repository = repository1
        } else if (repository2.length > 0) {
          repository = repository2
        } else if (repository3.length > 0) {
          repository = repository3
        } else if (repository4.length > 0) {
          repository = repository4
        }
      }
      // Ensure active repository is one of the four options
      if ([repository1, repository2, repository3, repository4].indexOf(repository) < 0) {
        repository = repository1
      }
      let defaultBranch1 = ''
      if (repository1.length > 0) {
        defaultBranch1 = (this.defaultBranchInput1.value || '').trim()
      }
      let defaultBranch2 = ''
      if (repository2.length > 0) {
        defaultBranch2 = (this.defaultBranchInput2.value || '').trim()
      }
      let defaultBranch3 = ''
      if (repository3.length > 0) {
        defaultBranch3 = (this.defaultBranchInput3.value || '').trim()
      }
      let defaultBranch4 = ''
      if (repository4.length > 0) {
        defaultBranch4 = (this.defaultBranchInput4.value || '').trim()
      }
      let defaultBranch = defaultBranch1
      if (repository === repository2) {
        defaultBranch = defaultBranch2
      } else if (repository === repository3) {
        defaultBranch = defaultBranch3
      } else if (repository === repository4) {
        defaultBranch = defaultBranch4
      }
      const user8 = (this.userInput8.value || '').trim()
      const user9 = (this.userInput9.value || '').trim()
      const user0 = (this.userInput0.value || '').trim()
      let userIsOrg8 = this.userIsOrg8.checked
      if (user8.length < 1) {
        userIsOrg8 = false
      }
      let userIsOrg9 = this.userIsOrg9.checked
      if (user9.length < 1) {
        userIsOrg9 = false
      }
      let userIsOrg0 = this.userIsOrg0.checked
      if (user0.length < 1) {
        userIsOrg0 = false
      }
      const closedIssues = this.closedIssues.checked
      const newIssue = this.newIssue.checked
      const mergedPullRequests = this.mergedPullRequests.checked
      const newPullRequest = this.newPullRequest.checked
      const newOptions = { repository, repository1, repository2, repository3, repository4,
                           defaultBranch1, defaultBranch2, defaultBranch3, defaultBranch4,
                           defaultBranch, closedIssues, newIssue, mergedPullRequests,
                           newPullRequest, user8, user9, user0, userIsOrg8, userIsOrg9, userIsOrg0 }
      HubnavStorage.save(newOptions).then(() => this.flashSaveNotice())
    })
  }

  restoreOptions() {
    HubnavStorage.load().then(options => {
      for (let i of REPO_SHORTCUTS) {
        const repo = options[`repository${i}`]
        if (repo && repo.length > 0) {
          this[`repoInput${i}`].value = repo
          this.loadRepoLogo(repo, i)
        }
        this[`defaultBranchInput${i}`].value = options[`defaultBranch${i}`] || 'master'
      }
      for (let i of USER_SHORTCUTS) {
        const user = options[`user${i}`]
        if (user && user.length > 0) {
          this[`userInput${i}`].value = user
          this.loadUserLogo(user, i)
          let isOrg = false
          if (typeof options[`userIsOrg${i}`] === 'boolean') {
            isOrg = options[`userIsOrg${i}`]
          }
          this[`userIsOrg${i}`].checked = isOrg
        }
      }
      if (typeof options.closedIssues === 'boolean') {
        this.closedIssues.checked = options.closedIssues
      } else {
        this.closedIssues.checked = true
      }
      if (typeof options.newIssue === 'boolean') {
        this.newIssue.checked = options.newIssue
      } else {
        this.newIssue.checked = true
      }
      if (typeof options.mergedPullRequests === 'boolean') {
        this.mergedPullRequests.checked = options.mergedPullRequests
      } else {
        this.mergedPullRequests.checked = true
      }
      if (typeof options.newPullRequest === 'boolean') {
        this.newPullRequest.checked = options.newPullRequest
      } else {
        this.newPullRequest.checked = true
      }
    })
  }

  setup() {
    this.repoInput1.focus()
    this.hookUpHandlers()
    this.restoreOptions()
    this.showShortcutTip()
    this.displayCurrentVersion()
  }

  displayCurrentVersion() {
    const manifest = chrome.runtime.getManifest()
    this.versionEl.textContent = manifest.version
  }

  showShortcutTip() {
    chrome.commands.getAll(commands => {
      const popupCommand = commands.filter(c => c.name === '_execute_browser_action')[0]
      if (popupCommand && popupCommand.shortcut && popupCommand.shortcut.length > 0) {
        this.shortcut.textContent = popupCommand.shortcut
        this.shortcutTipContainer.style.display = 'block'
      }
    })
  }
}

document.addEventListener('DOMContentLoaded', () => {
  const page = new OptionsPage()
  page.setup()
})
<commit_msg>Store active context<commit_after>class OptionsPage {
  constructor() {
    this.findElements()
    this.errors = {}
  }

  anyErrors() {
    return Object.keys(this.errors).length > 0
  }

  isValidRepo(repo) {
    if (repo.length < 1) {
      return true
    }
    const slashIndex = repo.indexOf('/')
    return slashIndex > 0 && slashIndex < repo.length - 1
  }

  checkFormValidity() {
    for (let i of REPO_SHORTCUTS) {
      const repo = (this[`repoInput${i}`].value || '').trim()
      if (this.isValidRepo(repo)) {
        delete this.errors[`repository${i}`]
      } else {
        this.errors[`repository${i}`] = true
        this.flashErrorMessage(`Invalid repository: #${i}`)
      }
    }

    if (this.anyErrors()) {
      this.optionsForm.classList.add('error')
    } else {
      this.optionsForm.classList.remove('error')
      this.saveOptions()
    }
  }

  findElements() {
    for (let i of REPO_SHORTCUTS) {
      this[`repoInput${i}`] = document.getElementById(`repository${i}`)
      this[`defaultBranchInput${i}`] = document.getElementById(`default-branch${i}`)
      this[`repoLogo${i}`] = document.getElementById(`repo-logo${i}`)
    }
    for (let i of USER_SHORTCUTS) {
      this[`userInput${i}`] = document.getElementById(`user${i}`)
      this[`userLogo${i}`] = document.getElementById(`user-logo${i}`)
      this[`userIsOrg${i}`] = document.getElementById(`user${i}-is-org`)
    }
    this.shortcutTipContainer = document.getElementById('shortcut-tip-container')
    this.shortcut = document.getElementById('shortcut')
    this.optionsForm = document.getElementById('options-form')
    this.notification = document.getElementById('notification')
    this.versionEl = document.getElementById('extension-version')
    this.closedIssues = document.getElementById('closed-issues')
    this.newIssue = document.getElementById('new-issue')
    this.mergedPullRequests = document.getElementById('merged-pull-requests')
    this.newPullRequest = document.getElementById('new-pull-request')
  }

  flashNotification(message, isError) {
    if (this.notificationTimer) {
      clearTimeout(this.notificationTimer)
    }
    this.notification.classList.toggle('error', isError)
    this.notification.textContent = message
    this.notification.style.display = 'block'
    this.notificationTimer = setTimeout(() => {
      this.notification.style.display = 'none'
    }, 2000)
  }

  flashSaveNotice() {
    this.flashNotification('Saved!', false)
  }

  flashErrorMessage(message) {
    this.flashNotification(message, true)
  }

  hookUpHandlers() {
    for (let i of REPO_SHORTCUTS) {
      this[`repoInput${i}`].addEventListener('keyup', e => this.onRepoKeyup(e, i))
      this[`defaultBranchInput${i}`].addEventListener('keyup', e => this.onDefaultBranchKeyup(e, i))
      this[`repoLogo${i}`].addEventListener('load', () => this.onRepoLogoLoad(i))
      this[`repoLogo${i}`].addEventListener('error', () => this.onRepoLogoError(i))
    }
    for (let i of USER_SHORTCUTS) {
      this[`userInput${i}`].addEventListener('keyup', e => this.onUserKeyup(e, i))
      this[`userLogo${i}`].addEventListener('load', () => this.onUserLogoLoad(i))
      this[`userLogo${i}`].addEventListener('error', () => this.onUserLogoError(i))
      this[`userIsOrg${i}`].addEventListener('change', () => this.checkFormValidity())
    }
    this.optionsForm.addEventListener('submit', e => this.onSubmit(e))
    this.closedIssues.addEventListener('change', () => this.checkFormValidity())
    this.newIssue.addEventListener('change', () => this.checkFormValidity())
    this.mergedPullRequests.addEventListener('change', () => this.checkFormValidity())
    this.newPullRequest.addEventListener('change', () => this.checkFormValidity())
  }

  loadRepoLogo(rawRepo, i) {
    let user = rawRepo.split('/')[0]
    if (user && user.length > 0) {
      user = encodeURIComponent(user)
      this[`repoLogo${i}`].src = `https://github.com/${user}.png?size=72`
      this[`repoLogo${i}`].alt = user
    }
  }

  loadUserLogo(rawUser, i) {
    const user = encodeURIComponent(rawUser)
    this[`userLogo${i}`].src = `https://github.com/${user}.png?size=72`
    this[`userLogo${i}`].alt = user
  }

  showBadRepoLogo(i) {
    this[`repoLogo${i}`].src = 'bad-user.png'
    this[`repoLogo${i}`].alt = ''
  }

  showBadUserLogo(i) {
    this[`userLogo${i}`].src = 'bad-user.png'
    this[`userLogo${i}`].alt = ''
  }

  showDefaultUserLogo(i) {
    this[`userLogo${i}`].src = 'unknown-user.png'
    this[`userLogo${i}`].alt = ''
  }

  showDefaultRepoLogo(i) {
    this[`repoLogo${i}`].src = 'unknown-user.png'
    this[`repoLogo${i}`].alt = ''
  }

  onDefaultBranchKeyup(event, i) {
    if (this[`defaultBranchTimer${i}`]) {
      clearTimeout(this[`defaultBranchTimer${i}`])
    }
    this[`defaultBranchTimer${i}`] = setTimeout(() => {
      this.checkFormValidity()
    }, 750)
  }

  onUserKeyup(event, i) {
    if (this[`userInput${i}Timer`]) {
      clearTimeout(this[`userInput${i}Timer`])
    }
    this[`userInput${i}Timer`] = setTimeout(() => {
      this.setUserLogoSource(i)
      this.checkFormValidity()
    }, 750)
  }

  onRepoKeyup(event, i) {
    if (this[`repoInput${i}Timer`]) {
      clearTimeout(this[`repoInput${i}Timer`])
    }
    this[`repoInput${i}Timer`] = setTimeout(() => {
      this.setRepoLogoSource(i)
      this.checkFormValidity()
    }, 750)
  }

  onUserLogoLoad(i) {
    if (this.isBadLogo(this[`userLogo${i}`].src)) {
      return
    }
    delete this.errors[`userLogo${i}`]
    if (!this.anyErrors()) {
      this.optionsForm.classList.remove('error')
    }
  }

  onRepoLogoLoad(i) {
    if (this.isBadLogo(this[`repoLogo${i}`].src)) {
      return
    }
    delete this.errors[`repositoryLogo${i}`]
    if (!this.anyErrors()) {
      this.optionsForm.classList.remove('error')
    }
  }

  onUserLogoError(i) {
    this.showBadUserLogo(i)
    this.errors[`userLogo${i}`] = true
    const user = encodeURIComponent((this[`userInput${i}`].value || '').trim())
    this.flashErrorMessage(`Invalid user: can't find "${user}"`)
    this.checkFormValidity()
  }

  onRepoLogoError(i) {
    this.showBadRepoLogo(i)
    this.errors[`repositoryLogo${i}`] = true
    const repo = (this[`repoInput${i}`].value || '').trim()
    const user = encodeURIComponent(repo.split('/')[0] || '')
    this.flashErrorMessage(`Invalid repository #${i}: can't find "${user}"`)
    this.checkFormValidity()
  }

  isBadLogo(url) {
    return url === `chrome-extension://${chrome.runtime.id}/bad-user.png`
  }

  setUserLogoSource(i) {
    const user = (this[`userInput${i}`].value || '').trim()
    if (user.length < 1) {
      this.showDefaultUserLogo(i)
    } else {
      this.loadUserLogo(user, i)
    }
  }

  setRepoLogoSource(i) {
    const repo = (this[`repoInput${i}`].value || '').trim()
    if (repo.length < 1) {
      this.showDefaultRepoLogo(i)
    } else {
      this.loadRepoLogo(repo, i)
    }
  }

  onSubmit(event) {
    event.preventDefault()
    this.saveOptions()
  }

  saveOptions() {
    if (this.optionsForm.classList.contains('error')) {
      return
    }
    HubnavStorage.load().then(currentOptions => {
      const repository1 = (this.repoInput1.value || '').trim()
      const repository2 = (this.repoInput2.value || '').trim()
      const repository3 = (this.repoInput3.value || '').trim()
      const repository4 = (this.repoInput4.value || '').trim()
      let repository = currentOptions.repository
      if (!repository || repository.length < 1) {
        if (repository1.length > 0) {
          repository = repository1
        } else if (repository2.length > 0) {
          repository = repository2
        } else if (repository3.length > 0) {
          repository = repository3
        } else if (repository4.length > 0) {
          repository = repository4
        }
      }
      // Ensure active repository is one of the four options
      if ([repository1, repository2, repository3, repository4].indexOf(repository) < 0) {
        repository = repository1
      }
      let defaultBranch1 = ''
      if (repository1.length > 0) {
        defaultBranch1 = (this.defaultBranchInput1.value || '').trim()
      }
      let defaultBranch2 = ''
      if (repository2.length > 0) {
        defaultBranch2 = (this.defaultBranchInput2.value || '').trim()
      }
      let defaultBranch3 = ''
      if (repository3.length > 0) {
        defaultBranch3 = (this.defaultBranchInput3.value || '').trim()
      }
      let defaultBranch4 = ''
      if (repository4.length > 0) {
        defaultBranch4 = (this.defaultBranchInput4.value || '').trim()
      }
      let defaultBranch = defaultBranch1
      if (repository === repository2) {
        defaultBranch = defaultBranch2
      } else if (repository === repository3) {
        defaultBranch = defaultBranch3
      } else if (repository === repository4) {
        defaultBranch = defaultBranch4
      }
      const user8 = (this.userInput8.value || '').trim()
      const user9 = (this.userInput9.value || '').trim()
      const user0 = (this.userInput0.value || '').trim()
      let userIsOrg8 = this.userIsOrg8.checked
      if (user8.length < 1) {
        userIsOrg8 = false
      }
      let userIsOrg9 = this.userIsOrg9.checked
      if (user9.length < 1) {
        userIsOrg9 = false
      }
      let userIsOrg0 = this.userIsOrg0.checked
      if (user0.length < 1) {
        userIsOrg0 = false
      }
      let user = currentOptions.user
      if (!user || user.length < 1) {
        if (user8.length > 0) {
          user = user8
        } else if (user9.length > 0) {
          user = user9
        } else if (user0.length > 0) {
          user = user0
        }
      }
      // Ensure active user is one of the three options
      if ([user8, user9, user0].indexOf(user) < 0) {
        user = user8
      }
      let userIsOrg = userIsOrg8
      if (user === user9) {
        userIsOrg = userIsOrg9
      } else if (user === user0) {
        userIsOrg = userIsOrg0
      }
      let active = currentOptions.active
      if (!active) {
        if (repository && repository.length > 0) {
          active = 'repository'
        } else if (user && user.length > 0) {
          active = userIsOrg ? 'organization' : 'user'
        }
      }
      const closedIssues = this.closedIssues.checked
      const newIssue = this.newIssue.checked
      const mergedPullRequests = this.mergedPullRequests.checked
      const newPullRequest = this.newPullRequest.checked
      const newOptions = { repository, repository1, repository2, repository3, repository4,
                           defaultBranch1, defaultBranch2, defaultBranch3, defaultBranch4,
                           defaultBranch, closedIssues, newIssue, mergedPullRequests, active,
                           newPullRequest, user8, user9, user0, userIsOrg8, userIsOrg9, userIsOrg0,
                           user, userIsOrg }
      HubnavStorage.save(newOptions).then(() => this.flashSaveNotice())
    })
  }

  restoreOptions() {
    HubnavStorage.load().then(options => {
      for (let i of REPO_SHORTCUTS) {
        const repo = options[`repository${i}`]
        if (repo && repo.length > 0) {
          this[`repoInput${i}`].value = repo
          this.loadRepoLogo(repo, i)
        }
        this[`defaultBranchInput${i}`].value = options[`defaultBranch${i}`] || 'master'
      }
      for (let i of USER_SHORTCUTS) {
        const user = options[`user${i}`]
        if (user && user.length > 0) {
          this[`userInput${i}`].value = user
          this.loadUserLogo(user, i)
          let isOrg = false
          if (typeof options[`userIsOrg${i}`] === 'boolean') {
            isOrg = options[`userIsOrg${i}`]
          }
          this[`userIsOrg${i}`].checked = isOrg
        }
      }
      if (typeof options.closedIssues === 'boolean') {
        this.closedIssues.checked = options.closedIssues
      } else {
        this.closedIssues.checked = true
      }
      if (typeof options.newIssue === 'boolean') {
        this.newIssue.checked = options.newIssue
      } else {
        this.newIssue.checked = true
      }
      if (typeof options.mergedPullRequests === 'boolean') {
        this.mergedPullRequests.checked = options.mergedPullRequests
      } else {
        this.mergedPullRequests.checked = true
      }
      if (typeof options.newPullRequest === 'boolean') {
        this.newPullRequest.checked = options.newPullRequest
      } else {
        this.newPullRequest.checked = true
      }
    })
  }

  setup() {
    this.repoInput1.focus()
    this.hookUpHandlers()
    this.restoreOptions()
    this.showShortcutTip()
    this.displayCurrentVersion()
  }

  displayCurrentVersion() {
    const manifest = chrome.runtime.getManifest()
    this.versionEl.textContent = manifest.version
  }

  showShortcutTip() {
    chrome.commands.getAll(commands => {
      const popupCommand = commands.filter(c => c.name === '_execute_browser_action')[0]
      if (popupCommand && popupCommand.shortcut && popupCommand.shortcut.length > 0) {
        this.shortcut.textContent = popupCommand.shortcut
        this.shortcutTipContainer.style.display = 'block'
      }
    })
  }
}

document.addEventListener('DOMContentLoaded', () => {
  const page = new OptionsPage()
  page.setup()
})
<|endoftext|>


<commit_before>DIRECT_PROPERTIES = ["length", "digits", "dashes"];
SCORE_PROPERTIES = ["english", "spanish", "french", "german",
					"prefix", "suffix"];
TLD_SCORES = {com: 10, net: 5, org: 5, biz: 3, info: 3};
SEARCH_LENGTHS = [7, 8, 6, 9, 5, 10, 4, 11, 3, 12];

function force_number(text) {
	var number = parseFloat(text);
	if (isNaN(number)) return 0;
	return number;
}

function form_weights() {
	return {length: force_number($("input#id_len").val()),
			digits: force_number($("input#id_digits").val()),
			dashes: force_number($("input#id_dashes").val()),
			english: force_number($("input#id_english").val()) / 1000000,
			spanish: force_number($("input#id_spanish").val()) / 1000000,
			french: force_number($("input#id_french").val()) / 1000000,
			german: force_number($("input#id_german").val()) / 1000000,
			prefix: force_number($("input#id_prefix").val()) / 1000000,
			suffix: force_number($("input#id_suffix").val()) / 1000000};
}

function domain_score(domain, weights) {
	var score = 0.0;
	for (var attr in weights)
		score += domain[attr] * weights[attr];
	for (var tld in TLD_SCORES)
		if (!domain[tld]) score += TLD_SCORES[tld];
	return score;
}

function affiliate_link(name, tld, text) {
	var html = '<a href="';
	if ($.registrar == 'moniker') {
		html += 'http://affiliates.moniker.com/pub/Affiliates';
		html += '?affiliate_id=3154&landingpage=domaincheck&domain=';
		html += name + '.' + tld;
	} else if ($.registrar == 'dotster') {
		html += 'http://www.tkqlhce.com/interactive';
		html += '?DomainName=' + name + '.' + tld;
		html += '&siteid=4798&aid=10275199&pid=3770298';
		html += '&url=https://secure.registerapi.com/dds2/index.php';
	} else {
		html += 'http://www.anrdoezrs.net/interactive';
		html += '?domainToCheck=' + name + '&tld=.' + tld.toUpperCase();
		html += '&checkAvail=1&aid=10390987&pid=3770298';
		html += '&url=http://www.godaddy.com/gdshop/registrar/search.asp';
		html += '?isc=0000000000';
	}
	html += '" title="Check availability on ' + $.registrar + '"';
	html += '>' + text + '';
	return html;
}

function table_row(domain, row) {
	var html = '
';
	html += affiliate_link(domain.name, 'com', domain.name) + '	';
	for (var index in DIRECT_PROPERTIES) {
		html += '' + domain[DIRECT_PROPERTIES[index]] + '	';
	}
	for (var index in SCORE_PROPERTIES) {
		var score = domain[SCORE_PROPERTIES[index]] / 1000000;
		html += '' + score.toFixed(3) + '	';
	}
	for (var tld in TLD_SCORES) {
		if (domain[tld]) {
			html += 'taken	';
		} else {
			html += '';
			html += affiliate_link(domain.name, tld, 'free');
			html += '	';
		}
	}
	html += '' + domain.score.toFixed(1) + '	';
	html += '
';
	return html;
}

function update_html() {
	var html = '';
	var row = 1;
	var names = [];
	for (var name in $.domains) names.push(name);
	names.sort(function(a,b) {
		return $.domains[b].score - $.domains[a].score });
	names.length = 100;
	for (var index in names) {
		domain = $.domains[names[index]];
		html += table_row(domain, row);
		row = (row % 2) + 1;
	}
	$("tbody#results").html(html);
	$("tbody tr").hover(
		function() { $(this).addClass("hover"); },
		function() { $(this).removeClass("hover"); });
}

function array_unchanged(a, b) {
	for (var index in a)
		if (a[index] != b[index])
			return false;
	return true;
}

function update_scores() {
	var weights = form_weights();
	if (array_unchanged($.weights, weights)) return;
	$.weights = weights;
	for (var name in $.domains) {
		var domain = $.domains[name];
		domain.score = domain_score(domain, weights);
	}
	update_html();
}

function keyword_match(left, right, name) {
	if (left && name.substr(0, left.length) != left) return false;
	if (right && name.substr(-right.length) != right) return false;
	return true;
}

function delete_domains(left, right) {
	for (var name in $.domains)
		if (!keyword_match(left, right, name))
			delete $.domains[name];
	update_html();
}

function ajax_result(json, status) {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var weights = form_weights();
	var updated = false;
	var length = 0;
	for (name in json) {
		domain = json[name];
		domain.name = name;
		domain.length = name.length;
		domain.score = domain_score(domain, weights);
		if (keyword_match(left, right, name)) {
			$.domains[name] = domain;
			updated = true;
		}
		length = name.length;
	}
	$.ajax_search.xhr[length] = false;
	if (updated) update_html();
}

function ajax_search(left, right) {
	if ($.ajax_search.left == left && $.ajax_search.right == right) return;
	$.ajax_search.left = left;
	$.ajax_search.right = right;
	delete_domains(left, right);
	for (var index in SEARCH_LENGTHS) {
		var length = SEARCH_LENGTHS[index];
		if ($.ajax_search.xhr[length])
			$.ajax_search.xhr[length].abort();
		if (left.length > length || right.length > length)
			continue;
		$.ajax_search.xhr[length] = $.ajax({
				type: "GET",
				url: "/search/json/",
				data: {left: left, right: right, length: length, version: 3},
				dataType: "json",
				cache: true,
				success: ajax_result,
			});
	}
}

function keyword_keypress(e) {
	if ((e.which != 45) &&
		(e.which < 48 || e.which > 57) &&
		(e.which < 97 || e.which > 122)) return;
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var updated =
		this.value.substr(0, this.selectionStart) +
		String.fromCharCode(e.which) +
		this.value.substr(this.selectionEnd);
	if (this.name == 'left') left = updated;
	else if (this.name == 'right') right = updated;
	ajax_search(left, right);
}

function keyword_keyup() {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	ajax_search(left, right);
}

function document_ready() {
	$.domains = {};
	$.weights = form_weights();
	$.registrar = 'godaddy';
	$.ajax_search = {};
	$.ajax_search.xhr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
	$.ajax_search.left = '*';
	$.ajax_search.right = '*';
	keyword_keyup();
	$("input.keyword").keypress(keyword_keypress);
	$("input.keyword").keyup(keyword_keyup);
	$("input.score").keyup(update_scores);
}

$(document).ready(document_ready);
<commit_msg>Added affiliate link for 1and1.<commit_after>DIRECT_PROPERTIES = ["length", "digits", "dashes"];
SCORE_PROPERTIES = ["english", "spanish", "french", "german",
					"prefix", "suffix"];
TLD_SCORES = {com: 10, net: 5, org: 5, biz: 3, info: 3};
SEARCH_LENGTHS = [7, 8, 6, 9, 5, 10, 4, 11, 3, 12];

function force_number(text) {
	var number = parseFloat(text);
	if (isNaN(number)) return 0;
	return number;
}

function form_weights() {
	return {length: force_number($("input#id_len").val()),
			digits: force_number($("input#id_digits").val()),
			dashes: force_number($("input#id_dashes").val()),
			english: force_number($("input#id_english").val()) / 1000000,
			spanish: force_number($("input#id_spanish").val()) / 1000000,
			french: force_number($("input#id_french").val()) / 1000000,
			german: force_number($("input#id_german").val()) / 1000000,
			prefix: force_number($("input#id_prefix").val()) / 1000000,
			suffix: force_number($("input#id_suffix").val()) / 1000000};
}

function domain_score(domain, weights) {
	var score = 0.0;
	for (var attr in weights)
		score += domain[attr] * weights[attr];
	for (var tld in TLD_SCORES)
		if (!domain[tld]) score += TLD_SCORES[tld];
	return score;
}

function affiliate_link(name, tld, text) {
	var html = '<a href="';
	if ($.registrar == 'moniker') {
		html += "http://affiliates.moniker.com/pub/Affiliates";
		html += "?affiliate_id=3154&landingpage=domaincheck&domain=";
		html += name + "." + tld;
	} else if ($.registrar == 'dotster') {
		html += "http://www.tkqlhce.com/interactive";
		html += "?DomainName=" + name + "." + tld + "&siteid=4798";
		html += "&aid=10275199&pid=3770298";
		html += "&url=https://secure.registerapi.com/dds2/index.php";
	} else if ($.registrar == '1and1') {
		html += "http://www.dpbolvw.net/interactive";
		html += "?domain=" + name + "&tld=" + tld;
		html += "&aid=10376103&pid=3770298";
		html += "&url=http://order.1and1.com/dcjump";
		html += "?ac=OM.US.US469K02463T2103a"
	} else {
		html += "http://www.anrdoezrs.net/interactive";
		html += "?domainToCheck=" + name + "&tld=." + tld.toUpperCase();
		html += "&checkAvail=1";
		html += "&aid=10390987&pid=3770298";
		html += "&url=http://www.godaddy.com/gdshop/registrar/search.asp";
		html += "?isc=0000000000";
	}
	html += '" title="Check availability on ' + $.registrar + '"';
	html += '>' + text + '';
	return html;
}

function table_row(domain, row) {
	var html = '
';
	html += affiliate_link(domain.name, 'com', domain.name) + '	';
	for (var index in DIRECT_PROPERTIES) {
		html += '' + domain[DIRECT_PROPERTIES[index]] + '	';
	}
	for (var index in SCORE_PROPERTIES) {
		var score = domain[SCORE_PROPERTIES[index]] / 1000000;
		html += '' + score.toFixed(3) + '	';
	}
	for (var tld in TLD_SCORES) {
		if (domain[tld]) {
			html += 'taken	';
		} else {
			html += '';
			html += affiliate_link(domain.name, tld, 'free');
			html += '	';
		}
	}
	html += '' + domain.score.toFixed(1) + '	';
	html += '
';
	return html;
}

function update_html() {
	var html = '';
	var row = 1;
	var names = [];
	for (var name in $.domains) names.push(name);
	names.sort(function(a,b) {
		return $.domains[b].score - $.domains[a].score });
	names.length = 100;
	for (var index in names) {
		domain = $.domains[names[index]];
		html += table_row(domain, row);
		row = (row % 2) + 1;
	}
	$("tbody#results").html(html);
	$("tbody tr").hover(
		function() { $(this).addClass("hover"); },
		function() { $(this).removeClass("hover"); });
}

function array_unchanged(a, b) {
	for (var index in a)
		if (a[index] != b[index])
			return false;
	return true;
}

function update_scores() {
	var weights = form_weights();
	if (array_unchanged($.weights, weights)) return;
	$.weights = weights;
	for (var name in $.domains) {
		var domain = $.domains[name];
		domain.score = domain_score(domain, weights);
	}
	update_html();
}

function keyword_match(left, right, name) {
	if (left && name.substr(0, left.length) != left) return false;
	if (right && name.substr(-right.length) != right) return false;
	return true;
}

function delete_domains(left, right) {
	for (var name in $.domains)
		if (!keyword_match(left, right, name))
			delete $.domains[name];
	update_html();
}

function ajax_result(json, status) {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var weights = form_weights();
	var updated = false;
	var length = 0;
	for (name in json) {
		domain = json[name];
		domain.name = name;
		domain.length = name.length;
		domain.score = domain_score(domain, weights);
		if (keyword_match(left, right, name)) {
			$.domains[name] = domain;
			updated = true;
		}
		length = name.length;
	}
	$.ajax_search.xhr[length] = false;
	if (updated) update_html();
}

function ajax_search(left, right) {
	if ($.ajax_search.left == left && $.ajax_search.right == right) return;
	$.ajax_search.left = left;
	$.ajax_search.right = right;
	delete_domains(left, right);
	for (var index in SEARCH_LENGTHS) {
		var length = SEARCH_LENGTHS[index];
		if ($.ajax_search.xhr[length])
			$.ajax_search.xhr[length].abort();
		if (left.length > length || right.length > length)
			continue;
		$.ajax_search.xhr[length] = $.ajax({
				type: "GET",
				url: "/search/json/",
				data: {left: left, right: right, length: length, version: 3},
				dataType: "json",
				cache: true,
				success: ajax_result,
			});
	}
}

function keyword_keypress(e) {
	if ((e.which != 45) &&
		(e.which < 48 || e.which > 57) &&
		(e.which < 97 || e.which > 122)) return;
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var updated =
		this.value.substr(0, this.selectionStart) +
		String.fromCharCode(e.which) +
		this.value.substr(this.selectionEnd);
	if (this.name == 'left') left = updated;
	else if (this.name == 'right') right = updated;
	ajax_search(left, right);
}

function keyword_keyup() {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	ajax_search(left, right);
}

function document_ready() {
	$.domains = {};
	$.weights = form_weights();
	$.registrar = 'godaddy';
	$.ajax_search = {};
	$.ajax_search.xhr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
	$.ajax_search.left = '*';
	$.ajax_search.right = '*';
	keyword_keyup();
	$("input.keyword").keypress(keyword_keypress);
	$("input.keyword").keyup(keyword_keyup);
	$("input.score").keyup(update_scores);
}

$(document).ready(document_ready);
<|endoftext|>


<commit_before>var https = require('https');

module.exports = function (context, req) {
    context.log('context:', JSON.stringify(context, null, 2));

    var input = JSON.stringify(req.body);
    var command = input.split('&')[7].split('=')[1];
    var userquery = input.split('&')[8].split('=')[1];
    var callback = input.split('&')[9].split('=')[1];
    var username = input.split('&')[6].split('=')[1];

    // define function to call other Azure function to get the weather
    function getMetar(icaocode) {

        context.log(`https://${process.env[functionUrl]}/api/metarSlackbot?icao=${icaocode}&callback=${callback}&user=${username}`);

        https.get(`https://${process.env[functionUrl]}/api/metarSlackbot?icao=${icaocode}&callback=${callback}&user=${username}`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
    }

    function getFlightStatus(flightnumber) {
        if (req.query.simple == "true") {
        context.log(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}&simple=true`);
        https.get(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}&simple=true`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
        } else {
        context.log(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}`);
        https.get(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
        }
    }

    context.log('Command was %s', command);
    context.log('Input was %s', userquery);

    if (command == '%2Fmetar') {

        context.bindings.response = `Hello ${username}, I am getting your weather for ${userquery}, try again if you have not heard back in 20s.`;

        getMetar(userquery);

        context.done();
    }
    else if (command == '%2Fflightstatus') {
        context.bindings.response = `Hello ${username}, I am getting the status for ${userquery}, try again if you have not heard back in 20s.`;
        getFlightStatus(userquery);
        context.done();
    }
};<commit_msg>Add output<commit_after>var https = require('https');

module.exports = function (context, req) {
    //context.log('context:', JSON.stringify(context, null, 2));
    context.log(process.env[functionUrl]);
    var input = JSON.stringify(req.body);
    var command = input.split('&')[7].split('=')[1];
    var userquery = input.split('&')[8].split('=')[1];
    var callback = input.split('&')[9].split('=')[1];
    var username = input.split('&')[6].split('=')[1];

    // define function to call other Azure function to get the weather
    function getMetar(icaocode) {

        context.log(`https://${process.env[functionUrl]}/api/metarSlackbot?icao=${icaocode}&callback=${callback}&user=${username}`);

        https.get(`https://${process.env[functionUrl]}/api/metarSlackbot?icao=${icaocode}&callback=${callback}&user=${username}`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
    }

    function getFlightStatus(flightnumber) {
        if (req.query.simple == "true") {
        context.log(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}&simple=true`);
        https.get(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}&simple=true`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
        } else {
        context.log(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}`);
        https.get(`https://${process.env[functionUrl]}/api/flightStatus?flightnumber=${flightnumber}&callback=${callback}&user=${username}`, function (res) {
            var body = ''; // Will contain the final response
            // Received data is a buffer.
            // Adding it to our body
            res.on('data', function (data) {
                body += data;
            });
            // After the response is completed, parse it and log it to the console
            res.on('end', function () {
                var parsed = JSON.parse(body);
                context.log(parsed);
            });
        })
            // If any error has occured, log error to console
            .on('error', function (e) {
                context.log("Got error: " + e.message);
            });
        }
    }

    context.log('Command was %s', command);
    context.log('Input was %s', userquery);

    if (command == '%2Fmetar') {

        context.bindings.response = `Hello ${username}, I am getting your weather for ${userquery}, try again if you have not heard back in 20s.`;

        getMetar(userquery);

        context.done();
    }
    else if (command == '%2Fflightstatus') {
        context.bindings.response = `Hello ${username}, I am getting the status for ${userquery}, try again if you have not heard back in 20s.`;
        getFlightStatus(userquery);
        context.done();
    }
};<|endoftext|>


<commit_before>LunaticFringe.MediaManager = function () {
  this.Sprites = {};
  this.Audio = {};

  this.LoadSprite = function (name, file) {
      this.Sprites[name] = new Image();
      this.Sprites[name].src = file;
      this.Sprites[name].Loaded = false;
      this.Sprites[name].onload = function () { this.Loaded = true; };
  };

  // Leave off the extension. MP3 or OGG will be used depending on browser. You must supply both and they must share the same file name. Ugh, this could be better.
  this.LoadAudio = function (name, fileName) {
      var ext;

      this.Audio[name] = new Audio();

      if (this.Audio[name].canPlayType("audio/ogg") === "probably" || this.Audio[name].canPlayType("audio/ogg") === "maybe") {
          ext = ".ogg";
      } else if (this.Audio[name].canPlayType("audio/mpeg") === "probably" || this.Audio[name].canPlayType("audio/mped") === "maybe") {
          ext = ".mp3";
      } else {
          log("No supported audio format detected.");
      }

      this.Audio[name].src = fileName + ext;
      this.Audio[name].preload = "auto";
      this.Audio[name].Loaded = false;
      this.Audio[name].onload = function () { game.mediaManager.Audio[name].Loaded = true; };
  };

  this.LoadSprite("Base", "images/Base.png");
  this.LoadSprite("EnemyBase", "images/EnemyBase.png");
  this.LoadSprite("Pebbles", "images/Pebbles.png");
  this.LoadSprite("PhotonSmall", "images/PhotonSmall.png");
  this.LoadSprite("PlayerShip", "images/PlayerShip.png");
  this.LoadSprite("Puffer", "images/Puffer.png");
  this.LoadSprite("QuadBlaster", "images/Quadblaster.png");
  this.LoadSprite("Rocko", "images/Rocko.png");
  this.LoadSprite("Slicer", "images/Slicer.png");
  this.LoadSprite("Sludger", "images/Sludger.png");
  this.LoadSprite("SludgerMine", "images/SludgerMine.png");
  this.LoadSprite("PufferShot", "images/PufferShot.png");

  this.LoadAudio("CollisionGeneral", "audio/collision_general");
  this.LoadAudio("CollisionSpreadshot", "audio/collision_spreadshot");
  this.LoadAudio("CollisionQuad", "audio/collision_quad");
  this.LoadAudio("CollisionDefaultWeapon", "audio/collision_defaultweapon");
  this.LoadAudio("PhotonSmall", "audio/PhotonSmall");
  this.LoadAudio("StartUp", "audio/StartUp");
  this.LoadAudio("SludgerMinePop", "audio/SludgerMinePop");
  this.LoadAudio("PlayerDeath", "audio/PlayerDeath");
  this.LoadAudio("SludgerDeath", "audio/SludgerDeath");
  this.LoadAudio("BaseRepair", "audio/baserepair");

  this.loaded = function () {
    var sprite, numLoaded = 0, total = 0;
    for (sprite in this.Sprites) {
      if (this.Sprites.hasOwnProperty(sprite)) {
        if (this.Sprites[sprite].Loaded) {
          numLoaded += 1;
        }
        total += 1;
      }
    }
    /*log(numLoaded + " of " + total + " sprites loaded");
    log(numLoaded / total * 100 + "%");*/
    return numLoaded / total * 100;
  };
};

// untested loaded checker
//var isloaded = function () {
//  var percent = mediaManager.loaded();
//  if (percent < 100) {
//    setTimeout(isloaded, 0);
//  }
//}
//setTimeout(isloaded, 0);
<commit_msg>Added in more projectile sprites<commit_after>LunaticFringe.MediaManager = function () {
  this.Sprites = {};
  this.Audio = {};

  this.LoadSprite = function (name, file) {
      this.Sprites[name] = new Image();
      this.Sprites[name].src = file;
      this.Sprites[name].Loaded = false;
      this.Sprites[name].onload = function () { this.Loaded = true; };
  };

  // Leave off the extension. MP3 or OGG will be used depending on browser. You must supply both and they must share the same file name. Ugh, this could be better.
  this.LoadAudio = function (name, fileName) {
      var ext;

      this.Audio[name] = new Audio();

      if (this.Audio[name].canPlayType("audio/ogg") === "probably" || this.Audio[name].canPlayType("audio/ogg") === "maybe") {
          ext = ".ogg";
      } else if (this.Audio[name].canPlayType("audio/mpeg") === "probably" || this.Audio[name].canPlayType("audio/mped") === "maybe") {
          ext = ".mp3";
      } else {
          log("No supported audio format detected.");
      }

      this.Audio[name].src = fileName + ext;
      this.Audio[name].preload = "auto";
      this.Audio[name].Loaded = false;
      this.Audio[name].onload = function () { game.mediaManager.Audio[name].Loaded = true; };
  };

  this.LoadSprite("Base", "images/Base.png");
  this.LoadSprite("EnemyBase", "images/EnemyBase.png");
  this.LoadSprite("Pebbles", "images/Pebbles.png");
  this.LoadSprite("PhotonQuad", "images/PhotonQuad.png");
  this.LoadSprite("PhotonSmall", "images/PhotonSmall.png");
  this.LoadSprite("PhotonMedium", "images/PhotonMedium.png");
  this.LoadSprite("PhotonLarge", "images/PhotonLarge.png");
  this.LoadSprite("PlayerShip", "images/PlayerShip.png");
  this.LoadSprite("Puffer", "images/Puffer.png");
  this.LoadSprite("QuadBlaster", "images/Quadblaster.png");
  this.LoadSprite("Rocko", "images/Rocko.png");
  this.LoadSprite("Slicer", "images/Slicer.png");
  this.LoadSprite("Sludger", "images/Sludger.png");
  this.LoadSprite("SludgerMine", "images/SludgerMine.png");
  this.LoadSprite("PufferShot", "images/PufferShot.png");

  this.LoadAudio("CollisionGeneral", "audio/collision_general");
  this.LoadAudio("CollisionSpreadshot", "audio/collision_spreadshot");
  this.LoadAudio("CollisionQuad", "audio/collision_quad");
  this.LoadAudio("CollisionDefaultWeapon", "audio/collision_defaultweapon");
  this.LoadAudio("PhotonSmall", "audio/PhotonSmall");
  this.LoadAudio("StartUp", "audio/StartUp");
  this.LoadAudio("SludgerMinePop", "audio/SludgerMinePop");
  this.LoadAudio("PlayerDeath", "audio/PlayerDeath");
  this.LoadAudio("SludgerDeath", "audio/SludgerDeath");
  this.LoadAudio("BaseRepair", "audio/baserepair");

  this.loaded = function () {
    var sprite, numLoaded = 0, total = 0;
    for (sprite in this.Sprites) {
      if (this.Sprites.hasOwnProperty(sprite)) {
        if (this.Sprites[sprite].Loaded) {
          numLoaded += 1;
        }
        total += 1;
      }
    }
    /*log(numLoaded + " of " + total + " sprites loaded");
    log(numLoaded / total * 100 + "%");*/
    return numLoaded / total * 100;
  };
};

// untested loaded checker
//var isloaded = function () {
//  var percent = mediaManager.loaded();
//  if (percent < 100) {
//    setTimeout(isloaded, 0);
//  }
//}
//setTimeout(isloaded, 0);
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const {forEach, split, assign} = require('lodash')

const ADMIN = 'zedeck'
const ID_STRING_LENGTH = 20
const USER_ID_STRING_LENGTH = 28
const PROFILES_NODE = 'members'
const ROLES_NODE = 'memberRoles'
const ROLES = [
  'clerk',
  'church_elder',
  'elder',
  'department_director',
  'department_secretary',
  'department_assistant'
]

function root(path) {
  let r = 'root'
  const path_components = split(path, '/')
  forEach(path_components, c => {
    if (c) {
      // component isn't empty
      if (c === 'auth.uid')
        r += `.child(${c})`
      else
        r += `.child('${c}')`
    }
  })
  return {
    matchUserID() {
      return `(${r}.val() === auth.uid)`
    },
    exists() {
      return `(${r}.exists())`
    }
  }
}

function requiresAuth() {
  return '(auth !== null)'
}

function hasProfile() {
  return `(${requiresAuth()} && ${root(PROFILES_NODE + '/auth.uid').exists()})`
}

function hasAnyRoles(roles) {
  if (Array.isArray(roles)) {
    let r = ''
    forEach(roles, role => {
      r += `root.child('${ROLES_NODE}').child(auth.uid).child('${role}').exists() || `
    })
    return `(${requiresAuth()} && (${r.substr(0, r.length - 4)}))`
  }
  return ''
}

function wildcard(name) {
  return {
    matchUserID() {
      return `(${requiresAuth()} && (auth.uid === ${name}))`
    },

    inStringEnum(list) {
      let r = ''
      forEach(list, e => { r += `${name} === '${e}' || ` })
      return `(${r.substr(0, r.length - 4)})`
    }
  }
}

function child(name, source) {
  return {
    matchUserID() {
      return `(${requiresAuth()} && auth.uid === ${source}.child('${name}').val())`
    },

    equalToString(value) {
      return `(${source}.child('${name}').val() === '${value}')`
    },

    equalTo(value) {
      return `(${source}.child('${name}').val() === ${value})`
    },

    exists() {
      return `(${source}.child('${name}').exists())`
    }
  }
}

function type(definitions) {
  let fieldsRules = {}
  let mandatoryFields = []

  forEach(definitions, (def, key) => {
    let rule = ''
    if ('type' in def) {
      if (def.type === 'bool' || def.type === 'boolean') {
        rule += `newData.isBoolean()`
      }
      else if (def.type === 'string') {
        rule += `newData.isString()`
        if ('min' in def)
          rule += ` && newData.val().length >= ${def.min}`
        if ('max' in def)
          rule += ` && newData.val().length <= ${def.max}`
      }
      else if (def.type === 'uid') {
        rule += `${requiresAuth()} && newData.isString() && newData.val().length === ${USER_ID_STRING_LENGTH}`
      }
      else if (def.type === 'user.uid') {
        rule += `${requiresAuth()} && newData.isString() && newData.val() === auth.uid`
      }
      else if (def.type === 'id') {
        rule += `newData.isString() && newData.val().length === ${ID_STRING_LENGTH}`
      }
      else if (def.type === 'timestamp' || def.type === 'number') {
        rule += `newData.isNumber()`
      }
      else if (def.type === 'now') {
        rule += `newData.isNumber() && newData.val() === now`
      }

      if (!def.optional) {
        mandatoryFields.push(key)
      }
      fieldsRules[key] = {
        '.validate': rule
      }

      if (def['.write']) {
        fieldsRules[key]['.write'] = def['.write']
      }
    }
  })

  fieldsRules['.validate'] = `newData.hasChildren(['${mandatoryFields.join("', '")}'])`
  fieldsRules['$other'] = {'.validate': false}
  return fieldsRules
}

function operations(rules) {
  let r = ''

  // Create
  if (rules.create)
    r += `(newData.exists() && !data.exists() && ${rules.create}) || `

  // Edit/modify
  if (rules.edit)
    r += `(newData.exists() && data.exists() && ${rules.edit}) || `

  // Delete
  if (rules.delete)
    r += `(!newData.exists() && data.exists() && ${rules.delete}) || `

  return `(${r.substr(0, r.length - 4)})`
}

const rules = {
  memberRoles: {
    $uid: {
      '.read': `${hasAnyRoles([ADMIN])} || ${wildcard('$uid').matchUserID()}`,

      $role: {
        '.validate': `newData.isBoolean() && ${wildcard('$role').inStringEnum(ROLES)}`,
        '.write': `${hasAnyRoles([ADMIN])}`
      }
    }
  },

  members: {
    '.read': `${hasProfile()}`,

    $uid: {
      '.write': `${wildcard('$uid').matchUserID()} || ${hasAnyRoles(['clerk', ADMIN])}`
    }
  },

  prayers: {
    '.read': hasProfile(),

    $prayer_id: assign(
      type({
        poster: {type: 'user.uid', optional: true},
        content: {type: 'string', min: 7, max: 4096},
        anonymous: {type: 'bool'},
        answeredAt: {
          type: 'now',
          optional: true,
          '.write': `${hasProfile()} && ${child('poster', 'data.parent()').matchUserID()}`
        },
        createdAt: {type: 'timestamp'}
      }),

      {
        '.write': operations({
          'create': `${hasProfile()} && ${child('poster', 'newData').matchUserID()}`,
          'edit': `${child('poster', 'data').matchUserID()} || ${hasAnyRoles(['clerk', 'zedeck'])}`,
          'delete': `${child('poster', 'data').matchUserID()} || ${hasAnyRoles(['clerk', 'zedeck'])}`
        })
      }
    )
  },

  prayerViews: {
    '.read': hasProfile(),

    $prayer_id: {
      '.validate': `newData.isNumber()`,

      '.write': operations({
        'create': `${hasProfile()} && newData.val() === 1`,
        'edit': `${hasProfile()} && data.val() + 1 === newData.val()`,
        'delete': `false`
      })
    }
  },

  prayerComments: {
    '.read': hasProfile(),

    $prayer_id: assign(
      type({
        prayerId: {type: 'id'},
        content: {type: 'string', min: 3, max: 4096},
        createdBy: {type: 'uid'},
        createdAt: {type: 'timestamp'}
      }),

      {
        '.write': operations({
          'create': `${hasProfile()} && ${child('createdBy', 'newData').matchUserID()}`,
          'edit': `false`,
          'delete': `${hasProfile()} || ${child('createdBy', 'data').matchUserID()} || ${hasAnyRoles(['clerk', ADMIN])}`
        })
      }
    )
  },

  membersPrayingForPrayerRequests: {
    $prayer_id: {
      '.read': hasProfile(),

      $uid: {
        '.validate': 'newData.isBoolean()',
        '.write': `${hasProfile()} && root.child('prayers').child($prayer_id).exists() && ${wildcard('$uid').matchUserID()}`,
      }
    }
  }
}

// Update rules
const output = JSON.stringify({
  rules
}, null, 2)
fs.writeFileSync(path.join(__dirname, 'database.rules.json'), output)
console.log(output)
<commit_msg>Don't wrap wildcards in quotes in root()<commit_after>const fs = require('fs')
const path = require('path')
const {forEach, split, assign} = require('lodash')

const ADMIN = 'zedeck'
const ID_STRING_LENGTH = 20
const USER_ID_STRING_LENGTH = 28
const PROFILES_NODE = 'members'
const ROLES_NODE = 'memberRoles'
const ROLES = [
  'clerk',
  'church_elder',
  'elder',
  'department_director',
  'department_secretary',
  'department_assistant'
]

function root(path) {
  let r = 'root'
  const path_components = split(path, '/')
  forEach(path_components, c => {
    if (c) {
      // component isn't empty
      if (c === 'auth.uid' || c[0] === '$')
        r += `.child(${c})`
      else
        r += `.child('${c}')`
    }
  })
  return {
    matchUserID() {
      return `(${r}.val() === auth.uid)`
    },
    exists() {
      return `(${r}.exists())`
    }
  }
}

function requiresAuth() {
  return '(auth !== null)'
}

function hasProfile() {
  return `(${requiresAuth()} && ${root(PROFILES_NODE + '/auth.uid').exists()})`
}

function hasAnyRoles(roles) {
  if (Array.isArray(roles)) {
    let r = ''
    forEach(roles, role => {
      r += `root.child('${ROLES_NODE}').child(auth.uid).child('${role}').exists() || `
    })
    return `(${requiresAuth()} && (${r.substr(0, r.length - 4)}))`
  }
  return ''
}

function wildcard(name) {
  return {
    matchUserID() {
      return `(${requiresAuth()} && (auth.uid === ${name}))`
    },

    inStringEnum(list) {
      let r = ''
      forEach(list, e => { r += `${name} === '${e}' || ` })
      return `(${r.substr(0, r.length - 4)})`
    }
  }
}

function child(name, source) {
  return {
    matchUserID() {
      return `(${requiresAuth()} && auth.uid === ${source}.child('${name}').val())`
    },

    equalToString(value) {
      return `(${source}.child('${name}').val() === '${value}')`
    },

    equalTo(value) {
      return `(${source}.child('${name}').val() === ${value})`
    },

    exists() {
      return `(${source}.child('${name}').exists())`
    }
  }
}

function type(definitions) {
  let fieldsRules = {}
  let mandatoryFields = []

  forEach(definitions, (def, key) => {
    let rule = ''
    if ('type' in def) {
      if (def.type === 'bool' || def.type === 'boolean') {
        rule += `newData.isBoolean()`
      }
      else if (def.type === 'string') {
        rule += `newData.isString()`
        if ('min' in def)
          rule += ` && newData.val().length >= ${def.min}`
        if ('max' in def)
          rule += ` && newData.val().length <= ${def.max}`
      }
      else if (def.type === 'uid') {
        rule += `${requiresAuth()} && newData.isString() && newData.val().length === ${USER_ID_STRING_LENGTH}`
      }
      else if (def.type === 'user.uid') {
        rule += `${requiresAuth()} && newData.isString() && newData.val() === auth.uid`
      }
      else if (def.type === 'id') {
        rule += `newData.isString() && newData.val().length === ${ID_STRING_LENGTH}`
      }
      else if (def.type === 'timestamp' || def.type === 'number') {
        rule += `newData.isNumber()`
      }
      else if (def.type === 'now') {
        rule += `newData.isNumber() && newData.val() === now`
      }

      if (!def.optional) {
        mandatoryFields.push(key)
      }
      fieldsRules[key] = {
        '.validate': rule
      }

      if (def['.write']) {
        fieldsRules[key]['.write'] = def['.write']
      }
    }
  })

  fieldsRules['.validate'] = `newData.hasChildren(['${mandatoryFields.join("', '")}'])`
  fieldsRules['$other'] = {'.validate': false}
  return fieldsRules
}

function operations(rules) {
  let r = ''

  // Create
  if (rules.create)
    r += `(newData.exists() && !data.exists() && ${rules.create}) || `

  // Edit/modify
  if (rules.edit)
    r += `(newData.exists() && data.exists() && ${rules.edit}) || `

  // Delete
  if (rules.delete)
    r += `(!newData.exists() && data.exists() && ${rules.delete}) || `

  return `(${r.substr(0, r.length - 4)})`
}

const rules = {
  memberRoles: {
    $uid: {
      '.read': `${hasAnyRoles([ADMIN])} || ${wildcard('$uid').matchUserID()}`,

      $role: {
        '.validate': `newData.isBoolean() && ${wildcard('$role').inStringEnum(ROLES)}`,
        '.write': `${hasAnyRoles([ADMIN])}`
      }
    }
  },

  members: {
    '.read': `${hasProfile()}`,

    $uid: {
      '.write': `${wildcard('$uid').matchUserID()} || ${hasAnyRoles(['clerk', ADMIN])}`
    }
  },

  prayers: {
    '.read': hasProfile(),

    $prayer_id: assign(
      type({
        poster: {type: 'user.uid', optional: true},
        content: {type: 'string', min: 7, max: 4096},
        anonymous: {type: 'bool'},
        answeredAt: {
          type: 'now',
          optional: true,
          '.write': `${hasProfile()} && ${child('poster', 'data.parent()').matchUserID()}`
        },
        createdAt: {type: 'timestamp'}
      }),

      {
        '.write': operations({
          'create': `${hasProfile()} && ${child('poster', 'newData').matchUserID()}`,
          'edit': `${child('poster', 'data').matchUserID()} || ${hasAnyRoles(['clerk', 'zedeck'])}`,
          'delete': `${child('poster', 'data').matchUserID()} || ${hasAnyRoles(['clerk', 'zedeck'])}`
        })
      }
    )
  },

  prayerViews: {
    '.read': hasProfile(),

    $prayer_id: {
      '.validate': `newData.isNumber()`,

      '.write': operations({
        'create': `${hasProfile()} && newData.val() === 1`,
        'edit': `${hasProfile()} && data.val() + 1 === newData.val()`,
        'delete': `false`
      })
    }
  },

  prayerComments: {
    '.read': hasProfile(),

    $prayer_id: assign(
      type({
        prayerId: {type: 'id'},
        content: {type: 'string', min: 3, max: 4096},
        createdBy: {type: 'uid'},
        createdAt: {type: 'timestamp'}
      }),

      {
        '.write': operations({
          'create': `${hasProfile()} && ${child('createdBy', 'newData').matchUserID()}`,
          'edit': `false`,
          'delete': `${hasProfile()} || ${child('createdBy', 'data').matchUserID()} || ${hasAnyRoles(['clerk', ADMIN])}`
        })
      }
    )
  },

  membersPrayingForPrayerRequests: {
    $prayer_id: {
      '.read': hasProfile(),

      $uid: {
        '.validate': 'newData.isBoolean()',
        '.write': `${hasProfile()} && root.child('prayers').child($prayer_id).exists() && ${wildcard('$uid').matchUserID()}`,
      }
    }
  }
}

// Update rules
const output = JSON.stringify({
  rules
}, null, 2)
fs.writeFileSync(path.join(__dirname, 'database.rules.json'), output)
console.log(output)
<|endoftext|>


<commit_before>(function () {
  var map = new L.Map('map').setView([42.354, -71.065], 14);
  var mapQuest = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg', {
    attribution: 'Tiles Courtesy of MapQuest — Map data © OpenStreetMap contributors, CC-BY-SA',
    subdomains: '1234'
  }).addTo(map);

  var censusData;
  L.Util.ajax('geodata/allcensusacsdata.json').then(function(data) {
	  censusData = data;

    var tracts2010 = L.geoJson.ajax("geodata/tracts2010.json",{
          middleware:function(data){
            return topojson.feature(data, data.objects.tracts2010);
          },
        style: function(feature){
          var featureId = feature.id;
        var d = censusData[2008][featureId].totalpop;
        var fill = d > 5944 ? '#800026' :
                 d > 5323  ? '#BD0026' :
                 d > 4777  ? '#E31A1C' :
                 d > 4146  ? '#FC4E2A' :
                 d > 3552   ? '#FD8D3C' :
                 d > 2970   ? '#FEB24C' :
                 d > 2215   ? '#FED976' :
                            '#FFEDA0';

          return {
          weight: 1,
          color: "#ff0000",
          fillColor: fill
        };
      }
      }).addTo(map);
      var tracts2000 = L.geoJson.ajax("geodata/tracts2000.json",{
          middleware:function(data){
            return topojson.feature(data, data.objects.tracts2000);
          },
        style: function(feature){
          var featureId = feature.id;
        var d = censusData[2000][featureId].totalpop;
        var fill = d > 5944 ? '#800026' :
                 d > 5323  ? '#BD0026' :
                 d > 4777  ? '#E31A1C' :
                 d > 4146  ? '#FC4E2A' :
                 d > 3552   ? '#FD8D3C' :
                 d > 2970   ? '#FEB24C' :
                 d > 2215   ? '#FED976' :
                            '#FFEDA0';

          return {
          weight: 1,
          color: "#ff0000",
          fillColor: fill
        };
        }
      });

    var baseLayers = {
      "Map Quest": mapQuest
    };

    var overlays = {
        "2010 Tracts": tracts2010,
        "2000 Tracts": tracts2000
    };

    L.control.layers(baseLayers, overlays).addTo(map);
  });

}());
<commit_msg>try-catch to handle missing population item preventing polygons showing<commit_after>(function () {
  var map = new L.Map('map').setView([42.354, -71.065], 14);
  var mapQuest = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg', {
    attribution: 'Tiles Courtesy of MapQuest — Map data © OpenStreetMap contributors, CC-BY-SA',
    subdomains: '1234'
  }).addTo(map);

  var censusData;
  L.Util.ajax('geodata/allcensusacsdata.json').then(function(data) {
	  censusData = data;

    var tracts2010 = L.geoJson.ajax("geodata/tracts2010.json",{
          middleware:function(data){
            return topojson.feature(data, data.objects.tracts2010);
          },
        style: function(feature){
          var featureId = feature.id;
          try {
            var d = censusData[2008][featureId].totalpop;
          } catch (e) {
            console.log(e);
          }
          var fill = d > 5944 ? '#800026' :
                   d > 5323  ? '#BD0026' :
                   d > 4777  ? '#E31A1C' :
                   d > 4146  ? '#FC4E2A' :
                   d > 3552   ? '#FD8D3C' :
                   d > 2970   ? '#FEB24C' :
                   d > 2215   ? '#FED976' :
                              '#FFEDA0';

          return {
          weight: 1,
          color: "#ff0000",
          fillColor: fill
        };
      }
      }).addTo(map);
      var tracts2000 = L.geoJson.ajax("geodata/tracts2000.json",{
          middleware:function(data){
            return topojson.feature(data, data.objects.tracts2000);
          },
        style: function(feature){
          var featureId = feature.id;
        var d = censusData[2000][featureId].totalpop;
        var fill = d > 5944 ? '#800026' :
                 d > 5323  ? '#BD0026' :
                 d > 4777  ? '#E31A1C' :
                 d > 4146  ? '#FC4E2A' :
                 d > 3552   ? '#FD8D3C' :
                 d > 2970   ? '#FEB24C' :
                 d > 2215   ? '#FED976' :
                            '#FFEDA0';

          return {
          weight: 1,
          color: "#ff0000",
          fillColor: fill
        };
        }
      });

    var baseLayers = {
      "Map Quest": mapQuest
    };

    var overlays = {
        "2010 Tracts": tracts2010,
        "2000 Tracts": tracts2000
    };

    L.control.layers(baseLayers, overlays).addTo(map);
  });

}());
<|endoftext|>


<commit_before>// metaConfirm.js

var exports = module.exports = {};

var request = require('request');

function findInPage(completeUrl, searchMetaType, searchTag, searchContent, cb) {
    "use strict";

    if (completeUrl === null) {
        cb(new Error("url cannot be null"), null);
        return;
    }

    if (searchTag === null) {
        cb(new Error("searchTag cannot be null"), null);
        return;
    }

    if (searchContent === null) {
        cb(new Error("searchContent cannot be null"), null);
        return;
    }

    if (searchMetaType === null) {
        cb(new Error("searchMetaType cannot be null"), null);
        return;
    }

    request.get(completeUrl, function (error, response, body) {

                if (error) {
                    cb(error, null);

                }
                else {

                    var cnt = countMatchesInString(body, searchMetaType, searchTag, searchContent);

                    if (cnt === 1) {
                        cb(null, false);
                    }
                    else {
                        cb(null, true);

                    }

                }
            }
    );

}

function countMatchesInString(body, searchMetaType, searchTag, searchContent) {
    "use strict";

    var specificTag = '<meta ' + searchMetaType + '="' + searchTag + '" content="' + searchContent + '">';

    return body.split(specificTag).length;

}

exports.FindInPage = findInPage;
<commit_msg>sendBackAnError method created to start refactoring<commit_after>// metaConfirm.js

var exports = module.exports = {};

var request = require('request');

function findInPage(completeUrl, searchMetaType, searchTag, searchContent, cb) {
    "use strict";

    var sendBackAnError = function (cb, errorMessage) {

        cb(new Error(errorMessage), null);

    };

    if (completeUrl === null) {

        sendBackAnError(cb, "url cannot be null");
        return;

    }

    if (searchTag === null) {
        sendBackAnError(cb, "searchTag cannot be null");
        return;
    }

    if (searchContent === null) {
        sendBackAnError(cb, "searchContent cannot be null");
        return;
    }

    if (searchMetaType === null) {
        sendBackAnError(cb, "searchMetaType cannot be null");
        return;
    }

    request.get(completeUrl, function (error, response, body) {

                if (error) {
                    cb(error, null);

                }
                else {

                    var cnt = countMatchesInString(body, searchMetaType, searchTag, searchContent);

                    if (cnt === 1) {
                        cb(null, false);
                    }
                    else {
                        cb(null, true);

                    }

                }
            }
    );

}

function countMatchesInString(body, searchMetaType, searchTag, searchContent) {
    "use strict";

    var specificTag = '<meta ' + searchMetaType + '="' + searchTag + '" content="' + searchContent + '">';

    return body.split(specificTag).length;

}

exports.FindInPage = findInPage;
<|endoftext|>


<commit_before>if (Meteor.isServer) {

  Projects.remove({url:"localhost:007"});
  Projects.remove({url:"localhost:2999"});
  Projects.insert({url:"localhost:2999"});
  Projects.remove({url:"localhost:3000"});
  Projects.insert({url:"localhost:3000"});

  Meteor.methods({
    addCount: function (clientUrl) {
      var host = clientUrl.split("/")[2];
      console.log('[count]', host);
      Projects.update({url:host}, {$inc:{visits: 1}});
      var project = Projects.findOne({url:host});
      console.log("[count] => proj", project);
      return project;
    }
  });
  //console.log("test", Projects.find({url:"http://localhost:007/test"}));
}

// client-side code moved to /count/test
<commit_msg>removed inserts of "localhost" projects + upserts projects on counter call (instead of update, until the project creation page exists)<commit_after>if (Meteor.isServer) {

  Projects.remove({url:"localhost:007"});
  Projects.remove({url:"localhost:2999"});
  //Projects.insert({url:"localhost:2999"});
  Projects.remove({url:"localhost:3000"});
  //Projects.insert({url:"localhost:3000"});

  Meteor.methods({
    addCount: function (clientUrl) {
      var host = clientUrl.split("/")[2];
      console.log('[count]', host);
      Projects.upsert({url:host}, {$inc:{visits: 1}});
      var project = Projects.findOne({url:host});
      console.log("[count] => proj", project);
      return project;
    }
  });
  //console.log("test", Projects.find({url:"http://localhost:007/test"}));
}

// client-side code moved to /count/test
<|endoftext|>


<commit_before>Electrify = {};

var callbacks = {};
var socket;
var where;

Meteor.startup(function(){

  if(Meteor.isServer) {
    where = 'server';
    SockJS = Npm.require('sockjs-client');
    Meteor.methods({
      'electrify.get.socket.port': function(){
        return process.env.SOCKET_PORT || null;
      }
    });

    connect(process.env.SOCKET_PORT);
  }

  if(Meteor.isClient) {
    where = 'client';
    SockJS = SockJS || window.SockJS;
    Meteor.call('electrify.get.socket.port', [], function(error, port){
      connect(port);
    });
  }

});

function log(){
  var args = Array.prototype.slice.call(arguments);
  console.log('electrify:meteor:index@'+ where +':', args.join(' '));
}

function connect(port){

  if(!port) {
    log([
      'cannot initialize connection. Did you `npm install -g electrify`?',
      'install it and try running your meteor app with `electrify` npm command'
    ].join('\n'));
    return;
  }

  socket = new SockJS('http://127.0.0.1:' + port + '/electrify');

  socket.onopen = function() {
    log('connection is open');
    _.each(startup_callbacks, function(ready) {
      ready();
    });
    startup_callbacks = [];
  };

  socket.onmessage = function(e) {
    var packet = JSON.parse(e.data);
    var done;

    if((done = callbacks[packet.handshake])) {
      callbacks[packet.handshake] = null;
      delete callbacks[packet.handshake];
      done.apply(null, [].concat(packet.args.error, packet.args));
    }
    else
      done.apply(null, [
        'No callback defined for handshake `'+ packet.handshake +'`'
      ]);
  };

  socket.onclose = function() {
    log('closing connection', JSON.stringify(_.toArray(arguments), null, 2));
  };
}

var startup_callbacks = [];
Electrify.startup = function(ready){
  startup_callbacks.push(ready);
};

Electrify.call = function(method, args, done) {

  if(!(done instanceof Function))
    throw new Error('Third argument to `Electrify.call()` must be a funciton');

  if(!socket) {
    var msg = 'Cannot call methods, socket connection not initialized';
    console.warn(msg);
    setTimeout(function(){ done(new Error(msg)); }, 1);
    return;
  }

  var packet = {
    handshake: Random.id(),
    method: method,
    args: args
  };

  callbacks[packet.handshake] = done;
  socket.send(JSON.stringify(packet));
};
<commit_msg>fixing typo in error param<commit_after>Electrify = {};

var callbacks = {};
var socket;
var where;

Meteor.startup(function(){

  if(Meteor.isServer) {
    where = 'server';
    SockJS = Npm.require('sockjs-client');
    Meteor.methods({
      'electrify.get.socket.port': function(){
        return process.env.SOCKET_PORT || null;
      }
    });

    connect(process.env.SOCKET_PORT);
  }

  if(Meteor.isClient) {
    where = 'client';
    SockJS = SockJS || window.SockJS;
    Meteor.call('electrify.get.socket.port', [], function(error, port){
      connect(port);
    });
  }

});

function log(){
  var args = Array.prototype.slice.call(arguments);
  console.log('electrify:meteor:index@'+ where +':', args.join(' '));
}

function connect(port){

  if(!port) {
    log([
      'cannot initialize connection. Did you `npm install -g electrify`?',
      'install it and try running your meteor app with `electrify` npm command'
    ].join('\n'));
    return;
  }

  socket = new SockJS('http://127.0.0.1:' + port + '/electrify');

  socket.onopen = function() {
    log('connection is open');
    _.each(startup_callbacks, function(ready) {
      ready();
    });
    startup_callbacks = [];
  };

  socket.onmessage = function(e) {
    var packet = JSON.parse(e.data);
    var done;

    if((done = callbacks[packet.handshake])) {
      callbacks[packet.handshake] = null;
      delete callbacks[packet.handshake];
      done.apply(null, [].concat(packet.error, packet.args));
    }
    else
      done.apply(null, [
        'No callback defined for handshake `'+ packet.handshake +'`'
      ]);
  };

  socket.onclose = function() {
    log('closing connection', JSON.stringify(_.toArray(arguments), null, 2));
  };
}

var startup_callbacks = [];
Electrify.startup = function(ready){
  startup_callbacks.push(ready);
};

Electrify.call = function(method, args, done) {

  if(!(done instanceof Function))
    throw new Error('Third argument to `Electrify.call()` must be a funciton');

  if(!socket) {
    var msg = 'Cannot call methods, socket connection not initialized';
    console.warn(msg);
    setTimeout(function(){ done(new Error(msg)); }, 1);
    return;
  }

  var packet = {
    handshake: Random.id(),
    method: method,
    args: args
  };

  callbacks[packet.handshake] = done;
  socket.send(JSON.stringify(packet));
};
<|endoftext|>