<commit_before>/*!
 *
 *  Static Website Starter Kit
 *  Copyright 2015 Konstantin Tarkus, Kriasoft LLC. All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License
 *
 */

var $CARD = $('#info-card');

(function() {
  'use strict';

  // Set initial conditions.
  init();

  // Show details
  $('.content-block').click(function() {
    var $block = $(this);

    // bind data
    $CARD.find('#title').text($block.data('title'));
    $CARD.find('#info-header').css('background-image', 'url(http://placehold.it/300?text=PLACEHOLDER)');
    $CARD.find('#category').text($block.data('category'));

    // Put each tag in its own div
    $CARD.find('#tags').text('');
    var tags = String($block.data('tags')).split(',');
    for (var str of tags) {
      var div = document.createElement('div');
      div.innerHTML = str;
      $CARD.find('#tags').append(div);
    }

    $CARD.find('#description').text($block.data('description'));

    $CARD.fadeIn(300);
  });

  $('#info-close').click(function() {
    $('#info-card').fadeOut(300);
  });

  $('.tag').hover(function() {
    var categoryClass = $(this).text();
    console.log(categoryClass);
    $('.' + categoryClass).fadeTo(150, 0.4);
  }, function(event) {
    var categoryClass = $(this).text();
    $('.' + categoryClass).fadeTo(150, 1);
  });

})();

/**
 * Set initial conditions on page load.
 */
function init() {
  'use strict';
  $CARD.hide();
  // particlesJS.load('particles-js', '../particles.json', function() {
  //     console.log('callback - particles.js config loaded');
  //   });

}
<commit_msg>dirty deploy<commit_after>/*!
 *
 *  Static Website Starter Kit
 *  Copyright 2015 Konstantin Tarkus, Kriasoft LLC. All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License
 *
 */

var $CARD = $('#info-card');

(function() {
  'use strict';

  // Set initial conditions.
  init();

  // Show details
  $('.content-block').click(function() {
    var $block = $(this);

    // bind data
    $CARD.find('#title').text($block.data('title'));
    $CARD.find('#info-header').css('background-image', 'url(http://placehold.it/300?text=PLACEHOLDER)');
    $CARD.find('#category').text($block.data('category'));

    // Put each tag in its own div
    $CARD.find('#tags').text('');
    var tags = String($block.data('tags')).split(',');
    for (var str of tags) {
      var div = document.createElement('div');
      div.innerHTML = str;
      $CARD.find('#tags').append(div);
    }

    $CARD.find('#description').text($block.data('description'));

    $CARD.fadeIn(300);
  });

  $('#info-close').click(function() {
    $('#info-card').fadeOut(300);
  });

  $('.tag').hover(function() {
    var categoryClass = $(this).text();
    console.log(categoryClass);
    $('.' + categoryClass).fadeTo(150, 0.4);
  }, function(event) {
    var categoryClass = $(this).text();
    $('.' + categoryClass).fadeTo(150, 1);
  });

})();

/**
 * Set initial conditions on page load.
 */
function init() {
  'use strict';
  $CARD.hide();
  particlesJS.load('particles-js', '../particles.json', function() {
      console.log('callback - particles.js config loaded');
    });

}
<|endoftext|>


<commit_before>describe("HotspotManager", function() {
    var container = document.createElement("div");
    container.id = "container";
    container.style.width = "800px";
    container.style.height = "600px";
    document.body.appendChild(container);

    beforeAll(function(done) {
        this.viewer = new FORGE.Viewer("container", {});
        this.viewer.onReady.add(done, this);
    });

    afterAll(function() {
        this.viewer.destroy();
        this.viewer = null;
    });

    describe("#clear()", function() {
        var config;

        beforeEach(function() {
            this.viewer.hotspots.clear();

            config = [
                { uid: "hotspot-3d-1", type: "3d" },
                { uid: "hotspot-3d-2" },
                { uid: "hotspot-3d-3", type: "3d" },
                { uid: "hotspot-dom-1", type: "dom" },
                { uid: "hotspot-dom-2", type: "dom" }
            ];

            this.viewer.hotspots.addConfig(config);
        });

        it("should delete all hotspots", function() {
            this.viewer.hotspots.clear();
            expect(this.viewer.hotspots.all).toEqual([]);
        });

        it("should not contain DOM hotspots", function() {
            this.viewer.hotspots.clear(FORGE.HotspotType.DOM);

            var all = this.viewer.hotspots.all;
            var dom = false;

            for (var i = 0, ii = all.length; i < ii; i++)
            {
                if (all[i].type === FORGE.HotspotType.DOM)
                {
                    dom = true;
                }
            }

            expect(dom).toBe(false);
        });

        it("should not contain 3D hotspots", function() {
            this.viewer.hotspots.clear(FORGE.HotspotType.THREE_DIMENSIONAL);

            var all = this.viewer.hotspots.all;
            var dom = false;

            for (var i = 0, ii = all.length; i < ii; i++)
            {
                if (all[i].type === FORGE.HotspotType.THREE_DIMENSIONAL)
                {
                    dom = true;
                }
            }

            expect(dom).toBe(false);
        });
    });
});
<commit_msg>Fix the hotspot test (#153)<commit_after>describe("HotspotManager", function() {
    var container = document.createElement("div");
    container.id = "container";
    container.style.width = "800px";
    container.style.height = "600px";
    document.body.appendChild(container);

    beforeAll(function(done) {
        this.viewer = new FORGE.Viewer("container", {});
        this.viewer.onConfigLoadComplete.add(done, this);
    });

    afterAll(function() {
        this.viewer.destroy();
        this.viewer = null;
    });

    describe("#clear()", function() {
        var config;

        beforeEach(function() {
            this.viewer.hotspots.clear();

            config = [
                { uid: "hotspot-3d-1", type: "3d" },
                { uid: "hotspot-3d-2" },
                { uid: "hotspot-3d-3", type: "3d" },
                { uid: "hotspot-dom-1", type: "dom" },
                { uid: "hotspot-dom-2", type: "dom" }
            ];

            this.viewer.hotspots.addConfig(config);
        });

        it("should delete all hotspots", function() {
            this.viewer.hotspots.clear();
            expect(this.viewer.hotspots.all).toEqual([]);
        });

        it("should not contain DOM hotspots", function() {
            this.viewer.hotspots.clear(FORGE.HotspotType.DOM);

            var all = this.viewer.hotspots.all;
            var dom = false;

            for (var i = 0, ii = all.length; i < ii; i++)
            {
                if (all[i].type === FORGE.HotspotType.DOM)
                {
                    dom = true;
                }
            }

            expect(dom).toBe(false);
        });

        it("should not contain 3D hotspots", function() {
            this.viewer.hotspots.clear(FORGE.HotspotType.THREE_DIMENSIONAL);

            var all = this.viewer.hotspots.all;
            var dom = false;

            for (var i = 0, ii = all.length; i < ii; i++)
            {
                if (all[i].type === FORGE.HotspotType.THREE_DIMENSIONAL)
                {
                    dom = true;
                }
            }

            expect(dom).toBe(false);
        });
    });
});
<|endoftext|>


<commit_before>typeof global != 'undefined' || (window.global = window);

var dirname;
var filename = '/module.js';
var scripts = document.scripts;
var length = scripts.length;
var src;
for (var i = 0; i < length; ++i) {
  src = scripts[i].src;
  if (src.indexOf(filename) > 0 )
    dirname = src.split(filename)[0] + '/';
    break;
}

global.console && console.log(dirname + 'module.js');

function define(name) {
  global.module = new Module(name);
}

function expand(path, parent) {

}

function require(path, name) {

}

require.cache = {};

function load(path, callback) {
  callback(err, parent)
}

function Module(id) {

  this.id = id;
  this.filename = id + '.js';
  this.exports = {};

}

define('.');

define('./inline');
<commit_msg>Update module.js<commit_after>typeof global != 'undefined' || (window.global = window);

var dirname;
var filename = '/module.js';
var scripts = document.scripts;
var length = scripts.length;
var src;
for (var i = 0; i < length; ++i) {
  src = scripts[i].src;
  if (src.indexOf(filename) > 0 )
    dirname = src.split(filename)[0] + '/';
    break;
}

global.console && console.log(dirname + 'module.js');

function define(name) {
  global.module = new Module(name);
}

function expand(path, parent) {

}

function require(path, name) {

}

require.cache = {};

function load(path, callback) {
  callback(err, parent)
}

function Module(id) {

  this.id = id;
  this.filename = id + '.js';
  this.exports = {};

}

define('.');

define('./inline');
;(function() {

  module.exports = inline; function inline() {
    global.console && console.log('inline.js');

  }

});

<|endoftext|>


<commit_before>var isSale = true

$(document).ready(function() {
  // hide contact us form
  if (!window.location.href.match(/localhost/)) {
    var interval = setInterval(function() {
      var contactUs = $('body').find('img[src*="icf.improvely.com"]')
      if (!contactUs.length) { return; }
      contactUs.hide()
      clearInterval(interval)
    }, 200)
  }
  // fix odd safari bug where the delegated click is not being recognized, but only for the bag
  setTimeout(function() {
    $('.js-click').on('click', function() {})
  }, 1000)

  // get template html and embed it in the page
  fetch((window.baseUrl || '') + '/assets/html/custombar.html').then(function(response) {
    return response.text()
  }).then(function(html) {
    html = html.replace(/assets\/img\//g, (window.baseUrl || '') + 'assets/img/')
    $('#custombar').parent().css({ position: 'relative', overflow: 'hidden' })
    $('#custombar').before(html).remove()
    render()
    resize()
  })
})

var state = {
  bag: {
    color: 'black',
    style: 'danny',
    height: 8.5,
    width: 12
  },
  letters: 'AA',
  letterAspectHeight: 0.26,
  materials: ['white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white'],
  positions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  activeLetter: -1,
  editing: false,
  editingBag: false,
  step: "custom-bar",
  navActive: false
}

var lastState = Object.assign({}, state);

//
// EVENT HANDLING
//

// tap bag to modify
$(document).on('click', '.js-bag', function(evt) {
  setState({
    editing: true,
    editingBag: true,
  })
})

// input to change both letters
$(document).on('input', '.js-bag-input', function(evt) {
  if ($(this).val().match(/[^A-z]/)) { return $(this).val(state.letters) }

  var newState = { letters: $(this).val() }

  // reset active letter pointer if letters are deleted
  if( $(this).val().length < state.letters.length ) {
    const letterIndexes = $(this).val().length - 1;
    newState.activeLetter = Math.min(letterIndexes, state.activeLetter);
  }

  setState(newState)
})
$(document).on('focus', '.js-bag-input', autoselect)
$(document).on('click', '.js-bag-input', autoselect)

// input to change a single letter
$(document).on('input', '.js-input', function(evt) {
  var letters = state.letters.split('')
  letters.splice(state.activeLetter, 1, $(this).val())

  setState({
    letters: letters.join(''),
  })
})
$(document).on('focus', '.js-input', autoselect)
$(document).on('click', '.js-input', autoselect)

// select material swatch for individual letter
$(document).on('click', '.js-swatch-link', function(evt) {
  var materials = state.materials.concat([])
  var color = $(this).data('color')
  if (state.editingBag) {
    materials = materials.map(function(m) { return color })
  } else {
    materials[state.activeLetter] = $(this).data('color')
  }

  setState({
    materials: materials
  })
})

// select bag style
$(document).on('click', '.js-bag-style-link', function(evt) {
  setState({
    bag: { color: state.bag.color, style: $(this).data('style') }
  })

})

// select bag color
$(document).on('click', '.js-bag-color-link', function(evt) {
  setState({
    bag: { color: $(this).data('color'), style: state.bag.style }
  })
})

// show custom bar customization step

$(document).on('click', '.js-show-custom-bar', function(evt) {
  setState({
    step: "custom-bar"
  })

})

// show style selector step
$(document).on('click', '.js-back-to-bag-styles', function(evt) {
  setState({
    step: "style"
  })
})

// remove individual letter from bag
$(document).on('click', '.js-remove-letter', function(evt) {
  var letters = state.letters.split('')
  letters.splice(state.activeLetter, 1)
  setState({
    letters: letters.join(''),
    editing: false,
  })
})

// edit individual letter
$(document).on('click', '.js-letter', function(evt) {
  evt.stopPropagation()
  if ($(this).data('index') > -1) {
    setState({
      editing: true,
      editingBag: false,
      activeLetter: $(this).data('index'),
    })
  }
})

$(document).on('click', '.js-tab', function(evt) {
  if ($(this).data('index') > -1) {
    setState({
      editing: true,
      editingBag: false,
      activeLetter: $(this).data('index'),
    })
  } else {
    setState({
      editing: false,
      editingBag: true,
      activeLetter: $(this).data('index'),
    })
  }

})

// stop editing
$(document).on('click', '.js-close-palette', function(evt) {
  setState({
    editing: false,
    editingBag: false
  })
})

$(window).on('resize', resize)

function setState(newState) {
  lastState = Object.assign({}, state)
  state = Object.assign({}, state, newState)
  if (window.location.href.match(/localhost/)) {
    console.log('set', newState, 'state is now', state)
  }
  render()
}

function updateCustomInfo() {
  var productDescription = state.bag.style + "-" + state.bag.color
  if (state.letters.length > 0) {
    productDescription += ` / ${state.letters[0].toUpperCase()}-${state.materials[0]}`
  }
  if (state.letters.length > 1) {
    productDescription += ` / ${state.letters[1].toUpperCase()}-${state.materials[1]}`
  }
  $("#custombar-custom-info").val(productDescription);
}

function resize() {
  $("#customBarSectionMain").height($("#customBarSectionMain").parent().height() + "px")
  $(".js-tab-cnr").height($(".js-tab-back:not(.js-tab-back-all)").width())
  $(".js-tab-back-all").css({ fontSize: ($(".js-tab-cnr").height() * 0.75) + "px" })
  $(".js-swatch").height(($(".js-palette").height() / 3) + "px")
  $(".js-letter-label").height($("js-bag-input").height())
  $(".js-letters").height(($(".js-bag-custom").height() * state.letterAspectHeight) + "px")
}

function render() {
  if (state.step == "style") {
    // show style selector step
    $("#styleViewSection").css({ display: "block" })
    $("#customBarSectionMain").css({ display: "none" })
    $(".show-custom-bar").css({ display: "flex" })
    $(".back-to-bag-styles").css({ display: "none" })
    $(".check-my-custom-out").css({ display: "none" })
  }

  if (state.step == "custom-bar") {
    // reset
    $('.js-letters').find('.js-letter').remove()
    $('.js-tab-cnr').find('.js-tab:not([data-index=-1])').parents('.js-tab-back').remove()
    $('.js-tab').html('')
    $('.js-preview').html('')
    $('.js-tab').removeClass('active')
    $('.js-tab-back').removeClass('active')
    $('.js-swatch').removeClass('active')
    $('.js-loading').hide()

    // show custom-bar step
    $("#styleViewSection").css({ display: "none" })
    $("#customBarSectionMain").css({ display: "block" })
    if (state.navActive == true) {
      $(".show-custom-bar").css({ display: "none" })
      $(".back-to-bag-styles").css({ display: "flex" })
      $(".check-my-custom-out").css({ display: "flex" })
    }

    // render bag color
    $('.js-bag-custom').css({ backgroundImage: "url(" + (window.baseUrl || '') + "assets/img/bags/" + state.bag.style + "-" + state.bag.color + ".png)" })

    // render letters in bag and preview and adds tabs

    state.letters.split('').forEach(function(l, i) {
      var letter = Letter({ letter: l, material: state.materials[i], index: i })
      var tab = Tab({ letter: l, material: state.materials[i], index: i })
      $('.js-loading').show()
      $('.js-letters').append(letter)
      $(`.js-tab[data-index=${i-1}]`).parents('.js-tab-back').after(tab)
      letter[0].onload = function() {
        $('.js-loading').hide()
        if (state.activeLetter === i) {
          $('.js-preview').append(letter.clone())
        }
      }
    })

    // render tabs
    $('.js-tab').each(function() {
      if ($(this).data('index') == -1) {
        $(this).html('All')
      } else {
        var ind = $(this).data('index')
        var src = `${window.baseUrl || ''}assets/img/letters/` + state.letters[ind].toUpperCase() + `-` + state.materials[ind] + `.png`;
        $(this).css({ background: "url(" + (window.baseUrl || '') + src + ") no-repeat", backgroundSize: "contain", backgroundPosition: "center" })
      }
    })

    // select input if we're showing a new input
    if (state.editing !== lastState.editing || (state.activeLetter !== lastState.activeLetter && state.activeLetter === state.letters.length)) {
      $('.js-input').select()
    }

    // render active tab

    $(`.js-tab[data-index=${state.activeLetter}]`).addClass('active')
    $(`.js-tab[data-index=${state.activeLetter}]`).parents('.js-tab-back').addClass('active')

    // render active swatch
    $(`.js-swatch[data-color=${state.materials[state.activeLetter]}]`).addClass('active')

    // set value of inputs
    $('.js-bag-input').val(state.letters)
    $('.js-input').val(state.letters[state.activeLetter])
  }
  // update shopify hidden input
  updateCustomInfo()
}

function autoselect() {
  $(this).select()
}

function Letter(props) {
  var alt = `${props.letter} in ${props.material}`
  var src = `${window.baseUrl || ''}assets/img/letters/${props.letter.toUpperCase()}-${props.material}.png`;
  return $(`

  `)
}

function Tab(props) {
  var alt = `${props.letter} in ${props.material}`
  var src = `${window.baseUrl || ''}assets/img/letters/${props.letter.toUpperCase()}-${props.material}.png`;

  return $(`

  `)
}
var imageCache = {}

function loadImage(src, cb) {
  if (!imageCache[src]) {
    imageCache[src] = new Image
    imageCache[src].src = src
  }
  imageCache[src].onload = function() {
    imageCache[src].loaded = true
    cb()
  }
}
<commit_msg>Use joined strings instead of string templates<commit_after>var isSale = true

$(document).ready(function() {
  // hide contact us form
  if (!window.location.href.match(/localhost/)) {
    var interval = setInterval(function() {
      var contactUs = $('body').find('img[src*="icf.improvely.com"]')
      if (!contactUs.length) { return; }
      contactUs.hide()
      clearInterval(interval)
    }, 200)
  }
  // fix odd safari bug where the delegated click is not being recognized, but only for the bag
  setTimeout(function() {
    $('.js-click').on('click', function() {})
  }, 1000)

  // get template html and embed it in the page
  fetch((window.baseUrl || '') + '/assets/html/custombar.html').then(function(response) {
    return response.text()
  }).then(function(html) {
    html = html.replace(/assets\/img\//g, (window.baseUrl || '') + 'assets/img/')
    $('#custombar').parent().css({ position: 'relative', overflow: 'hidden' })
    $('#custombar').before(html).remove()
    render()
    resize()
  })
})

var state = {
  bag: {
    color: 'black',
    style: 'danny',
    height: 8.5,
    width: 12
  },
  letters: 'AA',
  letterAspectHeight: 0.26,
  materials: ['white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white'],
  positions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  activeLetter: -1,
  editing: false,
  editingBag: false,
  step: "custom-bar",
  navActive: false
}

var lastState = Object.assign({}, state);

//
// EVENT HANDLING
//

// tap bag to modify
$(document).on('click', '.js-bag', function(evt) {
  setState({
    editing: true,
    editingBag: true,
  })
})

// input to change both letters
$(document).on('input', '.js-bag-input', function(evt) {
  if ($(this).val().match(/[^A-z]/)) { return $(this).val(state.letters) }

  var newState = { letters: $(this).val() }

  // reset active letter pointer if letters are deleted
  if( $(this).val().length < state.letters.length ) {
    const letterIndexes = $(this).val().length - 1;
    newState.activeLetter = Math.min(letterIndexes, state.activeLetter);
  }

  setState(newState)
})
$(document).on('focus', '.js-bag-input', autoselect)
$(document).on('click', '.js-bag-input', autoselect)

// input to change a single letter
$(document).on('input', '.js-input', function(evt) {
  var letters = state.letters.split('')
  letters.splice(state.activeLetter, 1, $(this).val())

  setState({
    letters: letters.join(''),
  })
})
$(document).on('focus', '.js-input', autoselect)
$(document).on('click', '.js-input', autoselect)

// select material swatch for individual letter
$(document).on('click', '.js-swatch-link', function(evt) {
  var materials = state.materials.concat([])
  var color = $(this).data('color')
  if (state.editingBag) {
    materials = materials.map(function(m) { return color })
  } else {
    materials[state.activeLetter] = $(this).data('color')
  }

  setState({
    materials: materials
  })
})

// select bag style
$(document).on('click', '.js-bag-style-link', function(evt) {
  setState({
    bag: { color: state.bag.color, style: $(this).data('style') }
  })

})

// select bag color
$(document).on('click', '.js-bag-color-link', function(evt) {
  setState({
    bag: { color: $(this).data('color'), style: state.bag.style }
  })
})

// show custom bar customization step

$(document).on('click', '.js-show-custom-bar', function(evt) {
  setState({
    step: "custom-bar"
  })

})

// show style selector step
$(document).on('click', '.js-back-to-bag-styles', function(evt) {
  setState({
    step: "style"
  })
})

// remove individual letter from bag
$(document).on('click', '.js-remove-letter', function(evt) {
  var letters = state.letters.split('')
  letters.splice(state.activeLetter, 1)
  setState({
    letters: letters.join(''),
    editing: false,
  })
})

// edit individual letter
$(document).on('click', '.js-letter', function(evt) {
  evt.stopPropagation()
  if ($(this).data('index') > -1) {
    setState({
      editing: true,
      editingBag: false,
      activeLetter: $(this).data('index'),
    })
  }
})

$(document).on('click', '.js-tab', function(evt) {
  if ($(this).data('index') > -1) {
    setState({
      editing: true,
      editingBag: false,
      activeLetter: $(this).data('index'),
    })
  } else {
    setState({
      editing: false,
      editingBag: true,
      activeLetter: $(this).data('index'),
    })
  }

})

// stop editing
$(document).on('click', '.js-close-palette', function(evt) {
  setState({
    editing: false,
    editingBag: false
  })
})

$(window).on('resize', resize)

function setState(newState) {
  lastState = Object.assign({}, state)
  state = Object.assign({}, state, newState)
  if (window.location.href.match(/localhost/)) {
    console.log('set', newState, 'state is now', state)
  }
  render()
}

function updateCustomInfo() {
  var productDescription = state.bag.style + "-" + state.bag.color
  if (state.letters.length > 0) {
    productDescription += [' / ', state.letters[0].toUpperCase(), '-', state.materials[0]].join('')
  }
  if (state.letters.length > 1) {
    productDescription += [' / ', state.letters[1].toUpperCase(), '-', state.materials[1]].join('')
  }
  $("#custombar-custom-info").val(productDescription);
}

function resize() {
  $("#customBarSectionMain").height($("#customBarSectionMain").parent().height() + "px")
  $(".js-tab-cnr").height($(".js-tab-back:not(.js-tab-back-all)").width())
  $(".js-tab-back-all").css({ fontSize: ($(".js-tab-cnr").height() * 0.75) + "px" })
  $(".js-swatch").height(($(".js-palette").height() / 3) + "px")
  $(".js-letter-label").height($("js-bag-input").height())
  $(".js-letters").height(($(".js-bag-custom").height() * state.letterAspectHeight) + "px")
}

function render() {
  if (state.step == "style") {
    // show style selector step
    $("#styleViewSection").css({ display: "block" })
    $("#customBarSectionMain").css({ display: "none" })
    $(".show-custom-bar").css({ display: "flex" })
    $(".back-to-bag-styles").css({ display: "none" })
    $(".check-my-custom-out").css({ display: "none" })
  }

  if (state.step == "custom-bar") {
    // reset
    $('.js-letters').find('.js-letter').remove()
    $('.js-tab-cnr').find('.js-tab:not([data-index=-1])').parents('.js-tab-back').remove()
    $('.js-tab').html('')
    $('.js-preview').html('')
    $('.js-tab').removeClass('active')
    $('.js-tab-back').removeClass('active')
    $('.js-swatch').removeClass('active')
    $('.js-loading').hide()

    // show custom-bar step
    $("#styleViewSection").css({ display: "none" })
    $("#customBarSectionMain").css({ display: "block" })
    if (state.navActive == true) {
      $(".show-custom-bar").css({ display: "none" })
      $(".back-to-bag-styles").css({ display: "flex" })
      $(".check-my-custom-out").css({ display: "flex" })
    }

    // render bag color
    $('.js-bag-custom').css({ backgroundImage: "url(" + (window.baseUrl || '') + "assets/img/bags/" + state.bag.style + "-" + state.bag.color + ".png)" })

    // render letters in bag and preview and adds tabs

    state.letters.split('').forEach(function(l, i) {
      var letter = Letter({ letter: l, material: state.materials[i], index: i })
      var tab = Tab({ letter: l, material: state.materials[i], index: i })
      $('.js-loading').show()
      $('.js-letters').append(letter)
      const tabSelector = ['.js-tab[data-index=',i-1,']'].join('')
      $(tabSelector).parents('.js-tab-back').after(tab)
      letter[0].onload = function() {
        $('.js-loading').hide()
        if (state.activeLetter === i) {
          $('.js-preview').append(letter.clone())
        }
      }
    })

    // render tabs
    $('.js-tab').each(function() {
      if ($(this).data('index') == -1) {
        $(this).html('All')
      } else {
        var ind = $(this).data('index')
        var src = [window.baseUrl || '', 'assets/img/letters/', state.letters[ind].toUpperCase(), '-', state.materials[ind], '.png'].join('')
        $(this).css({ background: "url(" + (window.baseUrl || '') + src + ") no-repeat", backgroundSize: "contain", backgroundPosition: "center" })
      }
    })

    // select input if we're showing a new input
    if (state.editing !== lastState.editing || (state.activeLetter !== lastState.activeLetter && state.activeLetter === state.letters.length)) {
      $('.js-input').select()
    }

    // render active tab
    const activeTabSelector = ['.js-tab[data-index=',state.activeLetter,']'].join('')
    $(activeTabSelector).addClass('active').parents('.js-tab-back').addClass('active')

    // render active swatch
    if( state.activeLetter > -1 ) {
      const activeSwatchSelector = ['.js-swatch[data-color=',state.materials[state.activeLetter],']'].join('')
      $(activeSwatchSelector).addClass('active')
    }

    // set value of inputs
    $('.js-bag-input').val(state.letters)
    $('.js-input').val(state.letters[state.activeLetter])
  }
  // update shopify hidden input
  updateCustomInfo()
}

function autoselect() {
  $(this).select()
}

function Letter(props) {
  var alt = [props.letter,' in ',props.material].join('')
  var src = [window.baseUrl || '','assets/img/letters/',props.letter.toUpperCase(),'-',props.material,'.png'].join('')
  var html = [''].join('')
  return $(html)
}

function Tab(props) {
  var alt = [props.letter,' in ', props.material].join('')
  var src = [window.baseUrl || '','assets/img/letters/',props.letter.toUpperCase(),'-',props.material,'.png'].join('')
  var html = [
    '
',
      '',
    '
',
  ].join('')

  return $(html)
}
<|endoftext|>


<commit_before>$(function() {

    function generateBoard(){
        var boardMatrix = [];
        var row=[];
        for (var i=0; i<9; i++){
            row.push(null);
        }
        for (var j=0; j < 9; j++){
            boardMatrix.push([row]);
        }
        return [[4,7,9,6,5,2,1,3,8],[6,8,5,3,4,1,9,7,2],[3,1,2,8,9,7,6,4,5],[2,5,1,9,7,3,4,8,6],[8,9,3,1,6,4,2,5,7],[7,6,4,5,2,8,3,9,1],[5,2,8,4,3,6,7,1,9],[9,3,6,7,1,5,8,2,4],[1,4,7,2,8,9,5,6,3]]
        // return populateBoard(boardMatrix);
    }
//
    // function populateBoard(board){
//
        // var availableMoves;
        // var valueIndex;
        // for (var row=0; row<9; row++){
            // console.log("row is"+row);
            // availableMoves = [1,2,3,4,5,6,7,8,9];
            // for (var col=0; col<9; col++){
                // valueIndex = Math.floor(Math.random() * availableMoves.length);
                // if (checkMove(availableMoves[valueIndex], row, col)){
                    // board[row][col] = availableMoves[valueIndex];
                    // availableMoves.splice(valueIndex, 1);
                // }else{
                    // col--;
                    // var value = board[row][col];
                    // board[row][col] = null;
                    // availableMoves.push(value);
                    // if (col>0){
                        // col--;
                    // }else{
                        // row--;
                        // col=9;
                    // }
                    //
                // }
//
            // }
        // }
//
        // function checkMove(value, row, col){
            // for (var move=0; move<9; move++){
                // check row
                // if(board[row][move]===value){
                    // return false;
                // }
                // check column
                // if (board[move][col]===value){
                    // return false;
                // }
            // }
            // check square
            // var row_square = Math.floor(row/3);
            // var col_square = Math.floor(col/3);
//
            // for (var row_count=row_square*3; row_count<=row_square*3+2; row_count++){
                // for (var col_count=col_square*3; col_count<=col_square*3+2; col_count++){
                    // if(board[row_count][col_count]===value){
                        // console.log('square faliure');
                        // return false;
                    // }
                // }
            // }
            // return true;
//
        // }
        // return board;
    // }
//

    function pickPermanent(){
        var possibleOptions = []
        for (var k=0; k<9; k++){
            for (var j=0; j<9; j++){
                possibleOptions.push([k, j])
            }
        }
        var permanent = _.sample(possibleOptions, 20);
        console.log('permanent is'+permanent);
        return permanent;
    }

    var Board = React.createClass({
        getInitialState: function(){
            var layout = generateBoard();
            console.log('layout is'+layout);
            var permanentNumbers = pickPermanent()
            return {boardLayout: layout, numberSelected: null, permanent: permanentNumbers};
        },

        numberSelected: function(number){
            this.setState({numberSelected: number});
            console.log("number selected is"+this.state.numberSelected);
        },

        isPermanent: function(row, column){
            var permanentNumbers = this.state.permanent;
            if ($.inArray([row,column], permanentNumbers)===-1){
                return false;
            }
            return true;

        },

        render: function(){
            var num = this.state.numberSelected;
            var board = this.state.boardLayout;
            var permanent = pickPermanent();
            console.log('permie is '+ permanent)
            return (

                    {this.state.boardLayout.map(function(row) {
                        return (

                            {row.map(function(col) {
                              return <Cell row={board.indexOf(row)} col={row.indexOf(col)} innerValue={col} value={col} numSelected={num}/>;
                            })}

                        );
                      })}

                        <Numbers numSelected={this.numberSelected}/>

            );

        }
    });

    var Cell = React.createClass({
        clickedCell: function(evt){
            if (this.props.numSelected){
                // $(evt.target).attr("disabled",true);
                evt.target.innerHTML = this.props.numSelected;
                // $(evt.target).val(this.props.numberSelected);
            }
        },
        render: function(){
            console.log("row"+this.props.row);
            console.log("column"+this.props.col);
            return <button onClick={this.clickedCell}>{this.props.value}</button>
        }

    });

    var Numbers = React.createClass({
        changeNumber: function(evt){
            this.props.numSelected(evt.target.innerHTML);
        },
        render: function(){
            return (

                    <button onClick={this.changeNumber}>1</button>
                    <button onClick={this.changeNumber}>2</button>
                    <button onClick={this.changeNumber}>3</button>
                    <button onClick={this.changeNumber}>4</button>
                    <button onClick={this.changeNumber}>5</button>
                    <button onClick={this.changeNumber}>6</button>
                    <button onClick={this.changeNumber}>7</button>
                    <button onClick={this.changeNumber}>8</button>
                    <button onClick={this.changeNumber}>9</button>

            );

        }
    });

    ReactDOM.render(
      <Board/>,
      document.getElementById('sudoku')
    );
});<commit_msg>later commit<commit_after>$(function() {

    function generateBoard(){
        var boardMatrix = [];
        var row=[];
        for (var i=0; i<9; i++){
            row.push(null);
        }
        for (var j=0; j < 9; j++){
            boardMatrix.push([row]);
        }
        return [[4,7,9,6,5,2,1,3,8],[6,8,5,3,4,1,9,7,2],[3,1,2,8,9,7,6,4,5],[2,5,1,9,7,3,4,8,6],[8,9,3,1,6,4,2,5,7],[7,6,4,5,2,8,3,9,1],[5,2,8,4,3,6,7,1,9],[9,3,6,7,1,5,8,2,4],[1,4,7,2,8,9,5,6,3]]
        // return populateBoard(boardMatrix);
    }
//
    // function populateBoard(board){
//
        // var availableMoves;
        // var valueIndex;
        // for (var row=0; row<9; row++){
            // console.log("row is"+row);
            // availableMoves = [1,2,3,4,5,6,7,8,9];
            // for (var col=0; col<9; col++){
                // valueIndex = Math.floor(Math.random() * availableMoves.length);
                // if (checkMove(availableMoves[valueIndex], row, col)){
                    // board[row][col] = availableMoves[valueIndex];
                    // availableMoves.splice(valueIndex, 1);
                // }else{
                    // col--;
                    // var value = board[row][col];
                    // board[row][col] = null;
                    // availableMoves.push(value);
                    // if (col>0){
                        // col--;
                    // }else{
                        // row--;
                        // col=9;
                    // }
                    //
                // }
//
            // }
        // }
//
        // function checkMove(value, row, col){
            // for (var move=0; move<9; move++){
                // check row
                // if(board[row][move]===value){
                    // return false;
                // }
                // check column
                // if (board[move][col]===value){
                    // return false;
                // }
            // }
            // check square
            // var row_square = Math.floor(row/3);
            // var col_square = Math.floor(col/3);
//
            // for (var row_count=row_square*3; row_count<=row_square*3+2; row_count++){
                // for (var col_count=col_square*3; col_count<=col_square*3+2; col_count++){
                    // if(board[row_count][col_count]===value){
                        // console.log('square faliure');
                        // return false;
                    // }
                // }
            // }
            // return true;
//
        // }
        // return board;
    // }
//

    function pickPermanent(){
        var possibleOptions = []
        for (var k=0; k<9; k++){
            for (var j=0; j<9; j++){
                possibleOptions.push([k, j])
            }
        }
        var permanent = _.sample(possibleOptions, 20);
        console.log('permanent is length'+permanent.length);
        return permanent;
    }

    var Board = React.createClass({
        getInitialState: function(){
            var layout = generateBoard();
            console.log('layout is'+layout);
            var permanentNumbers = pickPermanent();
            return {boardLayout: layout, numberSelected: null, permanent: permanentNumbers};
        },

        numberSelected: function(number){
            this.setState({numberSelected: number});
            console.log("number selected is"+this.state.numberSelected);
        },

        render: function(){
            var num = this.state.numberSelected;
            var board = this.state.boardLayout;
            var permanent = this.state.permanent;
            var counter = 0;
            return (

                    {this.state.boardLayout.map(function(val1) {
                        return (

                            {val1.map(function(val2) {
                                counter += 1;
                                return <Cell row={board.indexOf(val1)} id={counter} key={counter} col={val1.indexOf(val2)} innerValue={val2} permanent={permanent} value={val2} numSelected={num}/>;
                            })}

                        );
                      })}

                        <Numbers numSelected={this.numberSelected}/>

                    <Check />

            );

        }
    });

    var Check = React.createClass({
        checkBoard: function(evt){
            for (var w=0; w<80; w++){
                if $("#"+i)}
            console.log("hereee");
            console.log(Cell.innerValue)
            $("div#board-row").each(function(){
                console.log("here");
                console.log($(this).text());
                console.log($(this).children())

            })

        },
        render: function(){
            return <button onClick={this.checkBoard}>Check</button>
        }
    });

    var Cell = React.createClass({
        getInitialState: function(){
            var row = this.props.row;
            var column = this.props.col;
            var value = this.showValue(row, column, this.props.innerValue);
            var permanentBoolean;
            if(value===0){
                permanentBoolean = false;
                }else{
                permanentBoolean = true;
            }
            return {permanent: permanentBoolean, value: value}

        },
        clickedCell: function(evt){
            if (this.props.numSelected && this.state.permanent === false){
                // $(evt.target).attr("disabled",true);
                evt.target.innerHTML = this.props.numSelected;
                // $(evt.target).val(this.props.numberSelected);
            }
        },

        showValue: function(row, column, value){
            for (var p=0; p<20; p++){
                console.log("[rc]"+[row, column])
                if (row === this.props.permanent[p][0] && column === this.props.permanent[p][1]){
                    return 0;
                }
            }
            return value;

        },

        render: function(){

            return <button onClick={this.clickedCell}>{this.state.value}</button>
        }

    });

    var Numbers = React.createClass({
        changeNumber: function(evt){
            this.props.numSelected(evt.target.innerHTML);
        },
        render: function(){
            return (

                    <button onClick={this.changeNumber}>1</button>
                    <button onClick={this.changeNumber}>2</button>
                    <button onClick={this.changeNumber}>3</button>
                    <button onClick={this.changeNumber}>4</button>
                    <button onClick={this.changeNumber}>5</button>
                    <button onClick={this.changeNumber}>6</button>
                    <button onClick={this.changeNumber}>7</button>
                    <button onClick={this.changeNumber}>8</button>
                    <button onClick={this.changeNumber}>9</button>

            );

        }
    });

    ReactDOM.render(
      <Board/>,
      document.getElementById('sudoku')
    );
});<|endoftext|>


<commit_before>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var fileManager = options.fileManager;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move picture to permanent storage using jquery-file-upload-middleware'filehandler
     */
    var movePicture = function (req, picture) {
        var status = {ok: true, error: ""};
        var userId = req.session.userId;
        fileManager.movePictureToPermanentStorage(picture.url, userId, function (error, result) {

            if (!error && !!result) {
                picture.url = result.url;
                picture.thumbnailUrl = result.thumbnailUrl;

                underscore.each(picture.img, function (image) {
                    //is thumbnail if width and height is set
                    if (!!image.width && !!image.height) {
                        image.url = result.thumbnailUrl;
                    } else {
                        image.url = result.url;
                    }
                });

                console.log("moved picture: ", picture);

            } else {
                status.error = "Error moving file to permanent storage";
                status.ok = false;
                console.error(status.error);
            }
        });
        return status;
    };

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            console.error("id is missing in result after post!");
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride) {
        var apiKey = "?api_key=" + ntbApiKey;
        var url = ntbApiUri + path + apiKey;
        var method = req.method;

        console.log("url " + url);

        var onCompleteDefault = function (data) {
            console.log(data);
            if (data.document !== undefined) {
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data) {
            console.log("Response: ", data);
            moveId(data);
            res.json(data);
        };

        var onCompletePostPicture = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        if (method === "GET") {
            console.log("getUrl = " + url);
            restler.get(url, {})
                .on('complete', onComplete);

        } else if (method === "POST") {
            console.log("Posting: " + util.inspect(req.body));

            //Move pictures to permanent storage when saving to rest api. Updates results object with new urls.
            if (path.indexOf("bilder") > -1) {
                var result = movePicture(req, req.body);
                var resultOk = result.ok;
                var error = result.error;
                if (resultOk) {
                    restler.postJson(url, req.body)
                        .on('complete', function (data) {
                            onCompletePostPicture(data, req.body);
                        });
                } else {
                    restler.abort(error);
                }

            } else {
                restler.postJson(url, req.body)
                    .on('complete', onCompletePost);
            }

        } else if (method === "PUT") {
            var json = JSON.stringify(req.body);
            console.log("putUrl = " + url);
            var options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            restler.put(url, options)
                .on('complete', onComplete);

        } else if (method === "DELETE") {
            console.log("Deleting: " + url);
            restler.del(url, {})
                .on('complete', onComplete);
        }
    }

    // var makeRequest = function (path, method, req, res, onCompleteOverride) {

    app.all('/restProxy/*', function (req, res) {
        var path = req.url;
        path = path.replace("restProxy/", "");
        makeRequest(path, req, res);
    });

    return { makeApiRequest : makeRequest };
};

<commit_msg>Removed duplicate console log<commit_after>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var fileManager = options.fileManager;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move picture to permanent storage using jquery-file-upload-middleware'filehandler
     */
    var movePicture = function (req, picture) {
        var status = {ok: true, error: ""};
        var userId = req.session.userId;
        fileManager.movePictureToPermanentStorage(picture.url, userId, function (error, result) {

            if (!error && !!result) {
                picture.url = result.url;
                picture.thumbnailUrl = result.thumbnailUrl;

                underscore.each(picture.img, function (image) {
                    //is thumbnail if width and height is set
                    if (!!image.width && !!image.height) {
                        image.url = result.thumbnailUrl;
                    } else {
                        image.url = result.url;
                    }
                });

                console.log("moved picture: ", picture);

            } else {
                status.error = 'Error moving file to permanent storage';
                status.ok = false;
                console.error(status.error);
            }
        });
        return status;
    };

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            console.error('id is missing in result after post!');
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride) {
        var apiKey = '?api_key=' + ntbApiKey;
        var url = ntbApiUri + path + apiKey;
        var method = req.method;

        console.log("Request url " + url);

        var onCompleteDefault = function (data) {
            console.log(data);
            if (data.document !== undefined) {
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data) {
            console.log("Response: ", data);
            moveId(data);
            res.json(data);
        };

        var onCompletePostPicture = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        if (method === "GET") {
            // console.log("getUrl = " + url);
            restler.get(url, {})
                .on('complete', onComplete);

        } else if (method === "POST") {
            console.log("Posting: " + util.inspect(req.body));

            //Move pictures to permanent storage when saving to rest api. Updates results object with new urls.
            if (path.indexOf("bilder") > -1) {
                var result = movePicture(req, req.body);
                var resultOk = result.ok;
                var error = result.error;
                if (resultOk) {
                    restler.postJson(url, req.body)
                        .on('complete', function (data) {
                            onCompletePostPicture(data, req.body);
                        });
                } else {
                    restler.abort(error);
                }

            } else {
                restler.postJson(url, req.body)
                    .on('complete', onCompletePost);
            }

        } else if (method === "PUT") {
            var json = JSON.stringify(req.body);
            console.log("putUrl = " + url);
            var options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            restler.put(url, options)
                .on('complete', onComplete);

        } else if (method === "DELETE") {
            console.log("Deleting: " + url);
            restler.del(url, {})
                .on('complete', onComplete);
        }
    }

    // var makeRequest = function (path, method, req, res, onCompleteOverride) {

    app.all('/restProxy/*', function (req, res) {
        var path = req.url;
        path = path.replace("restProxy/", "");
        makeRequest(path, req, res);
    });

    return { makeApiRequest : makeRequest };
};

<|endoftext|>


<commit_before>
// Your Client ID can be retrieved from your project in the Google
// Developer Console, https://console.developers.google.com
var CLIENT_ID = '<YOUR_CLIENT_ID>';

var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];

/**
  * Check if current user has authorized this application.
  */
function checkAuth() {
  gapi.auth.authorize(
    {
      'client_id': CLIENT_ID,
      'scope': SCOPES.join(' '),
      'immediate': true
    }, handleAuthResult);
}

/**
  * Handle response from authorization server.
  *
  * @param {Object} authResult Authorization result.
  */
function handleAuthResult(authResult) {
  var authorizeDiv = document.getElementById('authorize-div');
  if (authResult && !authResult.error) {
    // Hide auth UI, then load client library.
    authorizeDiv.style.display = 'none';
    loadDriveApi();
  } else {
    // Show auth UI, allowing the user to initiate authorization by
    // clicking authorize button.
    authorizeDiv.style.display = 'inline';
  }
}

/**
  * Initiate auth flow in response to user clicking authorize button.
  *
  * @param {Event} event Button click event.
  */
function handleAuthClick(event) {
  gapi.auth.authorize(
    {client_id: CLIENT_ID, scope: SCOPES, immediate: false},
    handleAuthResult);
  return false;
}

/**
  * Load Drive API client library.
  */
function loadDriveApi() {
  gapi.client.load('drive', 'v2', listFiles);
}

/**
  * Print files.
  */
function listFiles() {
  var request = gapi.client.drive.files.list({
      'maxResults': 10
    });

    request.execute(function(resp) {
      appendPre('Files:');
      var files = resp.items;
      if (files && files.length > 0) {
        for (var i = 0; i < files.length; i++) {
          var file = files[i];
          appendPre(file.title + ' (' + file.id + ')');
        }
      } else {
        appendPre('No files found.');
      }
    });
}

/**
  * Append a pre element to the body containing the given message
  * as its text node.
  *
  * @param {string} message Text to be placed in pre element.
  */
function appendPre(message) {
  var pre = document.getElementById('output');
  var textContent = document.createTextNode(message + '\n');
  pre.appendChild(textContent);
}
<commit_msg>Added the client ID<commit_after>
// Your Client ID can be retrieved from your project in the Google
// Developer Console, https://console.developers.google.com
var CLIENT_ID = '681676105907-omec1itmltlnknrdfo150qcn7pdt95ri.apps.googleusercontent.com';

var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];

/**
  * Check if current user has authorized this application.
  */
function checkAuth() {
  gapi.auth.authorize(
    {
      'client_id': CLIENT_ID,
      'scope': SCOPES.join(' '),
      'immediate': true
    }, handleAuthResult);
}

/**
  * Handle response from authorization server.
  *
  * @param {Object} authResult Authorization result.
  */
function handleAuthResult(authResult) {
  var authorizeDiv = document.getElementById('authorize-div');
  if (authResult && !authResult.error) {
    // Hide auth UI, then load client library.
    authorizeDiv.style.display = 'none';
    loadDriveApi();
  } else {
    // Show auth UI, allowing the user to initiate authorization by
    // clicking authorize button.
    authorizeDiv.style.display = 'inline';
  }
}

/**
  * Initiate auth flow in response to user clicking authorize button.
  *
  * @param {Event} event Button click event.
  */
function handleAuthClick(event) {
  gapi.auth.authorize(
    {client_id: CLIENT_ID, scope: SCOPES, immediate: false},
    handleAuthResult);
  return false;
}

/**
  * Load Drive API client library.
  */
function loadDriveApi() {
  gapi.client.load('drive', 'v2', listFiles);
}

/**
  * Print files.
  */
function listFiles() {
  var request = gapi.client.drive.files.list({
      'maxResults': 10
    });

    request.execute(function(resp) {
      appendPre('Files:');
      var files = resp.items;
      if (files && files.length > 0) {
        for (var i = 0; i < files.length; i++) {
          var file = files[i];
          appendPre(file.title + ' (' + file.id + ')');
        }
      } else {
        appendPre('No files found.');
      }
    });
}

/**
  * Append a pre element to the body containing the given message
  * as its text node.
  *
  * @param {string} message Text to be placed in pre element.
  */
function appendPre(message) {
  var pre = document.getElementById('output');
  var textContent = document.createTextNode(message + '\n');
  pre.appendChild(textContent);
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
(function(global) {

var AbRecipientImagePopupSidebar = {
  get tree() {
    return document.getElementById('abResultsTree');
  },

  init: function() {
    window.removeEventListener('load', this, false);
    window.addEventListener('unload', this, false);
    this.tree.addEventListener('select', this, true);
    this.tree.addEventListener('mousemove', this, true);
  },

  destroy: function() {
    window.removeEventListener('unload', this, false);
    this.tree.removeEventListener('select', this, true);
    this.tree.removeEventListener('mousemove', this, true);
  },

  handleSelectionChange: function() {
    var cards = GetSelectedAbCards();
    if (cards.length > 0)
      this.showForCard(cards[0]);
  },

  handleMouseMove: function(aEvent) {
    if (this.delayedHandleMouseMoveTimer)
      window.clearTimeout(this.delayedHandleMouseMoveTimer);

    var row = this.tree.treeBoxObject.getRowAt(aEvent.clientX, aEvent.clientY);
    var card = null;
    if (row) {
      card = gAbView.getCardFromRow(row);
    }

    this.delayedHandleMouseMoveTimer = window.setTimeout((function() {
      this.delayedHandleMouseMoveTimer = null;
      var maybeShown = card && this.showForCard(card);
      if (!maybeShown)
        AbRecipientImagePopup.hide();
    }).bind(this), 100);
  },

  showForCard: function(aCard) {
    AbRecipientImagePopup.hide();

    var directoryURI = GetSelectedDirectory();
    var directory =  GetDirectoryFromURI(directoryURI);

    AbRecipientImagePopup.show({
      card:          aCard,
      book:          directory,
      // Popup always eats click events on the anchor element, so
      // we have to specify other element as the anchor.
      // (The previous element of the tree is <separator/> and
      // events on the element can be ignored.)
      anchorElement: this.tree.previousSibling,
      position:      'side'
    });
  },

  handleEvent: function(aEvent) {
    switch (aEvent.type) {
      case 'load':
        this.init();
        return;

      case 'unload':
        this.destroy();
        return;

      case 'select':
        this.handleSelectionChange();
        return;

      case 'mousemove':
        this.handleMouseMove(aEvent);
        return;
    }
  }
};

window.addEventListener('load', AbRecipientImagePopupSidebar, false);

global.AbRecipientImagePopupSidebar = AbRecipientImagePopupSidebar;
})(this);
<commit_msg>Ignore invalid row index<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
(function(global) {

var AbRecipientImagePopupSidebar = {
  get tree() {
    return document.getElementById('abResultsTree');
  },

  init: function() {
    window.removeEventListener('load', this, false);
    window.addEventListener('unload', this, false);
    this.tree.addEventListener('select', this, true);
    this.tree.addEventListener('mousemove', this, true);
  },

  destroy: function() {
    window.removeEventListener('unload', this, false);
    this.tree.removeEventListener('select', this, true);
    this.tree.removeEventListener('mousemove', this, true);
  },

  handleSelectionChange: function() {
    var cards = GetSelectedAbCards();
    if (cards.length > 0)
      this.showForCard(cards[0]);
  },

  handleMouseMove: function(aEvent) {
    if (this.delayedHandleMouseMoveTimer)
      window.clearTimeout(this.delayedHandleMouseMoveTimer);

    var row = this.tree.treeBoxObject.getRowAt(aEvent.clientX, aEvent.clientY);
    var card = null;
    if (row > -1)
      card = gAbView.getCardFromRow(row);
    }

    this.delayedHandleMouseMoveTimer = window.setTimeout((function() {
      this.delayedHandleMouseMoveTimer = null;
      var maybeShown = card && this.showForCard(card);
      if (!maybeShown)
        AbRecipientImagePopup.hide();
    }).bind(this), 100);
  },

  showForCard: function(aCard) {
    AbRecipientImagePopup.hide();

    var directoryURI = GetSelectedDirectory();
    var directory =  GetDirectoryFromURI(directoryURI);

    AbRecipientImagePopup.show({
      card:          aCard,
      book:          directory,
      // Popup always eats click events on the anchor element, so
      // we have to specify other element as the anchor.
      // (The previous element of the tree is <separator/> and
      // events on the element can be ignored.)
      anchorElement: this.tree.previousSibling,
      position:      'side'
    });
  },

  handleEvent: function(aEvent) {
    switch (aEvent.type) {
      case 'load':
        this.init();
        return;

      case 'unload':
        this.destroy();
        return;

      case 'select':
        this.handleSelectionChange();
        return;

      case 'mousemove':
        this.handleMouseMove(aEvent);
        return;
    }
  }
};

window.addEventListener('load', AbRecipientImagePopupSidebar, false);

global.AbRecipientImagePopupSidebar = AbRecipientImagePopupSidebar;
})(this);
<|endoftext|>


<commit_before>var SendGrid = require('../../lib/sendgrid');
var Email = require('../../lib/Email');

describe('attachments', function(){
  var sendgrid;
  beforeEach(function() {
    sendgrid = new SendGrid(setup.api_user, setup.api_key);
  });

  describe('web', function() {
    var mail;
    beforeEach(function() {
      mail = new Email({
        to: setup.single_to,
        from: setup.from,
        text: 'test of web files'
      });
    });

    it('should be able to send files via path', function(done) {
      var file = {
        filename: 'logo.png',
        path: __dirname + '/../assets/logo.png'
      };

      mail.subject = '(Web-path) File attachments';
      mail.addFile(file);
      console.log('now sending');
      sendgrid.send(mail, function(success, message) {
        console.log('message: %s', message);
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via url', function(done) {
      var file = {
        filename: 'icon.jpg',
        url: 'http://i.imgur.com/2fDh8.jpg'
      };

      mail.subject = '(Web-url) File attachments';
      mail.addFile(file);
      sendgrid.send(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via content', function(done) {
      var file = {
        filename: 'hello_snowman.txt',
        content: new Buffer("Hello ☃, I hope you don't melt", 'utf-8'),
        contentType: 'text/plain'
      };

      mail.subject = '(Web-content) File attachments';
      mail.addFile(file);
      sendgrid.send(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });
  });

  describe('smtp', function() {
    var mail;
    beforeEach(function() {
      mail = new Email({
        to: setup.single_to,
        from: setup.from,
        text: 'test of smtp files'
      });
    });

    it('should be able to send files via path', function(done) {
      var file = {
        filename: 'logo.png',
        path: __dirname + '/../assets/logo.png'
      };

      mail.subject = '(Smtp-path) File attachments';
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        console.log('message: %s', message);
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via url', function(done) {
      var file = {
        filename: 'icon.jpg',
        url: 'http://i.imgur.com/2fDh8.jpg'
      };

      mail.subject = '(Smtp-url) File attachments';
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via content', function(done) {
      var file = {
        filename: 'hello_snowman.txt',
        content: new Buffer("Hello ☃, I hope you don't melt", 'utf-8'),
        contentType: 'text/plain'
      };

      mail.subject = '(Smtp-content) File attachments';
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });
  });

});
<commit_msg>added a test to send multiple files<commit_after>var SendGrid = require('../../lib/sendgrid');
var Email = require('../../lib/Email');

describe('attachments', function(){
  var sendgrid;
  beforeEach(function() {
    sendgrid = new SendGrid(setup.api_user, setup.api_key);
  });

  describe('web', function() {
    var mail;
    beforeEach(function() {
      mail = new Email({
        to: setup.single_to,
        from: setup.from,
        text: 'test of web files'
      });
    });

    it('should be able to send files via path', function(done) {
      var file = {
        filename: 'logo.png',
        path: __dirname + '/../assets/logo.png'
      };

      mail.subject = '(Web-path) File attachments';
      mail.addFile(file);
      console.log('now sending');
      sendgrid.send(mail, function(success, message) {
        console.log('message: %s', message);
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via url', function(done) {
      var file = {
        filename: 'icon.jpg',
        url: 'http://i.imgur.com/2fDh8.jpg'
      };

      mail.subject = '(Web-url) File attachments';
      mail.addFile(file);
      sendgrid.send(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via content', function(done) {
      var file = {
        filename: 'hello_snowman.txt',
        content: new Buffer("Hello ☃, I hope you don't melt", 'utf-8'),
        contentType: 'text/plain'
      };

      mail.subject = '(Web-content) File attachments';
      mail.addFile(file);
      sendgrid.send(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });
  });

  describe('smtp', function() {
    var mail;
    beforeEach(function() {
      mail = new Email({
        to: setup.single_to,
        from: setup.from,
        text: 'test of smtp files'
      });
    });

    it('should be able to send files via path', function(done) {
      var file = {
        filename: 'logo.png',
        path: __dirname + '/../assets/logo.png'
      };

      mail.subject = '(Smtp-path) File attachments';
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        console.log('message: %s', message);
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via url', function(done) {
      var file = {
        filename: 'icon.jpg',
        url: 'http://i.imgur.com/2fDh8.jpg'
      };

      mail.subject = '(Smtp-url) File attachments';
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send files via content', function(done) {
      var file = {
        filename: 'hello_snowman.txt',
        content: new Buffer("Hello ☃, I hope you don't melt", 'utf-8'),
        contentType: 'text/plain'
      };

      mail.subject = '(Smtp-content) File attachments';
      mail.addFile(file);
      mail.addFile(file);
      sendgrid.smtp(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });

    it('should be able to send multiple files via content', function(done) {
      mail.subject = '(Smtp-content) File attachments';
      mail.addFile({
        filename: 'hello_snowman.txt',
        content: new Buffer("Hello ☃, I hope you don't melt", 'utf-8'),
        contentType: 'text/plain'
      });
      mail.addFile({
        filename: 'hello_snowman2.txt',
        content: new Buffer("Hello ☃, I hope you melt", 'utf-8'),
        contentType: 'text/plain'
      });
      sendgrid.smtp(mail, function(success, message) {
        expect(success).to.be.true;
        done();
      });
    });
  });

});
<|endoftext|>


<commit_before>/**
 * @package      SD-NodeChat
 *
 * @author       Saurin Dashadia (SD) (http://saur.in)
 * @copyright    Copyright (C) 2014 Saurin Dashadia. All rights reserved.
 * @license      http://opensource.org/licenses/MIT, see LICENSE
 */

(function (window, document, $) {

    $.SDNodeChat = function (options) {

        var _defaults = {

            /**
             * @default     localhost
             * @type        Text
             * @value       server-IP address
             * @usage       This will be consider as default server for chat
             */
            server: "localhost",

            /**
             * @default     80
             * @type        Text
             * @value       Port number
             * @usage       This will be consider as default port for the chat server
             */
            port: "80",

            /**
             * @default     null
             * @type        [object Socket]
             * @value       [object Socket]
             * @usage       This socket object will be use to communicate to server.
             */
            socket: null,

            /**
             * @default     false
             * @type        boolean
             * @value       true/false
             * @usage       This can enable or disable log on server side.
             */
            debug: false,

            /**
             * @default     null
             * @type        Text
             * @value       username
             * @usage       This can enable or disable log on server side.
             */
            username: null,

            /**
             * @default     $('#messages')
             * @type        [object HTMLUListElement]
             * @value       [object HTMLUListElement]
             * @usage       This element will be consider as chat container
             */
            chatContainer: $('#messages'),

            /**
             * @default     $('#SendButtonID')
             * @type        [object HTMLButtonElement]
             * @value       [object HTMLButtonElement]
             * @usage       This element will be consider as an action to send chat
             */
            sendButton: $('#SendButtonID'),

            /**
             * @default     $('#chatTextBoxId')
             * @type        [object HTMLInputElement]
             * @value       [object HTMLInputElement]
             * @usage       This element will be consider as chat input it can also handle action to send chat
             */
            chatBox: $('#chatTextBox'),

            /**
             * @default     true
             * @type        boolean
             * @value       true/false
             * @usage       This can enable or disable enter key as sender on chatBox
             */
            enterToSend: true,

            /**
             * @default     $('#userContainer')
             * @type        [object HTMLUListElement]
             * @value       [object HTMLUListElement]
             * @usage       This element will be consider as a container of online users list.
             */
            usersContainer: $('#userContainer'),

            /**
             * @default     "Welcome to SD-NodeChat! For more info visit SD-NodeChat@GitHub"
             * @type        [text]
             * @value       [text]
             * @usage       This is to welcome a new user. It will be ignored if value not present.
             */
            welcomeNote: "Welcome to SD-NodeChat! For more info visit SD-NodeChat@GitHub",
        }

        // extend default vaules
        var SDNodeChatConf = $.extend(_defaults, options);

        // remove trailing slash from URL using regular expression, if there any.
        SDNodeChatConf.server = SDNodeChatConf.server.replace(/\/$/, '');

        // Regualr expression for URL
        SDNodeChatConf.pattern = {};
        SDNodeChatConf.pattern.URL = /(https|http)(:\/\/)([\w\d.-]+)(:[\d]+)?([\/\w\d._-]+)?(\?[\w\d=&-_+!@%\+]+)?(#[\w\d!=%\+]+)?/ig;
        SDNodeChatConf.pattern.URLPlaceholder = '$1$2$3$4$5$6$7';

        return {
            /**
             *
             * @param       message {text}
             * @param       type    {text} ('self'/'other')
             * @returns     void
             * @usage       This function is use to display message.
             *              There are two ways to display messages
             *              1) type = 'self'    -> message from self
             *              2) type = 'other'   -> message from other users
             *              3) type = 'note'    -> Common notes to chat
             */
            addMsg : function (message, type) {
                var li = '
' + message + '
';
                $(SDNodeChatConf.chatContainer).append($(li));
                // scroll to new content
                this.scroll();
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function will be called when user send message. This function then add message
             *              to message container and will push message to server.
             */
            sendMsg: function () {

                var message = SDNodeChatConf.chatBox.val().trim();
                if (!message) return false;

                message = this.formatLink(message);

                this.addMsg(message, 'self');
                this.pushMsg(message);

                SDNodeChatConf.chatBox.val('');
                SDNodeChatConf.chatBox.focus();
            },

            /**
             * @param       message {Text}
             * @returns     message {Text}
             * @usage       This function will push a user message to server
             */
            formatLink: function (message) {
                return message.replace(SDNodeChatConf.pattern.URL, '' + SDNodeChatConf.pattern.URLPlaceholder + '');
            },

            /**
             * @param       message {Text}
             * @returns     void
             * @usage       This function will push a user message to server
             */
            pushMsg: function (message) {
                SDNodeChatConf.socket.emit('newMsg', { message: message, username: SDNodeChatConf.username });
            },

            init : function(success, fail){
                var that = this;
                var _sdnc = SDNodeChatConf;

                var hostport = [];
                hostport.push( ((_sdnc.server)?_sdnc.server:null) );
                hostport.push( ((_sdnc.server && _sdnc.port)?_sdnc.port:null) );

                // initiate socket object
                _sdnc.socket = io(hostport.join(':'));

                //ask server to add this user.
                _sdnc.socket.emit('addUser', {username: _sdnc.username});
                _sdnc.socket.on('userAdded', function(data){
                    if(data.success === true){
                        // Add welcome note
                        if(_sdnc.welcomeNote){
                            that.addMsg(_sdnc.welcomeNote,'note');
                        }

                        // listen for new user joins
                        _sdnc.socket.on('newUser', function (data) {
                            that.addMsg(data.username + ' has joined chat.', 'note');
                        });

                        // listen for user left
                        _sdnc.socket.on('userLeft', function (data) {
                            that.addMsg(data.username + ' has left.', 'note');
                        });

                        // listen for new messages over socket
                        _sdnc.socket.on('newMsg', function (data) {
                            that.addMsg(data.username + ': ' +data.message, 'other');
                        });

                        // Bind click event to sendButton
                        _sdnc.sendButton.click(function () {
                            that.sendMsg();
                        });

                        // Bind chatbox to enter press if config set to truesendMessage
                        if (_sdnc.enterToSend === true) {
                            _sdnc.chatBox.bind('keypress', function (e) {
                                // check if key is enter key
                                if (e.keyCode == 13) {
                                    that.sendMsg();
                                }
                            });
                        }

                        // Set focus to chatbox
                        _sdnc.chatBox.focus();

                        // callback
                        success();
                    }else{
                        // callback
                        fail();
                    }
                });
            },

            /**
             * @param       SDNodeChatConf key
             * @returns     SDNodeChatConf value
             * @usage       This function is to get config value.
             */
            get: function(key){
                return SDNodeChatConf[key];
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function scrolls chat container to the new added message (bottom)
             */
            scroll:function(){
                jQuery(document).scrollTop(jQuery(document).innerHeight());
            },

            /**
             * @param       void
             * @returns     string
             * @usage       This function is to query clients basic info usually a name which can be use to identify
             *              user in chat room
             */
            logMessage: function(msg,isDebug){
                // Follow global debug flag if local flag not set.
                if(typeof isDebug === 'undefined') isDebug = SDNodeChatConf.debug;
                if(isDebug) console.log(msg);
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function is use to request list of online users
             */
            getUserList: function(){
                var that = this;
                SDNodeChatConf.socket.emit('userList');
                SDNodeChatConf.socket.on('userList', function (data) {
                    that.showUserList(data);
                });
            },

            /**
             * @param       data    {object}
             * @returns     void
             * @usage       This function is use to set friends list
             */
            showUserList:function(data){
                SDNodeChatConf.usersContainer.find('li').not('.caption').remove();
                var userList = JSON.parse(data);
                var userListHTML = '';
                for(u in userList){
                    userListHTML += '
' + userList[u] + '
';
                }
                SDNodeChatConf.usersContainer.append($(userListHTML));
            }
        };
    };

}(window, document, jQuery));<commit_msg>Regular expression pattern added for URL. formatLink() function added to identify URLs inside message body and tranfer them to link. Fixes #5<commit_after>/**
 * @package      SD-NodeChat
 *
 * @author       Saurin Dashadia (SD) (http://saur.in)
 * @copyright    Copyright (C) 2014 Saurin Dashadia. All rights reserved.
 * @license      http://opensource.org/licenses/MIT, see LICENSE
 */

(function (window, document, $) {

    $.SDNodeChat = function (options) {

        var _defaults = {

            /**
             * @default     localhost
             * @type        Text
             * @value       server-IP address
             * @usage       This will be consider as default server for chat
             */
            server: "localhost",

            /**
             * @default     80
             * @type        Text
             * @value       Port number
             * @usage       This will be consider as default port for the chat server
             */
            port: "80",

            /**
             * @default     null
             * @type        [object Socket]
             * @value       [object Socket]
             * @usage       This socket object will be use to communicate to server.
             */
            socket: null,

            /**
             * @default     false
             * @type        boolean
             * @value       true/false
             * @usage       This can enable or disable log on server side.
             */
            debug: false,

            /**
             * @default     null
             * @type        Text
             * @value       username
             * @usage       This can enable or disable log on server side.
             */
            username: null,

            /**
             * @default     $('#messages')
             * @type        [object HTMLUListElement]
             * @value       [object HTMLUListElement]
             * @usage       This element will be consider as chat container
             */
            chatContainer: $('#messages'),

            /**
             * @default     $('#SendButtonID')
             * @type        [object HTMLButtonElement]
             * @value       [object HTMLButtonElement]
             * @usage       This element will be consider as an action to send chat
             */
            sendButton: $('#SendButtonID'),

            /**
             * @default     $('#chatTextBoxId')
             * @type        [object HTMLInputElement]
             * @value       [object HTMLInputElement]
             * @usage       This element will be consider as chat input it can also handle action to send chat
             */
            chatBox: $('#chatTextBox'),

            /**
             * @default     true
             * @type        boolean
             * @value       true/false
             * @usage       This can enable or disable enter key as sender on chatBox
             */
            enterToSend: true,

            /**
             * @default     $('#userContainer')
             * @type        [object HTMLUListElement]
             * @value       [object HTMLUListElement]
             * @usage       This element will be consider as a container of online users list.
             */
            usersContainer: $('#userContainer'),

            /**
             * @default     "Welcome to SD-NodeChat! For more info visit SD-NodeChat@GitHub"
             * @type        [text]
             * @value       [text]
             * @usage       This is to welcome a new user. It will be ignored if value not present.
             */
            welcomeNote: "Welcome to SD-NodeChat! For more info visit SD-NodeChat@GitHub",
        }

        // extend default vaules
        var SDNodeChatConf = $.extend(_defaults, options);

        // remove trailing slash from URL using regular expression, if there any.
        SDNodeChatConf.server = SDNodeChatConf.server.replace(/\/$/, '');

        // Regualr expression for URL
        SDNodeChatConf.pattern = {};
        SDNodeChatConf.pattern.URL = /(https|http)(:\/\/)([\w\d.-]+)(:[\d]+)?([\/\w\d._-]+)?(\?[\w\d=&-_+!@%\+]+)?(#[\w\d!=%\+]+)?/ig;
        SDNodeChatConf.pattern.URLPlaceholder = '$1$2$3$4$5$6$7';

        return {
            /**
             *
             * @param       message {text}
             * @param       type    {text} ('self'/'other')
             * @returns     void
             * @usage       This function is use to display message.
             *              There are two ways to display messages
             *              1) type = 'self'    -> message from self
             *              2) type = 'other'   -> message from other users
             *              3) type = 'note'    -> Common notes to chat
             */
            addMsg : function (message, type) {
                var li = '
' + message + '
';
                $(SDNodeChatConf.chatContainer).append($(li));
                // scroll to new content
                this.scroll();
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function will be called when user send message. This function then add message
             *              to message container and will push message to server.
             */
            sendMsg: function () {

                var message = SDNodeChatConf.chatBox.val().trim();
                if (!message) return false;

                message = this.formatLink(message);

                this.addMsg(message, 'self');
                this.pushMsg(message);

                SDNodeChatConf.chatBox.val('');
                SDNodeChatConf.chatBox.focus();
            },

            /**
             * @param       message {Text}
             * @returns     message {Text}
             * @usage       This function will identify URLs inside message body and will transform them to links.
             */
            formatLink: function (message) {
                return message.replace(SDNodeChatConf.pattern.URL, '' + SDNodeChatConf.pattern.URLPlaceholder + '');
            },

            /**
             * @param       message {Text}
             * @returns     void
             * @usage       This function will push a user message to server
             */
            pushMsg: function (message) {
                SDNodeChatConf.socket.emit('newMsg', { message: message, username: SDNodeChatConf.username });
            },

            init : function(success, fail){
                var that = this;
                var _sdnc = SDNodeChatConf;

                var hostport = [];
                hostport.push( ((_sdnc.server)?_sdnc.server:null) );
                hostport.push( ((_sdnc.server && _sdnc.port)?_sdnc.port:null) );

                // initiate socket object
                _sdnc.socket = io(hostport.join(':'));

                //ask server to add this user.
                _sdnc.socket.emit('addUser', {username: _sdnc.username});
                _sdnc.socket.on('userAdded', function(data){
                    if(data.success === true){
                        // Add welcome note
                        if(_sdnc.welcomeNote){
                            that.addMsg(_sdnc.welcomeNote,'note');
                        }

                        // listen for new user joins
                        _sdnc.socket.on('newUser', function (data) {
                            that.addMsg(data.username + ' has joined chat.', 'note');
                        });

                        // listen for user left
                        _sdnc.socket.on('userLeft', function (data) {
                            that.addMsg(data.username + ' has left.', 'note');
                        });

                        // listen for new messages over socket
                        _sdnc.socket.on('newMsg', function (data) {
                            that.addMsg(data.username + ': ' +data.message, 'other');
                        });

                        // Bind click event to sendButton
                        _sdnc.sendButton.click(function () {
                            that.sendMsg();
                        });

                        // Bind chatbox to enter press if config set to truesendMessage
                        if (_sdnc.enterToSend === true) {
                            _sdnc.chatBox.bind('keypress', function (e) {
                                // check if key is enter key
                                if (e.keyCode == 13) {
                                    that.sendMsg();
                                }
                            });
                        }

                        // Set focus to chatbox
                        _sdnc.chatBox.focus();

                        // callback
                        success();
                    }else{
                        // callback
                        fail();
                    }
                });
            },

            /**
             * @param       SDNodeChatConf key
             * @returns     SDNodeChatConf value
             * @usage       This function is to get config value.
             */
            get: function(key){
                return SDNodeChatConf[key];
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function scrolls chat container to the new added message (bottom)
             */
            scroll:function(){
                jQuery(document).scrollTop(jQuery(document).innerHeight());
            },

            /**
             * @param       void
             * @returns     string
             * @usage       This function is to query clients basic info usually a name which can be use to identify
             *              user in chat room
             */
            logMessage: function(msg,isDebug){
                // Follow global debug flag if local flag not set.
                if(typeof isDebug === 'undefined') isDebug = SDNodeChatConf.debug;
                if(isDebug) console.log(msg);
            },

            /**
             * @param       void
             * @returns     void
             * @usage       This function is use to request list of online users
             */
            getUserList: function(){
                var that = this;
                SDNodeChatConf.socket.emit('userList');
                SDNodeChatConf.socket.on('userList', function (data) {
                    that.showUserList(data);
                });
            },

            /**
             * @param       data    {object}
             * @returns     void
             * @usage       This function is use to set friends list
             */
            showUserList:function(data){
                SDNodeChatConf.usersContainer.find('li').not('.caption').remove();
                var userList = JSON.parse(data);
                var userListHTML = '';
                for(u in userList){
                    userListHTML += '
' + userList[u] + '
';
                }
                SDNodeChatConf.usersContainer.append($(userListHTML));
            }
        };
    };

}(window, document, jQuery));<|endoftext|>


<commit_before>var PrettyError = require('pretty-error');
var pe = new PrettyError();

function errorHandler(error) {

	var prettyError = pe.render(new Error(error));

	console.error('');
	console.error(prettyError);

	process.exit(1);
}

function setPrettyErrrorTheme() {
	pe.appendStyle({
		'pretty-error > header > title > kind': {
			display: 'none'
		},

		// the 'colon' after 'Error':
		'pretty-error > header > colon': {
			display: 'none'
		},

		// our error message
		'pretty-error > header > message': {
			color: 'bright-white',
			//colour range red, green, yellow, blue, magenta, cyan, white,
			background: 'red',
			padding: '0 1' // top/bottom left/right
		},

		// each trace item ...
		'pretty-error > trace > item': {
			marginLeft: 2,
			marginBottom: 0,
			bullet: '"<grey>· </grey>"'
		},

		'pretty-error > trace > item > header > pointer > file': {
			color: 'yellow'
		},

		'pretty-error > trace > item > header > pointer > colon': {
			color: 'yellow'
		},

		'pretty-error > trace > item > header > pointer > line': {
			color: 'bright-cyan'
		},

		'pretty-error > trace > item > header > what': {
			color: 'bright-white'
		},

		'pretty-error > trace > item > footer > addr': {
			// display: 'none'
			marginLeft: 4
		}
	});
}

function setPrettyErrorConfig() {
	pe.skipNodeFiles();
}

setPrettyErrrorTheme();
setPrettyErrorConfig();

module.exports = errorHandler<commit_msg>docs: error handler doc blockr<commit_after>var PrettyError = require('pretty-error');
var pe = new PrettyError();

/**
 * Main error handler function.
 * Outputs error on screen and exits program
 * @param  {Object} error Error object
 */
function errorHandler(error) {

	var prettyError = pe.render(new Error(error));

	console.error('');
	console.error(prettyError);

	process.exit(1);
}

/**
 * Set the on-screen theme for the PrettyError output
 */
function setPrettyErrrorTheme() {
	pe.appendStyle({
		'pretty-error > header > title > kind': {
			display: 'none'
		},

		// the 'colon' after 'Error':
		'pretty-error > header > colon': {
			display: 'none'
		},

		// our error message
		'pretty-error > header > message': {
			color: 'bright-white',
			//colour range red, green, yellow, blue, magenta, cyan, white,
			background: 'red',
			padding: '0 1' // top/bottom left/right
		},

		// each trace item ...
		'pretty-error > trace > item': {
			marginLeft: 2,
			marginBottom: 0,
			bullet: '"<grey>· </grey>"'
		},

		'pretty-error > trace > item > header > pointer > file': {
			color: 'yellow'
		},

		'pretty-error > trace > item > header > pointer > colon': {
			color: 'yellow'
		},

		'pretty-error > trace > item > header > pointer > line': {
			color: 'bright-cyan'
		},

		'pretty-error > trace > item > header > what': {
			color: 'bright-white'
		},

		'pretty-error > trace > item > footer > addr': {
			// display: 'none'
			marginLeft: 4
		}
	});
}

/**
 * Set PrettyError config
 */
function setPrettyErrorConfig() {
	pe.skipNodeFiles();
}

setPrettyErrrorTheme();
setPrettyErrorConfig();

module.exports = errorHandler<|endoftext|>