<commit_before>// load type definitions that come with Cypress module
/// <reference types="cypress" />

/**
 * @param {string} path
 */
function visitAndCheckUrl (path) {
  cy.visit(path)
  cy.wait(2000)
  cy.url().should('include', path)
}
describe('Reminders', function () {
  /**
   * @param {string} variableCategoryName
   */
  function goToCategoryInbox (variableCategoryName) {
    visitAndCheckUrl(`/#/app/reminders-inbox?variableCategoryName=${variableCategoryName}`)
    cy.get('#TodayReminders', { timeout: 40000 }).should('exist')
    cy.get('#TodayReminders').children().should('have.length.above', 0)
  }
  /**
   * @param {string} frequency
   */
  function setFrequency (frequency) {
    cy.log(`Setting frequency to ${frequency}`)
    cy.get('#frequencySelectorMaterial').click()
      cy.get('md-option').contains(frequency).click({force: true})
  }
  /**
   * @param {number} hour
   * @param {number} minute
   * @param {string} ampm
   */
  function setReminderTime (hour, minute, ampm) {
    cy.log(`Change to ${hour}:${minute} ${ampm} (We want this to be slightly later than other reminders so its always at the top of ` +
            'the reminder inbox.  (Warning: This will fail for 15 minutes every day)')
    cy.get('#materialFirstReminderStartTime', { timeout: 30000 }).click({ force: true })
    cy.get('.dtp-picker-time').contains(hour).click()
    cy.wait(1000)
    cy.get('a').contains(ampm).click()
    cy.wait(1000)
    cy.get('.dtp-picker-time').contains(minute).click()
    cy.wait(1000)
    cy.get('.dtp-btn-ok').contains('OK').click()
    cy.wait(1000)
  }
  function deleteReminders () {
    cy.log('Deleting reminders...')
    cy.wait(1000)
    let reminderListSelector = '#remindersList > div'
    let deleted = false

    cy.get(reminderListSelector, { timeout: 30000 })
    // eslint-disable-next-line no-unused-vars
            .each(($el, _index, _$list) => {
              let html = $el.html() // $el is a wrapped jQuery element

              if (html.indexOf('showActionSheet') !== -1 && $el.is('visible')) {
                cy.log(`Deleting ${$el.text()} reminder`)
                cy.wrap($el).click()
                cy.clickActionSheetButtonContaining('Delete')
                deleted = true
              } else {
                // It's a header
              }
            })
    if (deleted) {
      cy.log('Waiting for deletions to post...')
      cy.wait(5000)
    }
  }
  /**
   * @param {string} unitName
   */
  function changeUnit (unitName) {
    cy.log(`Changing unit to ${unitName}`)
    cy.get('#unitSelectorMaterial').click()
    cy.get('md-option').contains(unitName).click({ force: true })
  }
  /**
   * @param {string} variableName
   * @param {string} [frequency]
   */
  function addReminder (variableName, frequency) {
    cy.log(`Click Add new reminder for ${variableName}`)
    cy.get('#addReminderButton').click({ force: true })
    cy.searchAndClickTopResult(variableName, true)
    cy.get('#reminder-header').should('contain', variableName)
    if (frequency) {
      setFrequency(frequency)
    }
  }
  /**
   * @param {string} variableCategoryName
   */
  function getManagePathForCategory (variableCategoryName) {
    return `/#/app/variable-list-category/${variableCategoryName}`
  }
  /**
   * @param {string} variableName
   * @param {string} frequency
   * @param {string} variableCategoryName
   */
  function deleteRemindersAddOneAndGoToCategoryInbox (variableName, frequency, variableCategoryName) {
    deleteReminders()
    addReminder(variableName, frequency)
    saveReminderAndGoToCategoryInbox(variableCategoryName)
  }
  /**
   * @param {string} variableCategoryName
   */
  function saveReminderAndGoToCategoryInbox (variableCategoryName) {
    cy.get('#saveButton').click({ force: true })
    cy.wait(25000) // Have to wait for save to complete
    goToCategoryInbox(variableCategoryName)
  }
  it.skip('Create a nutrient reminder and skip it', function () {
    let variableName = 'Aaa Test Reminder Skip'
    let variableCategoryName = 'Nutrients'
    let frequency = '30 minutes'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#notification-skip').click({ force: true })
    cy.get('#notification-skip').should('not.exist')
    cy.visit(manageUrl)
    deleteReminders()
  })
  it.skip('Creates a sleep reminder and changes unit', function () {
    let variableName = 'Sleep Duration'
    let variableCategoryName = 'Sleep'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteReminders()
    addReminder(variableName)
    cy.get('#defaultValue').should('not.exist')
    let hour = 8
    let minute = 15
    let ampm = 'AM'

    setReminderTime(hour, minute, ampm)
    cy.get('#saveButton').click({ force: true })
    cy.visit(manageUrl)
    cy.log('Should not contain reminder time because the frequency is below a day')
    //let firstReminderTime = '#remindersList > div > div > div:nth-child(1) > div.col.col-70 > p';
    let firstReminderTime = '#remindersList'
    let time = `${hour}:${minute}`

    //assertReminderListContains(time);
    cy.get(firstReminderTime).should('contain', time)
    cy.wait(25000) // Have to wait for save to complete
    goToCategoryInbox(variableCategoryName)
    cy.get('#notification-settings').click({ force: true })
    cy.url().should('include', '#/app/reminder-add/')
    cy.get('#reminder-header').should('contain', variableName)
    changeUnit('Minutes')
    saveReminderAndGoToCategoryInbox(variableCategoryName)
    cy.log('Click Record different value/time')
    cy.get('#other-value-time-note-button').click({ force: true })
    cy.url().should('include', '#/app/measurement-add')
    //cy.get('#measurementAddCard > div', {timeout: 10000}).should('contain', variableName);
    //cy.get('#defaultValue').type("480", {force: true});
    cy.visit(manageUrl)
    deleteReminders()
  })
  it('Deletes reminders', function () {
    let path = getManagePathForCategory('Sleep')

    cy.loginWithAccessTokenIfNecessary(path, true)
    deleteReminders()
  })
  it.skip('Creates a food reminder and snoozes it', function () {
    let variableName = 'Aaa Test Reminder Snooze'
    let variableCategoryName = 'Foods'
    let frequency = '30 minutes'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#notification-snooze').click({ force: true })
    cy.get('#notification-snooze').should('not.exist')
    cy.visit(manageUrl)
    deleteReminders()
  })
  it('Creates a symptoms reminder and tracks it', function () {
    let variableName = 'Aaa Test Reminder Variable'
    let variableCategoryName = 'Symptoms'
    let manageUrl = getManagePathForCategory(variableCategoryName)
    let frequency = '30 minutes'

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#negativeRatingOptions4').click({ force: true })
    cy.visit(`/#/app/charts/${variableName}`)
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('History')
    cy.get('#historyItemTitle', { timeout: 30000 })
            .should('contain', `4/5 ${variableName}`)
    cy.get('#historyItemTitle').click({ force: true })
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('Analysis Settings')
    cy.get('#variableName', { timeout: 30000 }).should('contain', variableName)
    cy.log('Waiting for action sheet button to update...')
    cy.wait(5000)
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('Delete All')
    cy.get('#yesButton').click({ force: true })
    cy.visit(manageUrl)
    cy.wait(15000)
    deleteReminders()
  })
  it.skip('Selects a reminder time', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    setReminderTime(8, 15, 'AM')
  })
  it('Sets frequency to 30 minutes', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    setFrequency('30 minutes')
  })
  it('Changes unit', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    changeUnit('Minutes')
  })
})
<commit_msg>it.skip('Creates a symptoms reminder and tracks it'<commit_after>// load type definitions that come with Cypress module
/// <reference types="cypress" />

/**
 * @param {string} path
 */
function visitAndCheckUrl (path) {
  cy.visit(path)
  cy.wait(2000)
  cy.url().should('include', path)
}
describe('Reminders', function () {
  /**
   * @param {string} variableCategoryName
   */
  function goToCategoryInbox (variableCategoryName) {
    visitAndCheckUrl(`/#/app/reminders-inbox?variableCategoryName=${variableCategoryName}`)
    cy.get('#TodayReminders', { timeout: 40000 }).should('exist')
    cy.get('#TodayReminders').children().should('have.length.above', 0)
  }
  /**
   * @param {string} frequency
   */
  function setFrequency (frequency) {
    cy.log(`Setting frequency to ${frequency}`)
    cy.get('#frequencySelectorMaterial').click()
      cy.get('md-option').contains(frequency).click({force: true})
  }
  /**
   * @param {number} hour
   * @param {number} minute
   * @param {string} ampm
   */
  function setReminderTime (hour, minute, ampm) {
    cy.log(`Change to ${hour}:${minute} ${ampm} (We want this to be slightly later than other reminders so its always at the top of ` +
            'the reminder inbox.  (Warning: This will fail for 15 minutes every day)')
    cy.get('#materialFirstReminderStartTime', { timeout: 30000 }).click({ force: true })
    cy.get('.dtp-picker-time').contains(hour).click()
    cy.wait(1000)
    cy.get('a').contains(ampm).click()
    cy.wait(1000)
    cy.get('.dtp-picker-time').contains(minute).click()
    cy.wait(1000)
    cy.get('.dtp-btn-ok').contains('OK').click()
    cy.wait(1000)
  }
  function deleteReminders () {
    cy.log('Deleting reminders...')
    cy.wait(1000)
    let reminderListSelector = '#remindersList > div'
    let deleted = false

    cy.get(reminderListSelector, { timeout: 30000 })
    // eslint-disable-next-line no-unused-vars
            .each(($el, _index, _$list) => {
              let html = $el.html() // $el is a wrapped jQuery element

              if (html.indexOf('showActionSheet') !== -1 && $el.is('visible')) {
                cy.log(`Deleting ${$el.text()} reminder`)
                cy.wrap($el).click()
                cy.clickActionSheetButtonContaining('Delete')
                deleted = true
              } else {
                // It's a header
              }
            })
    if (deleted) {
      cy.log('Waiting for deletions to post...')
      cy.wait(5000)
    }
  }
  /**
   * @param {string} unitName
   */
  function changeUnit (unitName) {
    cy.log(`Changing unit to ${unitName}`)
    cy.get('#unitSelectorMaterial').click()
    cy.get('md-option').contains(unitName).click({ force: true })
  }
  /**
   * @param {string} variableName
   * @param {string} [frequency]
   */
  function addReminder (variableName, frequency) {
    cy.log(`Click Add new reminder for ${variableName}`)
    cy.get('#addReminderButton').click({ force: true })
    cy.searchAndClickTopResult(variableName, true)
    cy.get('#reminder-header').should('contain', variableName)
    if (frequency) {
      setFrequency(frequency)
    }
  }
  /**
   * @param {string} variableCategoryName
   */
  function getManagePathForCategory (variableCategoryName) {
    return `/#/app/variable-list-category/${variableCategoryName}`
  }
  /**
   * @param {string} variableName
   * @param {string} frequency
   * @param {string} variableCategoryName
   */
  function deleteRemindersAddOneAndGoToCategoryInbox (variableName, frequency, variableCategoryName) {
    deleteReminders()
    addReminder(variableName, frequency)
    saveReminderAndGoToCategoryInbox(variableCategoryName)
  }
  /**
   * @param {string} variableCategoryName
   */
  function saveReminderAndGoToCategoryInbox (variableCategoryName) {
    cy.get('#saveButton').click({ force: true })
    cy.wait(25000) // Have to wait for save to complete
    goToCategoryInbox(variableCategoryName)
  }
  it.skip('Create a nutrient reminder and skip it', function () {
    let variableName = 'Aaa Test Reminder Skip'
    let variableCategoryName = 'Nutrients'
    let frequency = '30 minutes'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#notification-skip').click({ force: true })
    cy.get('#notification-skip').should('not.exist')
    cy.visit(manageUrl)
    deleteReminders()
  })
  it.skip('Creates a sleep reminder and changes unit', function () {
    let variableName = 'Sleep Duration'
    let variableCategoryName = 'Sleep'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteReminders()
    addReminder(variableName)
    cy.get('#defaultValue').should('not.exist')
    let hour = 8
    let minute = 15
    let ampm = 'AM'

    setReminderTime(hour, minute, ampm)
    cy.get('#saveButton').click({ force: true })
    cy.visit(manageUrl)
    cy.log('Should not contain reminder time because the frequency is below a day')
    //let firstReminderTime = '#remindersList > div > div > div:nth-child(1) > div.col.col-70 > p';
    let firstReminderTime = '#remindersList'
    let time = `${hour}:${minute}`

    //assertReminderListContains(time);
    cy.get(firstReminderTime).should('contain', time)
    cy.wait(25000) // Have to wait for save to complete
    goToCategoryInbox(variableCategoryName)
    cy.get('#notification-settings').click({ force: true })
    cy.url().should('include', '#/app/reminder-add/')
    cy.get('#reminder-header').should('contain', variableName)
    changeUnit('Minutes')
    saveReminderAndGoToCategoryInbox(variableCategoryName)
    cy.log('Click Record different value/time')
    cy.get('#other-value-time-note-button').click({ force: true })
    cy.url().should('include', '#/app/measurement-add')
    //cy.get('#measurementAddCard > div', {timeout: 10000}).should('contain', variableName);
    //cy.get('#defaultValue').type("480", {force: true});
    cy.visit(manageUrl)
    deleteReminders()
  })
  it('Deletes reminders', function () {
    let path = getManagePathForCategory('Sleep')

    cy.loginWithAccessTokenIfNecessary(path, true)
    deleteReminders()
  })
  it.skip('Creates a food reminder and snoozes it', function () {
    let variableName = 'Aaa Test Reminder Snooze'
    let variableCategoryName = 'Foods'
    let frequency = '30 minutes'
    let manageUrl = getManagePathForCategory(variableCategoryName)

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#notification-snooze').click({ force: true })
    cy.get('#notification-snooze').should('not.exist')
    cy.visit(manageUrl)
    deleteReminders()
  })
  it.skip('Creates a symptoms reminder and tracks it', function () {
    let variableName = 'Aaa Test Reminder Variable'
    let variableCategoryName = 'Symptoms'
    let manageUrl = getManagePathForCategory(variableCategoryName)
    let frequency = '30 minutes'

    cy.loginWithAccessTokenIfNecessary(manageUrl)
    deleteRemindersAddOneAndGoToCategoryInbox(variableName, frequency, variableCategoryName)
    cy.get('#negativeRatingOptions4').click({ force: true })
    cy.visit(`/#/app/charts/${variableName}`)
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('History')
    cy.get('#historyItemTitle', { timeout: 30000 })
            .should('contain', `4/5 ${variableName}`)
    cy.get('#historyItemTitle').click({ force: true })
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('Analysis Settings')
    cy.get('#variableName', { timeout: 30000 }).should('contain', variableName)
    cy.log('Waiting for action sheet button to update...')
    cy.wait(5000)
    cy.get('#menu-more-button').click({ force: true })
    cy.clickActionSheetButtonContaining('Delete All')
    cy.get('#yesButton').click({ force: true })
    cy.visit(manageUrl)
    cy.wait(15000)
    deleteReminders()
  })
  it.skip('Selects a reminder time', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    setReminderTime(8, 15, 'AM')
  })
  it('Sets frequency to 30 minutes', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    setFrequency('30 minutes')
  })
  it('Changes unit', function () {
    cy.loginWithAccessTokenIfNecessary('/#/app/reminder-add/', false)
    changeUnit('Minutes')
  })
})
<|endoftext|>


<commit_before>/**
 * @file ArrowStepItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

class ArrowStepItem extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.touchTapHandler = ::this.touchTapHandler;

    }

    touchTapHandler(e) {
        e.preventDefault();
        const {isActivatedStep, isFinishedStep, index, onClick} = this.props;
        !isActivatedStep && isFinishedStep && onClick && onClick(index, e);
    }

    render() {

        const {className, style, isActivatedStep, isFinishedStep, index, value, isFirst, isLast} = this.props,

            itemClassName = classNames('arrow-step-item',
                isActivatedStep ? 'activated' : (isFinishedStep ? 'finished' : ''), {
                    first: isFirst,
                    last: isLast,
                    [className]: className
                }),

            triangleClassName = isActivatedStep ? 'activated' : (isFinishedStep ? 'finished' : ''),
            triangleTopClassName = classNames('triangle-top', triangleClassName),
            triangleMiddleClassName = classNames('triangle-middle', triangleClassName),
            triangleBottomClassName = classNames('triangle-bottom', triangleClassName);

        return (

                        {index + 1}

                        {value.title}

                {
                    isFirst ?
                        null
                        :

                }

                {
                    isLast ?
                        null
                        :

                }

        );

    }
}

ArrowStepItem.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    index: PropTypes.number,
    isActivatedStep: PropTypes.bool,
    isFinishedStep: PropTypes.bool,
    value: PropTypes.object,

    isFirst: PropTypes.bool,
    isLast: PropTypes.bool,

    onClick: PropTypes.func

};

ArrowStepItem.defaultProps = {

    index: 0,
    isActivatedStep: false,
    isFinishedStep: false,

    isFirst: true,
    isLast: true

};

export default ArrowStepItem;<commit_msg>update ArrowStepItem<commit_after>/**
 * @file ArrowStepItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

class ArrowStepItem extends Component {

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    touchTapHandler = e => {
        e.preventDefault();
        const {isActivatedStep, isFinishedStep, index, onClick} = this.props;
        !isActivatedStep && isFinishedStep && onClick && onClick(index, e);
    };

    render() {

        const {className, style, isActivatedStep, isFinishedStep, index, value, isFirst, isLast} = this.props,

            itemClassName = classNames('arrow-step-item',
                isActivatedStep ? 'activated' : (isFinishedStep ? 'finished' : ''), {
                    first: isFirst,
                    last: isLast,
                    [className]: className
                }),

            triangleClassName = isActivatedStep ? 'activated' : (isFinishedStep ? 'finished' : ''),
            triangleTopClassName = classNames('triangle-top', triangleClassName),
            triangleMiddleClassName = classNames('triangle-middle', triangleClassName),
            triangleBottomClassName = classNames('triangle-bottom', triangleClassName);

        return (

                        {index + 1}

                        {value.title}

                {
                    isFirst ?
                        null
                        :

                }

                {
                    isLast ?
                        null
                        :

                }

        );

    }
}

ArrowStepItem.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    index: PropTypes.number,
    isActivatedStep: PropTypes.bool,
    isFinishedStep: PropTypes.bool,
    value: PropTypes.object,

    isFirst: PropTypes.bool,
    isLast: PropTypes.bool,

    onClick: PropTypes.func

};

ArrowStepItem.defaultProps = {

    index: 0,
    isActivatedStep: false,
    isFinishedStep: false,

    isFirst: true,
    isLast: true

};

export default ArrowStepItem;<|endoftext|>


<commit_before>const tabListener = require('binary-style').tabListener;
const sidebar     = require('binary-style').sidebarCollapsible;
const localize    = require('../../_common/localize').localize;
const urlParam    = require('../../_common/url').param;
const TNCApproval = require('../../app/pages/user/tnc_approval');

const TermsAndConditions = (() => {
    let sidebar_width;

    const onLoad = () => {
        const container = document.getElementsByClassName('sidebar-collapsible-container')[0];
        if (container) sidebar_width = container.offsetWidth;

        handleActiveTab();
        TNCApproval.requiresTNCApproval(
            $('#btn_accept'),
            () => { $('.tnc_accept').setVisibility(1); },
            () => { $('#tnc_accept').html(localize('Your settings have been updated successfully.')); });
        tabListener();
        sidebar();

        handleSidebar();
        checkWidth();
        window.onresize = checkWidth;

        $('.currentYear').text(new Date().getFullYear());
    };

    const handleActiveTab = () => {
        const params      = window.location.hash.split('&');
        const hash        = params[0] || '#legal';
        const sub_content = params[1];
        const menu        = '.tab-menu-wrap';
        const content     = '.tab-content-wrapper';

        const parent_active = 'active';
        const child_active  = 'a-active';

        $(menu)
            .find('li')
            .removeClass(parent_active)
            .find('span')
            .removeClass(child_active);

        let $tab_to_show = $(hash);
        // if hash is a subtab or has subtabs
        if ($tab_to_show.find('.tm-li-2').length > 0 || /tm-li-2/.test($(hash).attr('class'))) {
            $tab_to_show =
                $tab_to_show
                    .find('.tm-a-2')
                    .first()
                    .addClass(child_active)
                    .closest('.tm-li');
        }
        $tab_to_show.addClass(parent_active);

        let content_to_show = `div${hash}-content`;
        if ($(content_to_show).length === 0) {
            content_to_show = `div#${$(hash).find('.tm-li-2').first().attr('id')}-content`;
        }
        $(content)
            .find('> div')
            .setVisibility(0)
            .end()
            .find(content_to_show)
            .setVisibility(1);

        const section  = urlParam('section');
        const $content = $('#content');
        if (section) {
            const $section = $content.find(`a#${section}`);
            if ($section.length) setTimeout(() => { $.scrollTo($section, 0, { offset: -5 }); }, 500);
        } else if (hash) {
            setTimeout(() => { $.scrollTo($content.find('.tab-menu'), 0, { offset: -10 }); }, 500);
        }
        if (sub_content) {
            setTimeout(() => { $.scrollTo($content.find(`#${sub_content}`), 500, { offset: -10 }); }, 500);
        }
    };

    const handleSidebar = () => {
        const hash     = window.location.hash || '#legal';
        const $sidebar = $('.sidebar-collapsible');
        const $content = $('.sidebar-collapsible-content');

        const is_submenu = /-binary|-mt/.test(hash);
        if (is_submenu) {
            let parent_hash = hash;
            if (/-binary/.test(hash)) {
                parent_hash = hash.split('-binary')[0];
            } else if (/-mt/.test(hash)) {
                parent_hash = hash.split('-mt')[0];
            }
            $sidebar.find(`${hash} a:first`).trigger('click');  // click submenu
        } else {
            $sidebar.find(`${hash} a:first`).trigger('click');
        }
    };

    const checkWidth = () => {
        const mq = window.matchMedia('(max-width: 1023px)').matches;
        if (mq) {
            $('.sidebar-collapsible').css({ position: 'relative' });
            $(window).off('scroll', stickySidebar);
        } else {
            $(window).on('scroll', stickySidebar);
        }
        return mq;
    };

    const stickySidebar = () => {
        const $sidebar   = $('.sidebar-collapsible');
        const $content   = $('.sidebar-collapsible-content');
        const $container = $('.sidebar-collapsible-container');

        if (!$sidebar.is(':visible')) return;

        if (window.scrollY < $content.offset().top) {
            $sidebar.css({ position: 'relative' });
        } else if (window.scrollY + $sidebar[0].offsetHeight + 20 >=
            $container[0].offsetHeight + $container.offset().top) { // 20 is the padding for content from bottom, to avoid menu snapping back up
            $sidebar.css({ position: 'absolute', bottom: '20px', top: '', width: sidebar_width });
        } else {
            $sidebar.css({ position: 'fixed', top: '0px', bottom: '', width: sidebar_width });
        }
    };

    const onUnload = () => {
        $('.sidebar-collapsible').off('click');
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = TermsAndConditions;
<commit_msg>update handleSidebar according to binary style fix<commit_after>const tabListener = require('binary-style').tabListener;
const sidebar     = require('binary-style').sidebarCollapsible;
const localize    = require('../../_common/localize').localize;
const urlParam    = require('../../_common/url').param;
const TNCApproval = require('../../app/pages/user/tnc_approval');

const TermsAndConditions = (() => {
    let sidebar_width;

    const onLoad = () => {
        const container = document.getElementsByClassName('sidebar-collapsible-container')[0];
        if (container) sidebar_width = container.offsetWidth;

        handleActiveTab();
        TNCApproval.requiresTNCApproval(
            $('#btn_accept'),
            () => { $('.tnc_accept').setVisibility(1); },
            () => { $('#tnc_accept').html(localize('Your settings have been updated successfully.')); });
        tabListener();
        sidebar();

        handleSidebar();
        checkWidth();
        window.onresize = checkWidth;

        $('.currentYear').text(new Date().getFullYear());
    };

    const handleActiveTab = () => {
        const params      = window.location.hash.split('&');
        const hash        = params[0] || '#legal';
        const sub_content = params[1];
        const menu        = '.tab-menu-wrap';
        const content     = '.tab-content-wrapper';

        const parent_active = 'active';
        const child_active  = 'a-active';

        $(menu)
            .find('li')
            .removeClass(parent_active)
            .find('span')
            .removeClass(child_active);

        let $tab_to_show = $(hash);
        // if hash is a subtab or has subtabs
        if ($tab_to_show.find('.tm-li-2').length > 0 || /tm-li-2/.test($(hash).attr('class'))) {
            $tab_to_show =
                $tab_to_show
                    .find('.tm-a-2')
                    .first()
                    .addClass(child_active)
                    .closest('.tm-li');
        }
        $tab_to_show.addClass(parent_active);

        let content_to_show = `div${hash}-content`;
        if ($(content_to_show).length === 0) {
            content_to_show = `div#${$(hash).find('.tm-li-2').first().attr('id')}-content`;
        }
        $(content)
            .find('> div')
            .setVisibility(0)
            .end()
            .find(content_to_show)
            .setVisibility(1);

        const section  = urlParam('section');
        const $content = $('#content');
        if (section) {
            const $section = $content.find(`a#${section}`);
            if ($section.length) setTimeout(() => { $.scrollTo($section, 0, { offset: -5 }); }, 500);
        } else if (hash) {
            setTimeout(() => { $.scrollTo($content.find('.tab-menu'), 0, { offset: -10 }); }, 500);
        }
        if (sub_content) {
            setTimeout(() => { $.scrollTo($content.find(`#${sub_content}`), 500, { offset: -10 }); }, 500);
        }
    };

    const handleSidebar = () => {
        const hash     = window.location.hash || '#legal-binary';
        const $sidebar = $('.sidebar-collapsible');
        $sidebar.find(`${hash} a:first`).trigger('click');
    };

    const checkWidth = () => {
        const mq = window.matchMedia('(max-width: 1023px)').matches;
        if (mq) {
            $('.sidebar-collapsible').css({ position: 'relative' });
            $(window).off('scroll', stickySidebar);
        } else {
            $(window).on('scroll', stickySidebar);
        }
        return mq;
    };

    const stickySidebar = () => {
        const $sidebar   = $('.sidebar-collapsible');
        const $content   = $('.sidebar-collapsible-content');
        const $container = $('.sidebar-collapsible-container');

        if (!$sidebar.is(':visible')) return;

        if (window.scrollY < $content.offset().top) {
            $sidebar.css({ position: 'relative' });
        } else if (window.scrollY + $sidebar[0].offsetHeight + 20 >=
            $container[0].offsetHeight + $container.offset().top) { // 20 is the padding for content from bottom, to avoid menu snapping back up
            $sidebar.css({ position: 'absolute', bottom: '20px', top: '', width: sidebar_width });
        } else {
            $sidebar.css({ position: 'fixed', top: '0px', bottom: '', width: sidebar_width });
        }
    };

    const onUnload = () => {
        $('.sidebar-collapsible').off('click');
    };

    return {
        onLoad,
        onUnload,
    };
})();

module.exports = TermsAndConditions;
<|endoftext|>


<commit_before>const redis = require('redis')
const { promisify } = require('util')
const Log = require('gk-log')
const { flatten } = require('lodash')

const dbs = require('../lib/dbs')
const githubQueue = require('../lib/github-queue')
const { createDocs } = require('../lib/repository-docs')
const GitHub = require('../lib/github')
const getToken = require('../lib/get-token')

module.exports = async function ({ accountId }) {
  const { installations, repositories } = await dbs()
  const logs = dbs.getLogsDb()
  const log = Log({ logsDb: logs, accountId: accountId, repoSlug: null, context: 'sync-repos' })
  log.info(`started`)

  const installation = await installations.get(String(accountId))
  const installationId = installation.installation

  let dbRepos
  let gitHubRepos
  let accountName
  try {
    const repoDoc = await installations.get(String(accountId))
    accountName = repoDoc.login
    const { rows: currentRepos } = await repositories.query('repo-by-org/repo-by-org', {
      key: accountName,
      reduce: false,
      include_docs: true
    })
    dbRepos = currentRepos.map(repo => repo.doc.fullName.split('/')[1])
  } catch (error) {
    log.error('Could not get repos from database', { error: error.message })
  }

  try {
    const { token } = await getToken(Number(installationId))
    const github = GitHub({ auth: `token ${token}` })
    const options = github.apps.listRepos.endpoint.merge({
      headers: {
        accept: 'application/vnd.github.machine-man-preview+json'
      },
      per_page: 100
    })

    // Paginate does not actually flatten results into a single result array
    // as it should, according to the docs, possibly due to these:
    // https://github.com/octokit/rest.js/issues/1161
    // https://github.com/octokit/routes/issues/329
    const results = await github.paginate(options)
    // So we flatten them ourselves
    gitHubRepos = flatten(results.map((result) => result.repositories))
  } catch (error) {
    log.error('Could not get repos from Github', { error: error.message })
  }
  log.info('There are more active repos on GitHub than in our database.')

  // create missing repositories
  let reposToCreate = []
  gitHubRepos.map(ghRepo => {
    if (!dbRepos.includes(ghRepo.name)) {
      reposToCreate.push(ghRepo)
    }
  })

  log.info('Starting to create missing repoDocs')
  try {
    const repoDocs = await createDocs({
      repositories: reposToCreate,
      accountId: String(accountId)
    })
    await repositories.bulkDocs(repoDocs)
  } catch (error) {
    log.warn('Could not create repository', { error: error.message })
  }

  const client = redis.createClient(process.env.REDIS_URL)
  const del = promisify(client.del)
  await del(`sync_${accountName}`)
}
<commit_msg>fix: runtime errors for repo-sync<commit_after>const redis = require('redis')
const { promisify } = require('util')
const Log = require('gk-log')
const { flatten } = require('lodash')

const dbs = require('../lib/dbs')
const { createDocs } = require('../lib/repository-docs')
const GitHub = require('../lib/github')
const getToken = require('../lib/get-token')

module.exports = async function ({ accountId }) {
  const { installations, repositories } = await dbs()
  const logs = dbs.getLogsDb()
  const log = Log({ logsDb: logs, accountId: accountId, repoSlug: null, context: 'sync-repos' })
  log.info(`started`)

  const installation = await installations.get(String(accountId))
  const installationId = installation.installation

  let dbRepos
  let gitHubRepos
  let accountName
  try {
    const repoDoc = await installations.get(String(accountId))
    accountName = repoDoc.login
    const { rows: currentRepos } = await repositories.query('repo-by-org/repo-by-org', {
      key: accountName,
      reduce: false,
      include_docs: true
    })
    dbRepos = currentRepos.map(repo => repo.doc.fullName.split('/')[1])
  } catch (error) {
    log.error('Could not get repos from database', { error: error.message })
  }

  try {
    const { token } = await getToken(Number(installationId))
    const github = GitHub({ auth: `token ${token}` })
    const options = github.apps.listRepos.endpoint.merge({
      headers: {
        accept: 'application/vnd.github.machine-man-preview+json'
      },
      per_page: 100
    })

    // Paginate does not actually flatten results into a single result array
    // as it should, according to the docs, possibly due to these:
    // https://github.com/octokit/rest.js/issues/1161
    // https://github.com/octokit/routes/issues/329
    const results = await github.paginate(options)
    // So we flatten them ourselves
    gitHubRepos = flatten(results.map((result) => result.repositories))
  } catch (error) {
    log.error('Could not get repos from Github', { error: error.message })
  }
  log.info('There are more active repos on GitHub than in our database.')

  // create missing repositories
  let reposToCreate = []
  gitHubRepos.map(ghRepo => {
    if (!dbRepos.includes(ghRepo.name)) {
      reposToCreate.push(ghRepo)
    }
  })

  log.info('Starting to create missing repoDocs')
  try {
    const repoDocs = await createDocs({
      repositories: reposToCreate,
      accountId: String(accountId)
    })
    await repositories.bulkDocs(repoDocs)
  } catch (error) {
    log.warn('Could not create repository', { error: error.message })
  }

  const client = redis.createClient(process.env.REDIS_URL)
  const del = promisify(client.del)
  await del(`sync_${accountName}`)
}
<|endoftext|>


<commit_before>/**
 * jQuery UI PickList Widget
 *
 * Copyright (c) 2012 Jonathon Freeman <jonathon@awnry.com>
 * Distributed under the terms of the MIT License.
 *
 * http://code.google.com/p/jquery-ui-picklist/
 */
(function($)
{
	$.widget("awnry.pickList",
	{
		options:
		{
			// Container classes
			mainClass:                  "pickList",
			listContainerClass:         "pickList_listContainer",
			sourceListContainerClass:   "pickList_sourceListContainer",
			controlsContainerClass:     "pickList_controlsContainer",
			targetListContainerClass:   "pickList_targetListContainer",
			listClass:                  "pickList_list",
			sourceListClass:            "pickList_sourceList",
			targetListClass:            "pickList_targetList",
			clearClass:                 "pickList_clear",

			// List item classes
			listItemClass:              "pickList_listItem",
			richListItemClass:          "pickList_richListItem",
			selectedListItemClass:      "pickList_selectedListItem",

			// Control classes
			addAllClass:                "pickList_addAll",
			addClass:                   "pickList_add",
			removeAllClass:             "pickList_removeAll",
			removeClass:                "pickList_remove",

			// Control labels
			addAllLabel:                ">>",
			addLabel:                   ">",
			removeAllLabel:             "<<",
			removeLabel:                "<",

			// List labels
			listLabelClass:             "pickList_listLabel",
			sourceListLabel:            "Available",
			sourceListLabelClass:       "pickList_sourceListLabel",
			targetListLabel:            "Selected",
			targetListLabelClass:       "pickList_targetListLabel",

			// Sorting
			sortItems:                  true,
			sortAttribute:              "label",

			// Additional list items
			items:						[],
			richItems:                  []     // DEPRECATED -- Use "items" instead.
		},

		_create: function()
		{
			var self = this;

			self._buildPickList();
			self._refresh();
		},

		_buildPickList: function()
		{
			var self = this;

			self.pickList = $("<div/>")
					.hide()
					.addClass(self.options.mainClass)
					.insertAfter(self.element)
					.append(self._buildSourceList())
					.append(self._buildControls())
					.append(self._buildTargetList())
					.append( $("<div/>").addClass(self.options.clearClass) );

			self._populateLists();

			self.element.hide();
			self.pickList.show();
		},

		_buildSourceList: function()
		{
			var self = this;

			var container = $("<div/>")
					.addClass(self.options.listContainerClass)
					.addClass(self.options.sourceListContainerClass)
					.css({
						"-moz-user-select": "none",
						"-webkit-user-select": "none",
						"user-select": "none",
						"-ms-user-select": "none"
					})
					.each(function()
					{
						this.onselectstart = function() { return false; };
					});

			var label = $("<div/>")
					.text(self.options.sourceListLabel)
					.addClass(self.options.listLabelClass)
					.addClass(self.options.sourceListLabelClass);

			self.sourceList = $("<ul/>")
					.addClass(self.options.listClass)
					.addClass(self.options.sourceListClass)
					.delegate("li", "click", {pickList: self}, self._changeHandler);

			container
					.append(label)
					.append(self.sourceList);

			return container;
		},

		_buildTargetList: function()
		{
			var self = this;

			var container = $("<div/>")
					.addClass(self.options.listContainerClass)
					.addClass(self.options.targetListContainerClass)
					.css({
						"-moz-user-select": "none",
						"-webkit-user-select": "none",
						"user-select": "none",
						"-ms-user-select": "none"
					})
					.each(function()
					{
						this.onselectstart = function() { return false; };
					});

			var label = $("<div/>")
					.text(self.options.targetListLabel)
					.addClass(self.options.listLabelClass)
					.addClass(self.options.targetListLabelClass);

			self.targetList = $("<ul/>")
					.addClass(self.options.listClass)
					.addClass(self.options.targetListClass)
					.delegate("li", "click", {pickList: self}, self._changeHandler);

			container
					.append(label)
					.append(self.targetList);

			return container;
		},

		_buildControls: function()
		{
			var self = this;

			self.controls = $("<div/>").addClass(self.options.controlsContainerClass);

			self.addAllButton = $("<button type='button'/>").click({pickList: self}, self._addAllHandler).html(self.options.addAllLabel).addClass(self.options.addAllClass);
			self.addButton = $("<button type='button'/>").click({pickList: self}, self._addHandler).html(self.options.addLabel).addClass(self.options.addClass);
			self.removeButton = $("<button type='button'/>").click({pickList: self}, self._removeHandler).html(self.options.removeLabel).addClass(self.options.removeClass);
			self.removeAllButton = $("<button type='button'/>").click({pickList: self}, self._removeAllHandler).html(self.options.removeAllLabel).addClass(self.options.removeAllClass);

			self.controls
					.append(self.addAllButton)
					.append(self.addButton)
					.append(self.removeButton)
					.append(self.removeAllButton);

			return self.controls;
		},

		_populateLists: function()
		{
			var self = this;

			self.element.children().each(function()
			{
				var text = $(this).text();
				var copy = $("<li/>")
						.text(text)
						.val($(this).val())
						.attr("label", text)
						.addClass(self.options.listItemClass);

				if($(this).attr("selected") == "selected")
				{
					self.targetList.append( copy );
				}
				else
				{
					self.sourceList.append( copy );
				}
			});

			$(self.options.items).each(function()
			{
				self.insert(this);
			});

			$(self.options.richItems).each(function()
			{
				self.insert(this);
			});
		},

		_addItem: function(value)
		{
			var self = this;

			self.sourceList.children("[value='" + value + "']").each(function()
			{
				self.targetList.append( self._removeSelection($(this)) );
			});

			self.element.children("[value='" + value + "']").each(function()
			{
				$(this).attr("selected", "selected");
			});
		},

		_removeItem: function(value)
		{
			var self = this;

			self.targetList.children("[value='" + value + "']").each(function()
			{
				self.sourceList.append( self._removeSelection($(this)) );
			});

			self.element.children("[value='" + value + "']").each(function()
			{
				$(this).removeAttr("selected");
			});
		},

		_addAllHandler: function(e)
		{
			var self = e.data.pickList;

			self.sourceList.children().each(function()
			{
				self._addItem( $(this).val() );
			});

			self._refresh();
		},

		_addHandler: function(e)
		{
			var self = e.data.pickList;

			self.sourceList.children(".ui-selected").each(function()
			{
				self._addItem( $(this).val() );
			});

			self._refresh();
		},

		_removeHandler: function(e)
		{
			var self = e.data.pickList;

			self.targetList.children(".ui-selected").each(function()
			{
				self._removeItem( $(this).val() );
			});

			self._refresh();
		},

		_removeAllHandler: function(e)
		{
			var self = e.data.pickList;

			self.targetList.children().each(function()
			{
				self._removeItem( $(this).val() );
			});

			self._refresh();
		},

		_refresh: function()
		{
			var self = this;

			// Enable/disable the Add All button state.
			if(self.sourceList.children().length)
			{
				self.addAllButton.removeAttr("disabled");
			}
			else
			{
				self.addAllButton.attr("disabled", "disabled");
			}

			// Enable/disable the Remove All button state.
			if(self.targetList.children().length)
			{
				self.removeAllButton.removeAttr("disabled");
			}
			else
			{
				self.removeAllButton.attr("disabled", "disabled");
			}

			// Enable/disable the Add button state.
			if(self.sourceList.children(".ui-selected").length)
			{
				self.addButton.removeAttr("disabled");
			}
			else
			{
				self.addButton.attr("disabled", "disabled");
			}

			// Enable/disable the Remove button state.
			if(self.targetList.children(".ui-selected").length)
			{
				self.removeButton.removeAttr("disabled");
			}
			else
			{
				self.removeButton.attr("disabled", "disabled");
			}

			// Sort the selection lists.
			if(self.options.sortItems)
			{
				self._sortItems(self.sourceList, self.options);
				self._sortItems(self.targetList, self.options);
			}
		},

		_sortItems: function(list, options)
		{
			var items = new Array();

			list.children().each(function()
			{
				items.push( $(this) );
			});

			items.sort(function(a, b)
			{
				if(a.attr(options.sortAttribute) > b.attr(options.sortAttribute))
				{
					return 1;
				}
				else if(a.attr(options.sortAttribute) == b.attr(options.sortAttribute))
				{
					return 0;
				}
				else
				{
					return -1;
				}
			});

			list.empty();

			for(var i = 0; i < items.length; i++)
			{
				list.append(items[i]);
			}
		},

		_changeHandler: function(e)
		{
			var self = e.data.pickList;

			if(e.ctrlKey)
			{
				if(self._isSelected( $(this) ))
				{
					self._removeSelection( $(this) );
				}
				else
				{
					self.lastSelectedItem = $(this);
					self._addSelection( $(this) );
				}
			}
			else if(e.shiftKey)
			{
				var current = $(this).val();
				var last = self.lastSelectedItem.val();

				if($(this).index() < $(self.lastSelectedItem).index())
				{
					var temp = current;
					current = last;
					last = temp;
				}

				var pastStart = false;
				var beforeEnd = true;

				self._clearSelections( $(this).parent() );

				$(this).parent().children().each(function()
				{
					if($(this).val() == last)
					{
						pastStart = true;
					}

					if(pastStart && beforeEnd)
					{
						self._addSelection( $(this) );
					}

					if($(this).val() == current)
					{
						beforeEnd = false;
					}

				});
			}
			else
			{
				self.lastSelectedItem = $(this);
				self._clearSelections( $(this).parent() );
				self._addSelection( $(this) );
			}

			self._refresh();
		},

		_isSelected: function(listItem)
		{
			return listItem.hasClass("ui-selected");
		},

		_addSelection: function(listItem)
		{
			var self = this;

			return listItem
					.addClass("ui-selected")
					.addClass("ui-state-highlight")
					.addClass(self.options.selectedListItemClass);
		},

		_removeSelection: function(listItem)
		{
			var self = this;

			return listItem
					.removeClass("ui-selected")
					.removeClass("ui-state-highlight")
					.removeClass(self.options.selectedListItemClass);
		},

		_clearSelections: function(list)
		{
			var self = this;

			list.children().each(function()
			{
				self._removeSelection( $(this) );
			});
		},

		_setOption: function(key, value)
		{
			switch(key)
			{
				case "clear":
				{
					break;
				}
			}

			$.Widget.prototype._setOption.apply(this, arguments);
		},

		destroy: function()
		{
			var self = this;

			self.pickList.remove();
			self.element.show();

			$.Widget.prototype.destroy.call(self);
		},

		insert: function(item)
		{
			var self = this;

			var list = item.selected ? self.targetList : self.sourceList;
			var selectItem = self._createSelectItem(item);
			var listItem = (item.element == undefined) ? self._createRegularItem(item) : self._createRichItem(item);

			self.element.append(selectItem);
			list.append(listItem);

			self._refresh();
		},

		_createSelectItem: function(item)
		{
			var selectItem = $("<option/>").val(item.value).text(item.label);

			if(item.selected)
			{
				selectItem.attr("selected", "selected");
			}

			return selectItem;
		},

		_createRegularItem: function(item)
		{
			var self = this;

			return $("<li/>")
					.val(item.value)
					.text(item.label)
					.attr("label", item.label)
					.addClass(self.options.listItemClass);
		},

		_createRichItem: function(item)
		{
			var self = this;

			return $("<li/>")
					.val(item.value)
					.attr("label", item.label)
					.addClass(self.options.listItemClass)
					.addClass(self.options.richListItemClass)
					.append(item.element);
		}
	});
}(jQuery));
<commit_msg>* Improved performance of initialization on very large item sets by building items via HTML rather than jQuery functions. * Removed the deprecated (and now defunct) "richItems" option.<commit_after>/**
 * jQuery UI PickList Widget
 *
 * Copyright (c) 2012 Jonathon Freeman <jonathon@awnry.com>
 * Distributed under the terms of the MIT License.
 *
 * http://code.google.com/p/jquery-ui-picklist/
 */
(function($)
{
	$.widget("awnry.pickList",
	{
		options:
		{
			// Container classes
			mainClass:                  "pickList",
			listContainerClass:         "pickList_listContainer",
			sourceListContainerClass:   "pickList_sourceListContainer",
			controlsContainerClass:     "pickList_controlsContainer",
			targetListContainerClass:   "pickList_targetListContainer",
			listClass:                  "pickList_list",
			sourceListClass:            "pickList_sourceList",
			targetListClass:            "pickList_targetList",
			clearClass:                 "pickList_clear",

			// List item classes
			listItemClass:              "pickList_listItem",
			richListItemClass:          "pickList_richListItem",
			selectedListItemClass:      "pickList_selectedListItem",

			// Control classes
			addAllClass:                "pickList_addAll",
			addClass:                   "pickList_add",
			removeAllClass:             "pickList_removeAll",
			removeClass:                "pickList_remove",

			// Control labels
			addAllLabel:                ">>",
			addLabel:                   ">",
			removeAllLabel:             "<<",
			removeLabel:                "<",

			// List labels
			listLabelClass:             "pickList_listLabel",
			sourceListLabel:            "Available",
			sourceListLabelClass:       "pickList_sourceListLabel",
			targetListLabel:            "Selected",
			targetListLabelClass:       "pickList_targetListLabel",

			// Sorting
			sortItems:                  true,
			sortAttribute:              "label",

			// Additional list items
			items:						[]
		},

		_create: function()
		{
			var self = this;

			self._buildPickList();
			self._refresh();
		},

		_buildPickList: function()
		{
			var self = this;

			self.pickList = $("<div/>")
					.hide()
					.addClass(self.options.mainClass)
					.insertAfter(self.element)
					.append(self._buildSourceList())
					.append(self._buildControls())
					.append(self._buildTargetList())
					.append( $("<div/>").addClass(self.options.clearClass) );

			self._populateLists();

			self.element.hide();
			self.pickList.show();
		},

		_buildSourceList: function()
		{
			var self = this;

			var container = $("<div/>")
					.addClass(self.options.listContainerClass)
					.addClass(self.options.sourceListContainerClass)
					.css({
						"-moz-user-select": "none",
						"-webkit-user-select": "none",
						"user-select": "none",
						"-ms-user-select": "none"
					})
					.each(function()
					{
						this.onselectstart = function() { return false; };
					});

			var label = $("<div/>")
					.text(self.options.sourceListLabel)
					.addClass(self.options.listLabelClass)
					.addClass(self.options.sourceListLabelClass);

			self.sourceList = $("<ul/>")
					.addClass(self.options.listClass)
					.addClass(self.options.sourceListClass)
					.delegate("li", "click", {pickList: self}, self._changeHandler);

			container
					.append(label)
					.append(self.sourceList);

			return container;
		},

		_buildTargetList: function()
		{
			var self = this;

			var container = $("<div/>")
					.addClass(self.options.listContainerClass)
					.addClass(self.options.targetListContainerClass)
					.css({
						"-moz-user-select": "none",
						"-webkit-user-select": "none",
						"user-select": "none",
						"-ms-user-select": "none"
					})
					.each(function()
					{
						this.onselectstart = function() { return false; };
					});

			var label = $("<div/>")
					.text(self.options.targetListLabel)
					.addClass(self.options.listLabelClass)
					.addClass(self.options.targetListLabelClass);

			self.targetList = $("<ul/>")
					.addClass(self.options.listClass)
					.addClass(self.options.targetListClass)
					.delegate("li", "click", {pickList: self}, self._changeHandler);

			container
					.append(label)
					.append(self.targetList);

			return container;
		},

		_buildControls: function()
		{
			var self = this;

			self.controls = $("<div/>").addClass(self.options.controlsContainerClass);

			self.addAllButton = $("<button type='button'/>").click({pickList: self}, self._addAllHandler).html(self.options.addAllLabel).addClass(self.options.addAllClass);
			self.addButton = $("<button type='button'/>").click({pickList: self}, self._addHandler).html(self.options.addLabel).addClass(self.options.addClass);
			self.removeButton = $("<button type='button'/>").click({pickList: self}, self._removeHandler).html(self.options.removeLabel).addClass(self.options.removeClass);
			self.removeAllButton = $("<button type='button'/>").click({pickList: self}, self._removeAllHandler).html(self.options.removeAllLabel).addClass(self.options.removeAllClass);

			self.controls
					.append(self.addAllButton)
					.append(self.addButton)
					.append(self.removeButton)
					.append(self.removeAllButton);

			return self.controls;
		},

		_populateLists: function()
		{
			var self = this;

			self.element.children().each(function()
			{
				var text = $(this).text();
				var copy = $("<li/>")
						.text(text)
						.val($(this).val())
						.attr("label", text)
						.addClass(self.options.listItemClass);

				if($(this).attr("selected") == "selected")
				{
					self.targetList.append( copy );
				}
				else
				{
					self.sourceList.append( copy );
				}
			});

			self.insertItems(self.options.items);
		},

		_addItem: function(value)
		{
			var self = this;

			self.sourceList.children("[value='" + value + "']").each(function()
			{
				self.targetList.append( self._removeSelection($(this)) );
			});

			self.element.children("[value='" + value + "']").each(function()
			{
				$(this).attr("selected", "selected");
			});
		},

		_removeItem: function(value)
		{
			var self = this;

			self.targetList.children("[value='" + value + "']").each(function()
			{
				self.sourceList.append( self._removeSelection($(this)) );
			});

			self.element.children("[value='" + value + "']").each(function()
			{
				$(this).removeAttr("selected");
			});
		},

		_addAllHandler: function(e)
		{
			var self = e.data.pickList;

			self.sourceList.children().each(function()
			{
				self._addItem( $(this).val() );
			});

			self._refresh();
		},

		_addHandler: function(e)
		{
			var self = e.data.pickList;

			self.sourceList.children(".ui-selected").each(function()
			{
				self._addItem( $(this).val() );
			});

			self._refresh();
		},

		_removeHandler: function(e)
		{
			var self = e.data.pickList;

			self.targetList.children(".ui-selected").each(function()
			{
				self._removeItem( $(this).val() );
			});

			self._refresh();
		},

		_removeAllHandler: function(e)
		{
			var self = e.data.pickList;

			self.targetList.children().each(function()
			{
				self._removeItem( $(this).val() );
			});

			self._refresh();
		},

		_refresh: function()
		{
			var self = this;

			// Enable/disable the Add All button state.
			if(self.sourceList.children().length)
			{
				self.addAllButton.removeAttr("disabled");
			}
			else
			{
				self.addAllButton.attr("disabled", "disabled");
			}

			// Enable/disable the Remove All button state.
			if(self.targetList.children().length)
			{
				self.removeAllButton.removeAttr("disabled");
			}
			else
			{
				self.removeAllButton.attr("disabled", "disabled");
			}

			// Enable/disable the Add button state.
			if(self.sourceList.children(".ui-selected").length)
			{
				self.addButton.removeAttr("disabled");
			}
			else
			{
				self.addButton.attr("disabled", "disabled");
			}

			// Enable/disable the Remove button state.
			if(self.targetList.children(".ui-selected").length)
			{
				self.removeButton.removeAttr("disabled");
			}
			else
			{
				self.removeButton.attr("disabled", "disabled");
			}

			// Sort the selection lists.
			if(self.options.sortItems)
			{
				self._sortItems(self.sourceList, self.options);
				self._sortItems(self.targetList, self.options);
			}
		},

		_sortItems: function(list, options)
		{
			var items = new Array();

			list.children().each(function()
			{
				items.push( $(this) );
			});

			items.sort(function(a, b)
			{
				if(a.attr(options.sortAttribute) > b.attr(options.sortAttribute))
				{
					return 1;
				}
				else if(a.attr(options.sortAttribute) == b.attr(options.sortAttribute))
				{
					return 0;
				}
				else
				{
					return -1;
				}
			});

			list.empty();

			for(var i = 0; i < items.length; i++)
			{
				list.append(items[i]);
			}
		},

		_changeHandler: function(e)
		{
			var self = e.data.pickList;

			if(e.ctrlKey)
			{
				if(self._isSelected( $(this) ))
				{
					self._removeSelection( $(this) );
				}
				else
				{
					self.lastSelectedItem = $(this);
					self._addSelection( $(this) );
				}
			}
			else if(e.shiftKey)
			{
				var current = $(this).val();
				var last = self.lastSelectedItem.val();

				if($(this).index() < $(self.lastSelectedItem).index())
				{
					var temp = current;
					current = last;
					last = temp;
				}

				var pastStart = false;
				var beforeEnd = true;

				self._clearSelections( $(this).parent() );

				$(this).parent().children().each(function()
				{
					if($(this).val() == last)
					{
						pastStart = true;
					}

					if(pastStart && beforeEnd)
					{
						self._addSelection( $(this) );
					}

					if($(this).val() == current)
					{
						beforeEnd = false;
					}

				});
			}
			else
			{
				self.lastSelectedItem = $(this);
				self._clearSelections( $(this).parent() );
				self._addSelection( $(this) );
			}

			self._refresh();
		},

		_isSelected: function(listItem)
		{
			return listItem.hasClass("ui-selected");
		},

		_addSelection: function(listItem)
		{
			var self = this;

			return listItem
					.addClass("ui-selected")
					.addClass("ui-state-highlight")
					.addClass(self.options.selectedListItemClass);
		},

		_removeSelection: function(listItem)
		{
			var self = this;

			return listItem
					.removeClass("ui-selected")
					.removeClass("ui-state-highlight")
					.removeClass(self.options.selectedListItemClass);
		},

		_clearSelections: function(list)
		{
			var self = this;

			list.children().each(function()
			{
				self._removeSelection( $(this) );
			});
		},

		_setOption: function(key, value)
		{
			switch(key)
			{
				case "clear":
				{
					break;
				}
			}

			$.Widget.prototype._setOption.apply(this, arguments);
		},

		destroy: function()
		{
			var self = this;

			self.pickList.remove();
			self.element.show();

			$.Widget.prototype.destroy.call(self);
		},

		insert: function(item)
		{
			var self = this;

			var list = item.selected ? self.targetList : self.sourceList;
			var selectItem = self._createSelectItem(item);
			var listItem = (item.element == undefined) ? self._createRegularItem(item) : self._createRichItem(item);

			self.element.append(selectItem);
			list.append(listItem);

			self._refresh();
		},

		insertItems: function(items)
		{
			var self = this;

			var selectItems = [];
			var sourceItems = [];
			var targetItems = [];

			$(items).each(function()
			{
				var selectItem = self._createSelectItem(this);
				var listItem = (this.element == undefined) ? self._createRegularItem(this) : self._createRichItem(this);

				selectItems.push(selectItem);

				if(this.selected)
				{
					targetItems.push(listItem);
				}
				else
				{
					sourceItems.push(listItem);
				}
			});

			self.element.append(selectItems.join("\n"));
			self.sourceList.append(sourceItems.join("\n"));
			self.targetList.append(targetItems.join("\n"));
		},

		_createSelectItem: function(item)
		{
			var selected = item.selected ? " selected='selected'" : "";
			return "<option value='" + item.value + "'" + selected + ">" + item.label + "</option>";
		},

		_createRegularItem: function(item)
		{
			var self = this;
			return "<li value='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + "'>" + item.label + "</li>";
		},

		_createRichItem: function(item)
		{
			var self = this;

			var richItemHtml = item.element.html();
			item.element.hide();

			return "<li value='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + " " + self.options.richListItemClass + "'>" + richItemHtml + "</li>";
		}
	});
}(jQuery));
<|endoftext|>


<commit_before>(function($) {
	var defaults = {
		'control':true
	};
	var initialized = false;

	function init() {
		if (! initialized) {
			initialized = true;
			$('head').append('');
		}
	}

	function syncScroll (sender) {
		var t = $(sender.contentWindow).scrollTop();
		$(sender).siblings().each(function() {
			$(this.contentWindow).scrollTop(t);
		});
	}

	function registerScrollSync(iframe) {
		$(iframe.contentWindow).scroll(function() { syncScroll(iframe); });
	}

	var methods = {
		'init': function(options) {
			init();
			var opts = $.extend(true, {}, defaults, options);
			return this.each(function() {
				var $this = $(this);
				var $ifOld = $('');
				var $ifNew = $('');
				var $ifOrg = $('');
				var $cover = $('
');
				var ifCss = {
					'position':'absolute',
					'width': '100%',
					'height': '100%',
					'top': '0',
					'left': '0',
					'border': 'none',
				};
				$this.html('');
				$this.css({
					'position' : 'relative',
					'overflow' : 'hidden'
				});
				$ifOld.css($.extend({}, ifCss, {'background-color':'#fff'}));
				$ifNew.css($.extend({}, ifCss, {'background-color':'#fff', 'mix-blend-mode':'difference'}));
				$ifOrg.css($.extend({}, ifCss, {'background-color':'#fff', 'mix-blend-mode':'difference'}));
				$cover.css(ifCss);
				$this.append($ifOld);
				$this.append($ifNew);
				$this.append($cover);
				$this.append($ifOrg);
				$this.children('iframe').on('load', function() {
					registerScrollSync(this);
				});
				$ifOld.attr('src', opts.oldUrl);
				$ifNew.attr('src', opts.newUrl);
				$ifOrg.attr('src', opts.newUrl);
			});
		},
		'mode': function(mode) {
			return this.each(function() {
				var $this = $(this);
				var $ifOld = $this.children('.diffpageOld');
				var $ifNew = $this.children('.diffpageNew');
				var $ifOrg = $this.children('.diffpageOrg');
				var $cover = $this.children('.diffpageCover');
				switch (mode) {
					case 'old':
						$ifOld.show();
						$ifNew.hide();
						$cover.hide();
						$ifOrg.hide();
						break;
					case 'new':
						$ifOld.hide();
						$ifNew.show();
						$cover.hide();
						$ifOrg.hide();
						break;
					case 'diff':
						$ifOld.show();
						$ifNew.show();
						$cover.hide();
						$ifOrg.hide();
						break;
					default:
						$ifOld.show();
						$ifNew.show();
						$cover.show();
						$ifOrg.show();
						break;
				}
			});
		}
	};

	$.fn.diffpage = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || ! method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('jQuery.diffpage: Method does not exists');
		}
	};
})(jQuery);
<commit_msg>Added stripes style settings<commit_after>(function($) {
	var defaults = {
		'stripeType': 'skew',
		'stripeSize': '16px',
		'stripeSpeed': '60s',
	};
	var initialized = false;

	function init() {
		if (! initialized) {
			initialized = true;
			$('head').append('');
		}
	}

	function syncScroll (sender) {
		var t = $(sender.contentWindow).scrollTop();
		$(sender).siblings().each(function() {
			$(this.contentWindow).scrollTop(t);
		});
	}

	function registerScrollSync(iframe) {
		$(iframe.contentWindow).scroll(function() { syncScroll(iframe); });
	}

	function styleCover($cover, type, size, speed) {
		var deg, px, duration;
		switch (type) {
			case 'v':
			case 'vertical':
				deg = '';
				break;
			case 'h':
			case 'horizontal':
				deg = '-90deg';
				break;
			case 'skew':
			default:
				deg = '-45deg';
				break;
		}
		px = size ? size : '16px';
		duration = speed ? speed : '60s';
		$cover.css({
			'mix-blend-mode': 'multiply',
			'background-image': 'linear-gradient(' + deg + ', #fff 25%, #000 25%, #000 50%, #fff 50%, #fff 75%, #000 75%, #000)',
			'background-size': px + ' ' + px,
			'animation': 'diffpageAnim ' + duration + ' linear infinite'
		});
	}

	var methods = {
		'init': function(options) {
			init();
			var opts = $.extend(true, {}, defaults, options);
			return this.each(function() {
				var $this = $(this);
				var $ifOld = $('');
				var $ifNew = $('');
				var $ifOrg = $('');
				var $cover = $('
');
				var ifCss = {
					'position':'absolute',
					'width': '100%',
					'height': '100%',
					'top': '0',
					'left': '0',
					'border': 'none',
				};
				$this.html('');
				$this.css({
					'position' : 'relative',
					'overflow' : 'hidden'
				});
				$ifOld.css($.extend({}, ifCss, {'background-color':'#fff'}));
				$ifNew.css($.extend({}, ifCss, {'background-color':'#fff', 'mix-blend-mode':'difference'}));
				$ifOrg.css($.extend({}, ifCss, {'background-color':'#fff', 'mix-blend-mode':'difference'}));
				$cover.css(ifCss);
				styleCover($cover, opts.stripeType, opts.stripeSize, opts.stripeSpeed);
				$this.append($ifOld);
				$this.append($ifNew);
				$this.append($cover);
				$this.append($ifOrg);
				$this.children('iframe').on('load', function() {
					registerScrollSync(this);
				});
				$ifOld.attr('src', opts.oldUrl);
				$ifNew.attr('src', opts.newUrl);
				$ifOrg.attr('src', opts.newUrl);
			});
		},
		'mode': function(mode) {
			return this.each(function() {
				var $this = $(this);
				var $ifOld = $this.children('.diffpageOld');
				var $ifNew = $this.children('.diffpageNew');
				var $ifOrg = $this.children('.diffpageOrg');
				var $cover = $this.children('.diffpageCover');
				switch (mode) {
					case 'old':
						$ifOld.show();
						$ifNew.hide();
						$cover.hide();
						$ifOrg.hide();
						break;
					case 'new':
						$ifOld.hide();
						$ifNew.show();
						$cover.hide();
						$ifOrg.hide();
						break;
					case 'diff':
						$ifOld.show();
						$ifNew.show();
						$cover.hide();
						$ifOrg.hide();
						break;
					default:
						$ifOld.show();
						$ifNew.show();
						$cover.show();
						$ifOrg.show();
						break;
				}
			});
		}
	};

	$.fn.diffpage = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || ! method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('jQuery.diffpage: Method does not exists');
		}
	};
})(jQuery);
<|endoftext|>


<commit_before>/*!
	SlickNav Responsive Mobile Menu
	(c) 2014 Josh Cope
	licensed under MIT
*/
;(function ($, document, window) {
	var
	// default settings object.
	defaults = {
		label: 'MENU',
		duplicate: true,
		duration: 200,
		easingOpen: 'swing',
		easingClose: 'swing',
		closedSymbol: '►',
		openedSymbol: '▼',
		prependTo: 'body',
		parentTag: 'a',
		closeOnClick: false,
		allowParentLinks: false,
        nestedParentLinks: true,
		init: function(){},
		open: function(){},
		close: function(){}
	},
	mobileMenu = 'slicknav',
	prefix = 'slicknav';

	function Plugin( element, options ) {
		this.element = element;

        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.settings = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = mobileMenu;

        this.init();
	}

	Plugin.prototype.init = function () {
        var $this = this;
		var menu = $(this.element);
		var settings = this.settings;

		// clone menu if needed
		if (settings.duplicate) {
			$this.mobileNav = menu.clone();
			//remove ids from clone to prevent css issues
			$this.mobileNav.removeAttr('id');
			$this.mobileNav.find('*').each(function(i,e){
				$(e).removeAttr('id');
			});
		}
		else
			$this.mobileNav = menu;

		// styling class for the button
		var iconClass = prefix+'_icon';

		if (settings.label == '') {
			iconClass += ' '+prefix+'_no-text';
		}

		if (settings.parentTag == 'a') {
			settings.parentTag = 'a href="#"';
		}

		// create menu bar
		$this.mobileNav.attr('class', prefix+'_nav');
		var menuBar = $('

');
		$this.btn = $('<'+settings.parentTag+' aria-haspopup="true" tabindex="0" class="'+prefix+'_btn '+prefix+'_collapsed">'+settings.label+'');
		$(menuBar).append($this.btn);
		$(settings.prependTo).prepend(menuBar);
		menuBar.append($this.mobileNav);

		// iterate over structure adding additional structure
		var items = $this.mobileNav.find('li');
		$(items).each(function () {
			var item = $(this);
			data = {};
			data.children = item.children('ul').attr('role','menu');
			item.data("menu", data);

			// if a list item has a nested menu
			if (data.children.length > 0) {

				// select all text before the child menu
                // check for anchors

				var a = item.contents();
                var containsAnchor = false;

				var nodes = [];
				$(a).each(function(){
					if(!$(this).is("ul")) {
						nodes.push(this);
					}
					else {
						return false;
					}

                    if($(this).is("a")) {
						containsAnchor = true;
					}
				});

                var wrapElement = $('<'+settings.parentTag+' role="menuitem" aria-haspopup="true" tabindex="-1" class="'+prefix+'_item"/>');

				// wrap item text with tag and add classes unless we are separating parent links
                if ((!settings.allowParentLinks || settings.nestedParentLinks) || !containsAnchor) {
                    $wrap = $(nodes).wrapAll(wrapElement).parent();
                    $wrap.addClass(prefix+'_row');
                } else
                    $(nodes).wrapAll('').parent();

				item.addClass(prefix+'_collapsed');
				item.addClass(prefix+'_parent');

				// create parent arrow. wrap with link if parent links and separating
                var arrowElement = $(''+settings.closedSymbol+'');

                if (settings.allowParentLinks && !settings.nestedParentLinks && containsAnchor)
                    arrowElement = arrowElement.wrap(wrapElement).parent();

                //append arrow
                $(nodes).last().after(arrowElement);

			} else if ( item.children().length == 0) {
				 item.addClass(prefix+'_txtnode');
			}

			// accessibility for links
			item.children('a').attr('role', 'menuitem').click(function(event){
				//Emulate menu close if set
                //Ensure that it's not a parent
				if (settings.closeOnClick && !$(event.target).parent().closest('li').hasClass(prefix+'_parent'))
					$($this.btn).click();
			});

            //also close on click if parent links are set
            if (settings.closeOnClick && settings.allowParentLinks) {
                item.children('a').children('a').click(function(event){
                    //Emulate menu close
                        $($this.btn).click();
                });

                item.find('.'+prefix+'_parent-link a:not(.'+prefix+'_item)').click(function(event){
                    //Emulate menu close
                        $($this.btn).click();
                });
            }
		});

		// structure is in place, now hide appropriate items
		$(items).each(function () {
			var data = $(this).data("menu");
			$this._visibilityToggle(data.children, null, false, null, true);
		});

		// finally toggle entire menu
		$this._visibilityToggle($this.mobileNav, null, false, 'init', true);

		// accessibility for menu button
		$this.mobileNav.attr('role','menu');

		// outline prevention when using mouse
		$(document).mousedown(function(){
			$this._outlines(false);
		});

		$(document).keyup(function(){
			$this._outlines(true);
		});

		// menu button click
		$($this.btn).click(function (e) {
			e.preventDefault();
			$this._menuToggle();
		});

		// click on menu parent
		$this.mobileNav.on('click', '.'+prefix+'_item', function(e){
			e.preventDefault();
			$this._itemClick($(this));
		});

		// check for enter key on menu button and menu parents
		$($this.btn).keydown(function (e) {
			var ev = e || event;
			if(ev.keyCode == 13) {
				e.preventDefault();
				$this._menuToggle();
			}
		});

		$this.mobileNav.on('keydown', '.'+prefix+'_item', function(e) {
			var ev = e || event;
			if(ev.keyCode == 13) {
				e.preventDefault();
				$this._itemClick($(e.target));
			}
		});

		// allow links clickable within parent tags if set
		if (settings.allowParentLinks && settings.nestedParentLinks) {
			$('.'+prefix+'_item a').click(function(e){
					e.stopImmediatePropagation();
			});
		}
    };

	//toggle menu
	Plugin.prototype._menuToggle = function(el){
		var $this = this;
		var btn = $this.btn;
		var mobileNav = $this.mobileNav;

		if (btn.hasClass(prefix+'_collapsed')) {
			btn.removeClass(prefix+'_collapsed');
			btn.addClass(prefix+'_open');
		} else {
			btn.removeClass(prefix+'_open');
			btn.addClass(prefix+'_collapsed');
		}
		btn.addClass(prefix+'_animating');
		$this._visibilityToggle(mobileNav, btn.parent(), true, btn);
	}

	// toggle clicked items
	Plugin.prototype._itemClick = function(el) {
		var $this = this;
		var settings = $this.settings;
		var data = el.data("menu");
		if (!data) {
			data = {};
			data.arrow = el.children('.'+prefix+'_arrow');
			data.ul = el.next('ul');
			data.parent = el.parent();
            //Separated parent link structure
            if (data.parent.hasClass(prefix+'_parent-link')) {
                data.parent = el.parent().parent();
                data.ul = el.parent().next('ul');
            }
			el.data("menu", data);
		}
		if (data.parent.hasClass(prefix+'_collapsed')) {
			data.arrow.html(settings.openedSymbol);
			data.parent.removeClass(prefix+'_collapsed');
			data.parent.addClass(prefix+'_open');
			data.parent.addClass(prefix+'_animating');
			$this._visibilityToggle(data.ul, data.parent, true, el);
		} else {
			data.arrow.html(settings.closedSymbol);
			data.parent.addClass(prefix+'_collapsed');
			data.parent.removeClass(prefix+'_open');
			data.parent.addClass(prefix+'_animating');
			$this._visibilityToggle(data.ul, data.parent, true, el);
		}
	}

	// toggle actual visibility and accessibility tags
	Plugin.prototype._visibilityToggle = function(el, parent, animate, trigger, init) {
		var $this = this;
		var settings = $this.settings;
		var items = $this._getActionItems(el);
		var duration = 0;
		if (animate)
			duration = settings.duration;

		if (el.hasClass(prefix+'_hidden')) {
			el.removeClass(prefix+'_hidden');
			el.slideDown(duration, settings.easingOpen, function(){

				$(trigger).removeClass(prefix+'_animating');
				$(parent).removeClass(prefix+'_animating');

				//Fire open callback
				if (!init) {
					settings.open(trigger);
				}
			});
			el.attr('aria-hidden','false');
			items.attr('tabindex', '0');
			$this._setVisAttr(el, false);
		} else {
			el.addClass(prefix+'_hidden');
			el.slideUp(duration, this.settings.easingClose, function() {
				el.attr('aria-hidden','true');
				items.attr('tabindex', '-1');
				$this._setVisAttr(el, true);
				el.hide(); //jQuery 1.7 bug fix

				$(trigger).removeClass(prefix+'_animating');
				$(parent).removeClass(prefix+'_animating');

				//Fire init or close callback
				if (!init)
					settings.close(trigger);
				else if (trigger == 'init')
					settings.init();
			});
		}
	}

	// set attributes of element and children based on visibility
	Plugin.prototype._setVisAttr = function(el, hidden) {
		var $this = this;

		// select all parents that aren't hidden
		var nonHidden = el.children('li').children('ul').not('.'+prefix+'_hidden');

		// iterate over all items setting appropriate tags
		if (!hidden) {
			nonHidden.each(function(){
				var ul = $(this);
				ul.attr('aria-hidden','false');
				var items = $this._getActionItems(ul);
				items.attr('tabindex', '0');
				$this._setVisAttr(ul, hidden);
			});
		} else {
			nonHidden.each(function(){
				var ul = $(this);
				ul.attr('aria-hidden','true');
				var items = $this._getActionItems(ul);
				items.attr('tabindex', '-1');
				$this._setVisAttr(ul, hidden);
			});
		}
	}

	// get all 1st level items that are clickable
	Plugin.prototype._getActionItems = function(el) {
		var data = el.data("menu");
		if (!data) {
			data = {};
			var items = el.children('li');
			var anchors = items.find('a');
			data.links = anchors.add(items.find('.'+prefix+'_item'));
			el.data("menu", data);
		}
		return data.links;
	}

	Plugin.prototype._outlines = function(state) {
		if (!state) {
			$('.'+prefix+'_item, .'+prefix+'_btn').css('outline','none');
		} else {
			$('.'+prefix+'_item, .'+prefix+'_btn').css('outline','');
		}
	}

	Plugin.prototype.toggle = function(){
        $this = this;
		$this._menuToggle();
	}

	Plugin.prototype.open = function(){
		$this = this;
		if ($this.btn.hasClass(prefix+'_collapsed')) {
			$this._menuToggle();
		}
	}

	Plugin.prototype.close = function(){
		$this = this;
		if ($this.btn.hasClass(prefix+'_open')) {
			$this._menuToggle();
		}
	}

	$.fn[mobileMenu] = function ( options ) {
		var args = arguments;

		// Is the first parameter an object (options), or was omitted, instantiate a new instance
		if (options === undefined || typeof options === 'object') {
			return this.each(function () {

				// Only allow the plugin to be instantiated once due to methods
				if (!$.data(this, 'plugin_' + mobileMenu)) {

					// if it has no instance, create a new one, pass options to our plugin constructor,
					// and store the plugin instance in the elements jQuery data object.
					$.data(this, 'plugin_' + mobileMenu, new Plugin( this, options ));
				}
			});

		// If is a string and doesn't start with an underscore or 'init' function, treat this as a call to a public method.
		} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

			// Cache the method call to make it possible to return a value
			var returns;

			this.each(function () {
				var instance = $.data(this, 'plugin_' + mobileMenu);

				// Tests that there's already a plugin-instance and checks that the requested public method exists
				if (instance instanceof Plugin && typeof instance[options] === 'function') {

					// Call the method of our plugin instance, and pass it the supplied arguments.
					returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
				}
			});

			// If the earlier cached method gives a value back return the value, otherwise return this to preserve chainability.
			return returns !== undefined ? returns : this;
		}
	};
}(jQuery, document, window));<commit_msg>Show Children<commit_after>/*!
	SlickNav Responsive Mobile Menu
	(c) 2014 Josh Cope
	licensed under MIT
*/
;(function ($, document, window) {
	var
	// default settings object.
	defaults = {
		label: 'MENU',
		duplicate: true,
		duration: 200,
		easingOpen: 'swing',
		easingClose: 'swing',
		closedSymbol: '►',
		openedSymbol: '▼',
		prependTo: 'body',
		parentTag: 'a',
		closeOnClick: false,
		allowParentLinks: false,
        nestedParentLinks: true,
		showChildren: false,
		init: function(){},
		open: function(){},
		close: function(){}
	},
	mobileMenu = 'slicknav',
	prefix = 'slicknav';

	function Plugin( element, options ) {
		this.element = element;

        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.settings = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = mobileMenu;

        this.init();
	}

	Plugin.prototype.init = function () {
        var $this = this;
		var menu = $(this.element);
		var settings = this.settings;

		// clone menu if needed
		if (settings.duplicate) {
			$this.mobileNav = menu.clone();
			//remove ids from clone to prevent css issues
			$this.mobileNav.removeAttr('id');
			$this.mobileNav.find('*').each(function(i,e){
				$(e).removeAttr('id');
			});
		}
		else
			$this.mobileNav = menu;

		// styling class for the button
		var iconClass = prefix+'_icon';

		if (settings.label == '') {
			iconClass += ' '+prefix+'_no-text';
		}

		if (settings.parentTag == 'a') {
			settings.parentTag = 'a href="#"';
		}

		// create menu bar
		$this.mobileNav.attr('class', prefix+'_nav');
		var menuBar = $('

');
		$this.btn = $('<'+settings.parentTag+' aria-haspopup="true" tabindex="0" class="'+prefix+'_btn '+prefix+'_collapsed">'+settings.label+'');
		$(menuBar).append($this.btn);
		$(settings.prependTo).prepend(menuBar);
		menuBar.append($this.mobileNav);

		// iterate over structure adding additional structure
		var items = $this.mobileNav.find('li');
		$(items).each(function () {
			var item = $(this);
			data = {};
			data.children = item.children('ul').attr('role','menu');
			item.data("menu", data);

			// if a list item has a nested menu
			if (data.children.length > 0) {

				// select all text before the child menu
                // check for anchors

				var a = item.contents();
                var containsAnchor = false;

				var nodes = [];
				$(a).each(function(){
					if(!$(this).is("ul")) {
						nodes.push(this);
					}
					else {
						return false;
					}

                    if($(this).is("a")) {
						containsAnchor = true;
					}
				});

                var wrapElement = $('<'+settings.parentTag+' role="menuitem" aria-haspopup="true" tabindex="-1" class="'+prefix+'_item"/>');

				// wrap item text with tag and add classes unless we are separating parent links
                if ((!settings.allowParentLinks || settings.nestedParentLinks) || !containsAnchor) {
                    $wrap = $(nodes).wrapAll(wrapElement).parent();
                    $wrap.addClass(prefix+'_row');
                } else
                    $(nodes).wrapAll('').parent();

				item.addClass(prefix+'_collapsed');
				item.addClass(prefix+'_parent');

				// create parent arrow. wrap with link if parent links and separating
                var arrowElement = $(''+settings.closedSymbol+'');

                if (settings.allowParentLinks && !settings.nestedParentLinks && containsAnchor)
                    arrowElement = arrowElement.wrap(wrapElement).parent();

                //append arrow
                $(nodes).last().after(arrowElement);

			} else if ( item.children().length == 0) {
				 item.addClass(prefix+'_txtnode');
			}

			// accessibility for links
			item.children('a').attr('role', 'menuitem').click(function(event){
				//Emulate menu close if set
                //Ensure that it's not a parent
				if (settings.closeOnClick && !$(event.target).parent().closest('li').hasClass(prefix+'_parent'))
					$($this.btn).click();
			});

            //also close on click if parent links are set
            if (settings.closeOnClick && settings.allowParentLinks) {
                item.children('a').children('a').click(function(event){
                    //Emulate menu close
                        $($this.btn).click();
                });

                item.find('.'+prefix+'_parent-link a:not(.'+prefix+'_item)').click(function(event){
                    //Emulate menu close
                        $($this.btn).click();
                });
            }
		});

		// structure is in place, now hide appropriate items
		$(items).each(function () {
			var data = $(this).data("menu");
			if (!settings.showChildren){
				$this._visibilityToggle(data.children, null, false, null, true);
			}
		});

		// finally toggle entire menu
		$this._visibilityToggle($this.mobileNav, null, false, 'init', true);

		// accessibility for menu button
		$this.mobileNav.attr('role','menu');

		// outline prevention when using mouse
		$(document).mousedown(function(){
			$this._outlines(false);
		});

		$(document).keyup(function(){
			$this._outlines(true);
		});

		// menu button click
		$($this.btn).click(function (e) {
			e.preventDefault();
			$this._menuToggle();

		});

		// click on menu parent
		$this.mobileNav.on('click', '.'+prefix+'_item', function(e){
			e.preventDefault();
			$this._itemClick($(this));
		});

		// check for enter key on menu button and menu parents
		$($this.btn).keydown(function (e) {
			var ev = e || event;
			if(ev.keyCode == 13) {
				e.preventDefault();
				$this._menuToggle();
			}
		});

		$this.mobileNav.on('keydown', '.'+prefix+'_item', function(e) {
			var ev = e || event;
			if(ev.keyCode == 13) {
				e.preventDefault();
				$this._itemClick($(e.target));
			}
		});

		// allow links clickable within parent tags if set
		if (settings.allowParentLinks && settings.nestedParentLinks) {
			$('.'+prefix+'_item a').click(function(e){
					e.stopImmediatePropagation();
			});
		}
    };

	//toggle menu
	Plugin.prototype._menuToggle = function(el){
		var $this = this;
		var btn = $this.btn;
		var mobileNav = $this.mobileNav;

		if (btn.hasClass(prefix+'_collapsed')) {
			btn.removeClass(prefix+'_collapsed');
			btn.addClass(prefix+'_open');
		} else {
			btn.removeClass(prefix+'_open');
			btn.addClass(prefix+'_collapsed');
		}
		btn.addClass(prefix+'_animating');
		$this._visibilityToggle(mobileNav, btn.parent(), true, btn);
	}

	// toggle clicked items
	Plugin.prototype._itemClick = function(el) {
		var $this = this;
		var settings = $this.settings;
		var data = el.data("menu");
		if (!data) {
			data = {};
			data.arrow = el.children('.'+prefix+'_arrow');
			data.ul = el.next('ul');
			data.parent = el.parent();
            //Separated parent link structure
            if (data.parent.hasClass(prefix+'_parent-link')) {
                data.parent = el.parent().parent();
                data.ul = el.parent().next('ul');
            }
			el.data("menu", data);
		}
		if (data.parent.hasClass(prefix+'_collapsed')) {
			data.arrow.html(settings.openedSymbol);
			data.parent.removeClass(prefix+'_collapsed');
			data.parent.addClass(prefix+'_open');
			data.parent.addClass(prefix+'_animating');
			$this._visibilityToggle(data.ul, data.parent, true, el);
		} else {
			data.arrow.html(settings.closedSymbol);
			data.parent.addClass(prefix+'_collapsed');
			data.parent.removeClass(prefix+'_open');
			data.parent.addClass(prefix+'_animating');
			$this._visibilityToggle(data.ul, data.parent, true, el);
		}
	}

	// toggle actual visibility and accessibility tags
	Plugin.prototype._visibilityToggle = function(el, parent, animate, trigger, init) {
		var $this = this;
		var settings = $this.settings;
		var items = $this._getActionItems(el);
		var duration = 0;
		if (animate)
			duration = settings.duration;

		if (el.hasClass(prefix+'_hidden')) {
			el.removeClass(prefix+'_hidden');
			el.slideDown(duration, settings.easingOpen, function(){

				$(trigger).removeClass(prefix+'_animating');
				$(parent).removeClass(prefix+'_animating');

				//Fire open callback
				if (!init) {
					settings.open(trigger);
				}
			});
			el.attr('aria-hidden','false');
			items.attr('tabindex', '0');
			$this._setVisAttr(el, false);
		} else {
			el.addClass(prefix+'_hidden');
			el.slideUp(duration, this.settings.easingClose, function() {
				el.attr('aria-hidden','true');
				items.attr('tabindex', '-1');
				$this._setVisAttr(el, true);
				el.hide(); //jQuery 1.7 bug fix

				$(trigger).removeClass(prefix+'_animating');
				$(parent).removeClass(prefix+'_animating');

				//Fire init or close callback
				if (!init)
					settings.close(trigger);
				else if (trigger == 'init')
					settings.init();
			});
		}
	}

	// set attributes of element and children based on visibility
	Plugin.prototype._setVisAttr = function(el, hidden) {
		var $this = this;

		// select all parents that aren't hidden
		var nonHidden = el.children('li').children('ul').not('.'+prefix+'_hidden');

		// iterate over all items setting appropriate tags
		if (!hidden) {
			nonHidden.each(function(){
				var ul = $(this);
				ul.attr('aria-hidden','false');
				var items = $this._getActionItems(ul);
				items.attr('tabindex', '0');
				$this._setVisAttr(ul, hidden);
			});
		} else {
			nonHidden.each(function(){
				var ul = $(this);
				ul.attr('aria-hidden','true');
				var items = $this._getActionItems(ul);
				items.attr('tabindex', '-1');
				$this._setVisAttr(ul, hidden);
			});
		}
	}

	// get all 1st level items that are clickable
	Plugin.prototype._getActionItems = function(el) {
		var data = el.data("menu");
		if (!data) {
			data = {};
			var items = el.children('li');
			var anchors = items.find('a');
			data.links = anchors.add(items.find('.'+prefix+'_item'));
			el.data("menu", data);
		}
		return data.links;
	}

	Plugin.prototype._outlines = function(state) {
		if (!state) {
			$('.'+prefix+'_item, .'+prefix+'_btn').css('outline','none');
		} else {
			$('.'+prefix+'_item, .'+prefix+'_btn').css('outline','');
		}
	}

	Plugin.prototype.toggle = function(){
        $this = this;
		$this._menuToggle();
	}

	Plugin.prototype.open = function(){
		$this = this;
		if ($this.btn.hasClass(prefix+'_collapsed')) {
			$this._menuToggle();
		}
	}

	Plugin.prototype.close = function(){
		$this = this;
		if ($this.btn.hasClass(prefix+'_open')) {
			$this._menuToggle();
		}
	}

	$.fn[mobileMenu] = function ( options ) {
		var args = arguments;

		// Is the first parameter an object (options), or was omitted, instantiate a new instance
		if (options === undefined || typeof options === 'object') {
			return this.each(function () {

				// Only allow the plugin to be instantiated once due to methods
				if (!$.data(this, 'plugin_' + mobileMenu)) {

					// if it has no instance, create a new one, pass options to our plugin constructor,
					// and store the plugin instance in the elements jQuery data object.
					$.data(this, 'plugin_' + mobileMenu, new Plugin( this, options ));
				}
			});

		// If is a string and doesn't start with an underscore or 'init' function, treat this as a call to a public method.
		} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

			// Cache the method call to make it possible to return a value
			var returns;

			this.each(function () {
				var instance = $.data(this, 'plugin_' + mobileMenu);

				// Tests that there's already a plugin-instance and checks that the requested public method exists
				if (instance instanceof Plugin && typeof instance[options] === 'function') {

					// Call the method of our plugin instance, and pass it the supplied arguments.
					returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
				}
			});

			// If the earlier cached method gives a value back return the value, otherwise return this to preserve chainability.
			return returns !== undefined ? returns : this;
		}
	};
}(jQuery, document, window));
<|endoftext|>


<commit_before>/*
 * HTML5 Sortable jQuery Plugin
 * http://farhadi.ir/projects/html5sortable
 *
 * Copyright 2012, Ali Farhadi
 * Released under the MIT license.
 */
(function($) {
var dragging, placeholders = $();
$.fn.sortable = function(options) {
	var method = String(options);
	options = $.extend({
		connectWith: false
	}, options);
	return this.each(function() {
		if (/^enable|disable|destroy$/.test(method)) {
			var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable');
			if (method == 'destroy') {
				items.add(this).removeData('connectWith items')
					.off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s');
			}
			return;
		}
		var isHandle, index, items = $(this).children(options.items);
		var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">');
		items.find(options.handle).mousedown(function() {
			isHandle = true;
		}).mouseup(function() {
			isHandle = false;
		});
		$(this).data('items', options.items)
		placeholders = placeholders.add(placeholder);
		if (options.connectWith) {
			$(options.connectWith).add(this).data('connectWith', options.connectWith);
		}
		items.attr('draggable', 'true').on('dragstart.h5s', function(e) {
			if (options.handle && !isHandle) {
				return false;
			}
			isHandle = false;
			var dt = e.originalEvent.dataTransfer;
			dt.effectAllowed = 'move';
			dt.setData('Text', 'dummy');
			index = (dragging = $(this)).addClass('sortable-dragging').index();
		}).on('dragend.h5s', function() {
			if (!dragging) {
				return;
			}
			dragging.removeClass('sortable-dragging').show();
			placeholders.detach();
			if (index != dragging.index()) {
				dragging.parent().trigger('sortupdate', {item: dragging});
			}
			dragging = null;
		}).not('a[href], img').on('selectstart.h5s', function() {
			this.dragDrop && this.dragDrop();
			return false;
		}).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function(e) {
			if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) {
				return true;
			}
			if (e.type == 'drop') {
				e.stopPropagation();
				placeholders.filter(':visible').after(dragging);
				dragging.trigger('dragend.h5s');
				return false;
			}
			e.preventDefault();
			e.originalEvent.dataTransfer.dropEffect = 'move';
			if (items.is(this)) {
				if (options.forcePlaceholderSize) {
					placeholder.height(dragging.outerHeight());
				}
				dragging.hide();
				$(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder);
				placeholders.not(placeholder).detach();
			} else if (!placeholders.is(this) && !$(this).children(options.items).length) {
				placeholders.detach();
				$(this).append(placeholder);
			}
			return false;
		});
	});
};
})(jQuery);
<commit_msg>Add oldindex property to sortupdate event data<commit_after>/*
 * HTML5 Sortable jQuery Plugin
 * http://farhadi.ir/projects/html5sortable
 *
 * Copyright 2012, Ali Farhadi
 * Released under the MIT license.
 */
(function($) {
var dragging, placeholders = $();
$.fn.sortable = function(options) {
	var method = String(options);
	options = $.extend({
		connectWith: false
	}, options);
	return this.each(function() {
		if (/^enable|disable|destroy$/.test(method)) {
			var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable');
			if (method == 'destroy') {
				items.add(this).removeData('connectWith items')
					.off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s');
			}
			return;
		}
		var isHandle, index, items = $(this).children(options.items);
		var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">');
		items.find(options.handle).mousedown(function() {
			isHandle = true;
		}).mouseup(function() {
			isHandle = false;
		});
		$(this).data('items', options.items)
		placeholders = placeholders.add(placeholder);
		if (options.connectWith) {
			$(options.connectWith).add(this).data('connectWith', options.connectWith);
		}
		items.attr('draggable', 'true').on('dragstart.h5s', function(e) {
			if (options.handle && !isHandle) {
				return false;
			}
			isHandle = false;
			var dt = e.originalEvent.dataTransfer;
			dt.effectAllowed = 'move';
			dt.setData('Text', 'dummy');
			index = (dragging = $(this)).addClass('sortable-dragging').index();
		}).on('dragend.h5s', function() {
			if (!dragging) {
				return;
			}
			dragging.removeClass('sortable-dragging').show();
			placeholders.detach();
			if (index != dragging.index()) {
				dragging.parent().trigger('sortupdate', {item: dragging, oldindex: index});
			}
			dragging = null;
		}).not('a[href], img').on('selectstart.h5s', function() {
			this.dragDrop && this.dragDrop();
			return false;
		}).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function(e) {
			if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) {
				return true;
			}
			if (e.type == 'drop') {
				e.stopPropagation();
				placeholders.filter(':visible').after(dragging);
				dragging.trigger('dragend.h5s');
				return false;
			}
			e.preventDefault();
			e.originalEvent.dataTransfer.dropEffect = 'move';
			if (items.is(this)) {
				if (options.forcePlaceholderSize) {
					placeholder.height(dragging.outerHeight());
				}
				dragging.hide();
				$(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder);
				placeholders.not(placeholder).detach();
			} else if (!placeholders.is(this) && !$(this).children(options.items).length) {
				placeholders.detach();
				$(this).append(placeholder);
			}
			return false;
		});
	});
};
})(jQuery);
<|endoftext|>