<commit_before>export default {
  personal: {
    name: "Hannu Pousi",
    title: "// fullstack developer",
    picture: "pics/profile-pic.jpg",
    description: "In a nushell creating great software is what makes me tick. I'm not talking about having a cup of tea and typing in the code with your favourite editor, but the whole collaborative process of crafting an initial idea into a finished software product. Buzz word complaint but not naïve."
  },
  sections: [
    {
      id: "profile",
      title: "Personal info",
      items: [
        {
          type: "text",
          label: "Full name",
          content: "Hannu Pousi"
        },
        {
          type: "text",
          label: "Born",
          content: "19 Dec 1980 - Tampere, Finland"
        },
        {
          type: "text",
          label: "Email",
          content: "pousi@iki.fi"
        },
        {
          type: "links",
          label: "Find me on",
          content: [
            {
              type: "facebook",
              url: "https://www.facebook.com/pousi"
            },
            {
              type: "twitter",
              url: "https://twitter.com/HannuPousi"
            },
            {
              type: "github",
              url: "https://github.com/dahlie/"
            },
            {
              type: "linkedin",
              url: "https://linkedin.com/in/HannuPousi"
            }
          ]
        }
      ]
    },
    {
      id: "skills",
      title: "Skills",
      items: [
        {
          type: "list",
          label: "Languages",
          content: [
            {
              label: "Finnish",
              description: "Native"
            },
            {
              label: "English",
              description: "Full professional profiency"
            }
          ]
        },
        {
          type: "list",
          label: "Programming",
          content: [
            {
              label: "Javascript/Coffeescript",
              description: "2+ years of experience developing SPAs using modern JS-frameworks like React.js, Angular.js and Knockout.js. Also familiar with JS ecosystem (npm, bower, Gulp), Node.js and ES6."
            },
            {
              label: "HTML/CSS",
              description: "Good understanding of basic concepts in both HTML and CSS (Jade, Stylus)."
            },
            {
              label: "C#",
              description: "5+ years of experience developing .NET desktop applications and back-end solutions (WPF, WCF, Asp.Net MVC3, Prism, NInject)."
            },
            {
              label: "Java",
              description: "4+ years of experience developing Java applications with Spring framework."
            },
            {
              label: "Clojure",
              description: "1+ year of experience developing back-ends for web applications (Ring, lein)."
            },
            {
              label: "Other languages",
              description: "Python, Ruby, Swift (iOS), C/C++, LUA, Scala"
            }
          ]
        },
        {
          type: "list",
          label: "Tools / methodologies",
          content: [
            {
              label: "Databases",
              description: "Many years experience with different SQL DBs and ORMs. Also familiar with MongoDB, Redis, Elastic."
            },
            {
              label: "Agile",
              description: "Scrum, Kanban. Also experienced with team coaching and training."
            },
            {
              label: "Test automation",
              description: "8+ years experience in test automation including TDD, BDD and integration testing (Protractor, Capybara, RSpec)."
            },
            {
              label: "Version control",
              description: "GIT, SVN, Mercurial."
            }
          ]
        },
        {
          type: "list",
          label: "Other skills",
          content: [
            {
              label: "Project management",
              description: "6+ years experience managing different sized projects and customers."
            },
            {
              label: "Training",
              description: "Experienced in customer and internal training."
            }
          ]
        }
      ]
    },
    {
      id: "education",
      title: "Education",
      items: [
        {
          type: "education",
          label: "Master of Science (eng.)",
          school: "Tampere University of Technology",
          graduated: "2005",
          content: "Graduated from information technology degree program with software engineering as main subject and hypermedia as subsidiary subject. Grade average and thesis grade were both very good."
        },
        {
          type: "education",
          label: "Matriculation Examination",
          school: "Jämsänkosken lukio",
          graduated: "1999",
          content: ""
        }
      ]
    },
    {
      id: "work-history",
      title: "Work history",
      items: [
        {
          type: "work",
          company: "Leonidas Oy",
          label: "Developer Extraordinare",
          from: "Aug 2013",
          to: "Present",
          content: "Worked as project lead and/or developer in multiple projects with public and private sector clients. All implemented front-ends were complex SPA applications using React.js and Angular.js. Also worked in back-end development using Clojure and Java.",
          keywords: ["React.js", "Angular.js", "SPA", "Node.js", "Clojure", "Java", "Jade", "Stylus", "SQL", "MongoDB"]
        },
        {
          type: "work",
          company: "Bitwise Oy",
          label: "Design engineer",
          from: "Feb 2008",
          to: "Jul 2013",
          content: "Worked as a project lead/manager and/or developer in multiple projects. Reponsibilities covered almost every aspect of software development from technology studies and architecture design to UX/IX design. Did also some client training and software methodology evaluations and helping putting them into daily project practices.",
          keywords: ["C#", ".Net", "WPF", "MVVM", "WCF", "Linq", "SQL", "Java"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Software architect",
          from: "Oct 2007",
          to: "Jan 2008",
          content: "Continued in the research project. Project's goals now also included evaluating new methodologies such as TDD and Scrum in daily use.",
          keywords: ["C++", "Java", "Spring", "Software architecture", "GIS", "Web services"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Design engineer",
          from: "Nov 2005",
          to: "Sep 2007",
          content: "Implementation and testing of distributed FAF ADCC system user interfaces and back-end. Also worked in a research project which studied and evaluated suitability of new techonologies and software tools. This included developing higher level architecture for the legacy system using rapid prototyping.",
          keywords: ["C++", "Java", "Spring", "Software architecture", "GIS", "Web services"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Trainee",
          from: "May 2003",
          to: "Oct 2005",
          content: "Implementation and testing of distributed FAF ADCC system user interfaces and back-end.",
          keywords: ["C++", "C"]
        }
      ]
    },
    {
      id: "interests",
      title: "Interests",
      items: [
        {
          type: "text",
          label: "Sports",
          content: "Badminton, Les Mills classes, jogging, snowboarding to name few. Excercising regularly 4 to 6 times a week is essential in trying to keep body and mind in shape."
        },
        {
          type: "text",
          label: "Food and wine",
          content: "Excercising requires good food - or the other way around. Either way I enjoy good food whether it's trying out a new local restaurant or experimenting in kitchen at home."
        },
        {
          type: "text",
          label: "Music",
          content: "When it comes to music I'm an omnivore. Good music is always good music despite of its obscure genre definitions or heavy playlist rotation. Trying ironically avoid being categorized as hipster."
        }
      ]
    }
  ]
}
<commit_msg>fix typos<commit_after>export default {
  personal: {
    name: "Hannu Pousi",
    title: "// full-stack developer",
    picture: "pics/profile-pic.jpg",
    description: "In a nutshell creating great software is what makes me tick. I'm not talking about having a cup of tea and typing in the code with your favourite editor, but the whole collaborative process of crafting an initial idea into a finished software product. Buzz word complaint but not naïve."
  },
  sections: [
    {
      id: "profile",
      title: "Personal info",
      items: [
        {
          type: "text",
          label: "Full name",
          content: "Hannu Pousi"
        },
        {
          type: "text",
          label: "Born",
          content: "19 Dec 1980 - Tampere, Finland"
        },
        {
          type: "text",
          label: "Email",
          content: "pousi@iki.fi"
        },
        {
          type: "links",
          label: "Find me on",
          content: [
            {
              type: "facebook",
              url: "https://www.facebook.com/pousi"
            },
            {
              type: "twitter",
              url: "https://twitter.com/HannuPousi"
            },
            {
              type: "github",
              url: "https://github.com/dahlie/"
            },
            {
              type: "linkedin",
              url: "https://linkedin.com/in/HannuPousi"
            }
          ]
        }
      ]
    },
    {
      id: "skills",
      title: "Skills",
      items: [
        {
          type: "list",
          label: "Languages",
          content: [
            {
              label: "Finnish",
              description: "Native"
            },
            {
              label: "English",
              description: "Full professional profiency"
            }
          ]
        },
        {
          type: "list",
          label: "Programming",
          content: [
            {
              label: "Javascript/Coffeescript",
              description: "2+ years of experience developing SPAs using modern JS-frameworks like React.js, Angular.js and Knockout.js. Also familiar with JS ecosystem (npm, bower, Gulp), Node.js and ES6."
            },
            {
              label: "HTML/CSS",
              description: "Good understanding of basic concepts in both HTML and CSS (Jade, Stylus)."
            },
            {
              label: "C#",
              description: "5+ years of experience developing .NET desktop applications and back-end solutions (WPF, WCF, Asp.Net MVC3, Prism, NInject)."
            },
            {
              label: "Java",
              description: "4+ years of experience developing Java applications with Spring framework."
            },
            {
              label: "Clojure",
              description: "1+ year of experience developing back-ends for web applications (Ring, lein)."
            },
            {
              label: "Other languages",
              description: "Python, Ruby, Swift (iOS), C/C++, LUA, Scala"
            }
          ]
        },
        {
          type: "list",
          label: "Tools / methodologies",
          content: [
            {
              label: "Databases",
              description: "Many years experience with different SQL DBs and ORMs. Also familiar with MongoDB, Redis, Elastic."
            },
            {
              label: "Agile",
              description: "Scrum, Kanban. Also experienced with team coaching and training."
            },
            {
              label: "Test automation",
              description: "8+ years experience in test automation including TDD, BDD and integration testing (Protractor, Capybara, RSpec)."
            },
            {
              label: "Version control",
              description: "GIT, SVN, Mercurial."
            }
          ]
        },
        {
          type: "list",
          label: "Other skills",
          content: [
            {
              label: "Project management",
              description: "6+ years experience managing different sized projects and customers."
            },
            {
              label: "Training",
              description: "Experienced in customer and internal training."
            }
          ]
        }
      ]
    },
    {
      id: "education",
      title: "Education",
      items: [
        {
          type: "education",
          label: "Master of Science (eng.)",
          school: "Tampere University of Technology",
          graduated: "2005",
          content: "Graduated from information technology degree program with software engineering as main subject and hypermedia as subsidiary subject. Grade average and thesis grade were both \"very good\"."
        },
        {
          type: "education",
          label: "Matriculation Examination",
          school: "Jämsänkosken lukio",
          graduated: "1999",
          content: ""
        }
      ]
    },
    {
      id: "work-history",
      title: "Work history",
      items: [
        {
          type: "work",
          company: "Leonidas Oy",
          label: "Developer Extraordinare",
          from: "Aug 2013",
          to: "Present",
          content: "Worked as project lead and/or developer in multiple projects with public and private sector clients. All implemented front-ends were complex SPA applications using React.js and Angular.js. Also worked in back-end development using Clojure and Java.",
          keywords: ["React.js", "Angular.js", "SPA", "Node.js", "Clojure", "Java", "Jade", "Stylus", "SQL", "MongoDB"]
        },
        {
          type: "work",
          company: "Bitwise Oy",
          label: "Design engineer",
          from: "Feb 2008",
          to: "Jul 2013",
          content: "Worked as a project lead/manager and/or developer in multiple projects. Responsibilities covered almost every aspect of software development from technology studies and architecture design to UX/IX design. Did also some client training and software methodology evaluations and helping putting them into daily project practices.",
          keywords: ["C#", ".Net", "WPF", "MVVM", "WCF", "Linq", "SQL", "Java"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Software architect",
          from: "Oct 2007",
          to: "Jan 2008",
          content: "Continued in the research project. Project's goals now also included evaluating new methodologies such as TDD and Scrum in daily use.",
          keywords: ["C++", "Java", "Spring", "Software architecture", "GIS", "Web services"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Design engineer",
          from: "Nov 2005",
          to: "Sep 2007",
          content: "Implementation and testing of distributed FAF ADCC system user interfaces and back-end. Also worked in a research project which studied and evaluated suitability of new technologies and software tools. This included developing higher level architecture for the legacy system using rapid prototyping.",
          keywords: ["C++", "Java", "Spring", "Software architecture", "GIS", "Web services"]
        },
        {
          type: "work",
          company: "Insta Oy",
          label: "Trainee",
          from: "May 2003",
          to: "Oct 2005",
          content: "Implementation and testing of distributed FAF ADCC system user interfaces and back-end.",
          keywords: ["C++", "C"]
        }
      ]
    },
    {
      id: "interests",
      title: "Interests",
      items: [
        {
          type: "text",
          label: "Sports",
          content: "Badminton, Les Mills classes, jogging, snowboarding to name few. Exercising regularly 4 to 6 times a week is essential in trying to keep body and mind in shape."
        },
        {
          type: "text",
          label: "Food and wine",
          content: "Exercising requires good food - or the other way around. Either way I enjoy good food whether it's trying out a new local restaurant or experimenting in kitchen at home."
        },
        {
          type: "text",
          label: "Music",
          content: "When it comes to music I'm an omnivore. Good music is always good music despite of its obscure genre definitions or heavy playlist rotation. Trying ironically avoid being categorized as hipster."
        }
      ]
    }
  ]
}
<|endoftext|>


<commit_before>(function ( window ) {
    'use strict';

    var indexedDB,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var getIndexedDB = function() {
      if ( !indexedDB ) {
        indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB || ((window.indexedDB === null && window.shimIndexedDB) ? window.shimIndexedDB : undefined);

        if ( !indexedDB ) {
          throw 'IndexedDB required';
        }
      }
      return indexedDB;
    };

    var defaultMapper = function (value) {
        return value;
    };

    var dbCache = {};

    var Server = function ( db , name ) {
        var that = this,
            closed = false;

        this.getIndexedDB = function () {
            return db;
        };

        this.add = function( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }

            var records = [];
            var counter = 0;

            var i, alm;
            var isArray = Array.isArray;
            for (i = 0, alm = arguments.length - 1; i < alm; i++) {
                var aip = arguments[i + 1];
                if (isArray(aip)) {
                    var j, alp, aipl = aip.length;
                    for (j = 0; j < aipl; j++) {
                        records[counter] = aip[j];
                        counter++;
                    }
                } else {
                    records[counter] = aip;
                    counter++;
                }
            }

            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table );

            return new Promise(function(resolve, reject){
              records.forEach( function ( record ) {
                  var req;
                  if ( record.item && record.key ) {
                      var key = record.key;
                      record = record.item;
                      req = store.add( record , key );
                  } else {
                      req = store.add( record );
                  }

                  req.onsuccess = function ( e ) {
                      var target = e.target;
                      var keyPath = target.source.keyPath;
                      if ( keyPath === null ) {
                          keyPath = '__id__';
                      }
                      Object.defineProperty( record , keyPath , {
                          value: target.result,
                          enumerable: true
                      });
                  };
              } );

              transaction.oncomplete = function () {
                  resolve( records , that );
              };
              transaction.onerror = function ( e ) {
                  // prevent Firefox from throwing a ConstraintError and aborting (hard)
                  // https://bugzilla.mozilla.org/show_bug.cgi?id=872873
                  e.preventDefault();
                  reject( e );
              };
              transaction.onabort = function ( e ) {
                  reject( e );
              };

            });
        };

        this.update = function( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }

            var records = [];
            var i;
            for ( i = 0 ; i < arguments.length - 1 ; i++ ) {
                records[ i ] = arguments[ i + 1 ];
            }

            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                keyPath = store.keyPath;

            return new Promise(function(resolve, reject){
              records.forEach( function ( record ) {
                  var req;
                  var count;
                  if ( record.item && record.key ) {
                      var key = record.key;
                      record = record.item;
                      req = store.put( record , key );
                  } else {
                      req = store.put( record );
                  }

                  req.onsuccess = function ( e ) {
                      // deferred.notify(); es6 promise can't notify
                  };
              } );

              transaction.oncomplete = function () {
                  resolve( records , that );
              };
              transaction.onerror = function ( e ) {
                  reject( e );
              };
              transaction.onabort = function ( e ) {
                  reject( e );
              };
            });

        };

        this.remove = function ( table , key ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table );

            return new Promise(function(resolve, reject){
              var req = store['delete']( key );
              transaction.oncomplete = function ( ) {
                  resolve( key );
              };
              transaction.onerror = function ( e ) {
                  reject( e );
              };
            });
        };

        this.clear = function ( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table );

            var req = store.clear();
            return new Promise(function(resolve, reject){
              transaction.oncomplete = function ( ) {
                  resolve( );
              };
              transaction.onerror = function ( e ) {
                  reject( e );
              };
            });
        };

        this.close = function ( ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[ name ];
        };

        this.get = function ( table , id ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table );

            var req = store.get( id );
            return new Promise(function(resolve, reject){
              req.onsuccess = function ( e ) {
                  resolve( e.target.result );
              };
              transaction.onerror = function ( e ) {
                  reject( e );
              };
            });
        };

        this.query = function ( table , index ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new IndexQuery( table , db , index );
        };

        this.count = function (table , key) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table );
        };

        var i, il;
        for ( i = 0 , il = db.objectStoreNames.length ; i < il ; i++ ) {
            (function ( storeName ) {
                that[ storeName ] = { };
                var i;
                for ( i in that ) {
                    if ( !hasOwn.call( that , i ) || i === 'close' ) {
                        continue;
                    }
                    that[ storeName ][ i ] = (function ( i ) {
                        return function () {
                            var args = [ storeName ].concat( [].slice.call( arguments , 0 ) );
                            return that[ i ].apply( that , args );
                        };
                    }( i ));
                }
            }( db.objectStoreNames[ i ] ));
        }
    };

    var IndexQuery = function ( table , db , indexName ) {
        var that = this;
        var modifyObj = false;

        var runQuery = function ( type, args , cursorType , direction, limitRange, filters , mapper ) {
            var transaction = db.transaction( table, modifyObj ? transactionModes.readwrite : transactionModes.readonly ),
                store = transaction.objectStore( table ),
                index = indexName ? store.index( indexName ) : store,
                keyRange = type ? IDBKeyRange[ type ].apply( null, args ) : null,
                results = [],
                indexArgs = [ keyRange ],
                counter = 0;

            limitRange = limitRange || null;
            filters = filters || [];
            if ( cursorType !== 'count' ) {
                indexArgs.push( direction || 'next' );
            }

            // create a function that will set in the modifyObj properties into
            // the passed record.
            var modifyKeys = modifyObj ? Object.keys(modifyObj) : false;
            var modifyRecord = function(record) {
                var i;
                for(i = 0; i < modifyKeys.length; i++) {
                    var key = modifyKeys[i];
                    var val = modifyObj[key];
                    if(val instanceof Function) {val = val(record);}
                    record[key] = val;
                }
                return record;
            };

            index[cursorType].apply( index , indexArgs ).onsuccess = function ( e ) {
                var cursor = e.target.result;
                if ( typeof cursor === 'number' ) {
                    results = cursor;
                } else if ( cursor ) {
                    if ( limitRange !== null && limitRange[0] > counter) {
                        counter = limitRange[0];
                        cursor.advance(limitRange[0]);
                    } else if ( limitRange !== null && counter >= (limitRange[0] + limitRange[1]) ) {
                        //out of limit range... skip
                    } else {
                        var matchFilter = true;
                        var result = 'value' in cursor ? cursor.value : cursor.key;

                        filters.forEach( function ( filter ) {
                            if ( !filter || !filter.length ) {
                                //Invalid filter do nothing
                            } else if ( filter.length === 2 ) {
                                matchFilter = matchFilter && (result[filter[0]] === filter[1]);
                            } else {
                                matchFilter = matchFilter && filter[0].apply(undefined,[result]);
                            }
                        });

                        if (matchFilter) {
                            counter++;
                            results.push( mapper(result) );
                            // if we're doing a modify, run it now
                            if(modifyObj) {
                                result = modifyRecord(result);
                                cursor.update(result);
                            }
                        }
                        cursor['continue']();
                    }
                }
            };

            return new Promise(function(resolve, reject){
              transaction.oncomplete = function () {
                  resolve( results );
              };
              transaction.onerror = function ( e ) {
                  reject( e );
              };
              transaction.onabort = function ( e ) {
                  reject( e );
              };
            });
        };

        var Query = function ( type , args ) {
            var direction = 'next',
                cursorType = 'openCursor',
                filters = [],
                limitRange = null,
                mapper = defaultMapper,
                unique = false;

            var execute = function () {
                return runQuery( type , args , cursorType , unique ? direction + 'unique' : direction, limitRange, filters , mapper );
            };

            var limit = function () {
                limitRange = Array.prototype.slice.call( arguments , 0 , 2 );
                if (limitRange.length === 1) {
                    limitRange.unshift(0);
                }

                return {
                    execute: execute
                };
            };
            var count = function () {
                direction = null;
                cursorType = 'count';

                return {
                    execute: execute
                };
            };

            var filter, desc, distinct, modify, map;
            var keys = function () {
                cursorType = 'openKeyCursor';

                return {
                    desc: desc,
                    execute: execute,
                    filter: filter,
                    distinct: distinct,
                    map: map
                };
            };
            filter = function ( ) {
                filters.push( Array.prototype.slice.call( arguments , 0 , 2 ) );

                return {
                    keys: keys,
                    execute: execute,
                    filter: filter,
                    desc: desc,
                    distinct: distinct,
                    modify: modify,
                    limit: limit,
                    map: map
                };
            };
            desc = function () {
                direction = 'prev';

                return {
                    keys: keys,
                    execute: execute,
                    filter: filter,
                    distinct: distinct,
                    modify: modify,
                    map: map
                };
            };
            distinct = function () {
                unique = true;
                return {
                    keys: keys,
                    count: count,
                    execute: execute,
                    filter: filter,
                    desc: desc,
                    modify: modify,
                    map: map
                };
            };
            modify = function(update) {
                modifyObj = update;
                return {
                    execute: execute
                };
            };
            map = function (fn) {
                mapper = fn;

                return {
                    execute: execute,
                    count: count,
                    keys: keys,
                    filter: filter,
                    desc: desc,
                    distinct: distinct,
                    modify: modify,
                    limit: limit,
                    map: map
                };
            };

            return {
                execute: execute,
                count: count,
                keys: keys,
                filter: filter,
                desc: desc,
                distinct: distinct,
                modify: modify,
                limit: limit,
                map: map
            };
        };

        ['only', 'bound', 'upperBound', 'lowerBound'].forEach(function (name) {
            that[name] = function () {
                return new Query( name , arguments );
            };
        });

        this.filter = function () {
            var query = new Query( null , null );
            return query.filter.apply( query , arguments );
        };

        this.all = function () {
            return this.filter();
        };
    };

    var createSchema = function ( e , schema , db ) {
        if ( typeof schema === 'function' ) {
            schema = schema();
        }

        var tableName;
        for ( tableName in schema ) {
            var table = schema[ tableName ];
            var store;
            if (!hasOwn.call(schema, tableName) || db.objectStoreNames.contains(tableName)) {
                store = e.currentTarget.transaction.objectStore(tableName);
            } else {
                store = db.createObjectStore(tableName, table.key);
            }

            var indexKey;
            for ( indexKey in table.indexes ) {
                var index = table.indexes[ indexKey ];
                try {
                    store.index(indexKey);
                } catch (err) {
                    store.createIndex( indexKey , index.key || indexKey , Object.keys(index).length ? index : { unique: false } );
                }
            }
        }
    };

    var open = function ( e , server , version , schema ) {
        var db = e.target.result;
        var s = new Server( db , server );
        var upgrade;

        dbCache[ server ] = db;

        return Promise.resolve(s);
    };

    var db = {
        version: '0.10.2',
        open: function ( options ) {
            var request;

            return new Promise(function(resolve, reject){
              if ( dbCache[ options.server ] ) {
                  open( {
                      target: {
                          result: dbCache[ options.server ]
                      }
                  } , options.server , options.version , options.schema )
                  .then(resolve, reject);
              } else {
                  request = getIndexedDB().open( options.server , options.version );

                  request.onsuccess = function ( e ) {
                      open( e , options.server , options.version , options.schema )
                          .then(resolve, reject);
                  };

                  request.onupgradeneeded = function ( e ) {
                      createSchema( e , options.schema , e.target.result );
                  };
                  request.onerror = function ( e ) {
                      reject( e );
                  };
              }
            });
        },
        'delete': function (dbName) {
            var request;

            return new Promise(function(resolve, reject){
                request = indexedDB.deleteDatabase( dbName );

                request.onsuccess = function () {
                    resolve();
                };
                request.onerror = function ( e ) {
                    reject( e );
                };
                request.onblocked = function ( e ) {
                    reject( e );
                };
            });
        }
    };

    if (module !== undefined && module.exports !== undefined) {
        module.exports = db;
    } else if ( typeof define === 'function' && define.amd ) {
        define( function() { return db; } );
    } else {
        window.db = db;
    }
}( window ));
<commit_msg>Reformatted the document<commit_after>(function (window) {
    'use strict';

    var indexedDB,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var getIndexedDB = function () {
        if (!indexedDB) {
            indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB || ((window.indexedDB === null && window.shimIndexedDB) ? window.shimIndexedDB : undefined);

            if (!indexedDB) {
                throw 'IndexedDB required';
            }
        }
        return indexedDB;
    };

    var defaultMapper = function (value) {
        return value;
    };

    var dbCache = {};

    var Server = function (db, name) {
        var that = this,
            closed = false;

        this.getIndexedDB = function () {
            return db;
        };

        this.add = function (table) {
            if (closed) {
                throw 'Database has been closed';
            }

            var records = [];
            var counter = 0;

            var i, alm;
            var isArray = Array.isArray;
            for (i = 0, alm = arguments.length - 1; i < alm; i++) {
                var aip = arguments[i + 1];
                if (isArray(aip)) {
                    var j, alp, aipl = aip.length;
                    for (j = 0; j < aipl; j++) {
                        records[counter] = aip[j];
                        counter++;
                    }
                } else {
                    records[counter] = aip;
                    counter++;
                }
            }

            var transaction = db.transaction(table, transactionModes.readwrite),
                store = transaction.objectStore(table);

            return new Promise(function (resolve, reject) {
                records.forEach(function (record) {
                    var req;
                    if (record.item && record.key) {
                        var key = record.key;
                        record = record.item;
                        req = store.add(record, key);
                    } else {
                        req = store.add(record);
                    }

                    req.onsuccess = function (e) {
                        var target = e.target;
                        var keyPath = target.source.keyPath;
                        if (keyPath === null) {
                            keyPath = '__id__';
                        }
                        Object.defineProperty(record, keyPath, {
                            value: target.result,
                            enumerable: true
                        });
                    };
                });

                transaction.oncomplete = function () {
                    resolve(records, that);
                };
                transaction.onerror = function (e) {
                    // prevent Firefox from throwing a ConstraintError and aborting (hard)
                    // https://bugzilla.mozilla.org/show_bug.cgi?id=872873
                    e.preventDefault();
                    reject(e);
                };
                transaction.onabort = function (e) {
                    reject(e);
                };

            });
        };

        this.update = function (table) {
            if (closed) {
                throw 'Database has been closed';
            }

            var records = [];
            var i;
            for (i = 0; i < arguments.length - 1; i++) {
                records[i] = arguments[i + 1];
            }

            var transaction = db.transaction(table, transactionModes.readwrite),
                store = transaction.objectStore(table),
                keyPath = store.keyPath;

            return new Promise(function (resolve, reject) {
                records.forEach(function (record) {
                    var req;
                    var count;
                    if (record.item && record.key) {
                        var key = record.key;
                        record = record.item;
                        req = store.put(record, key);
                    } else {
                        req = store.put(record);
                    }

                    req.onsuccess = function (e) {
                        // deferred.notify(); es6 promise can't notify
                    };
                });

                transaction.oncomplete = function () {
                    resolve(records, that);
                };
                transaction.onerror = function (e) {
                    reject(e);
                };
                transaction.onabort = function (e) {
                    reject(e);
                };
            });

        };

        this.remove = function (table, key) {
            if (closed) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction(table, transactionModes.readwrite),
                store = transaction.objectStore(table);

            return new Promise(function (resolve, reject) {
                var req = store['delete'](key);
                transaction.oncomplete = function () {
                    resolve(key);
                };
                transaction.onerror = function (e) {
                    reject(e);
                };
            });
        };

        this.clear = function (table) {
            if (closed) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction(table, transactionModes.readwrite),
                store = transaction.objectStore(table);

            var req = store.clear();
            return new Promise(function (resolve, reject) {
                transaction.oncomplete = function () {
                    resolve();
                };
                transaction.onerror = function (e) {
                    reject(e);
                };
            });
        };

        this.close = function () {
            if (closed) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[name];
        };

        this.get = function (table, id) {
            if (closed) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction(table),
                store = transaction.objectStore(table);

            var req = store.get(id);
            return new Promise(function (resolve, reject) {
                req.onsuccess = function (e) {
                    resolve(e.target.result);
                };
                transaction.onerror = function (e) {
                    reject(e);
                };
            });
        };

        this.query = function (table, index) {
            if (closed) {
                throw 'Database has been closed';
            }
            return new IndexQuery(table, db, index);
        };

        this.count = function (table, key) {
            if (closed) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction(table),
                store = transaction.objectStore(table);
        };

        var i, il;
        for (i = 0, il = db.objectStoreNames.length; i < il; i++) {
            (function (storeName) {
                that[storeName] = {};
                var i;
                for (i in that) {
                    if (!hasOwn.call(that, i) || i === 'close') {
                        continue;
                    }
                    that[storeName][i] = (function (i) {
                        return function () {
                            var args = [storeName].concat([].slice.call(arguments, 0));
                            return that[i].apply(that, args);
                        };
                    } (i));
                }
            } (db.objectStoreNames[i]));
        }
    };

    var IndexQuery = function (table, db, indexName) {
        var that = this;
        var modifyObj = false;

        var runQuery = function (type, args, cursorType, direction, limitRange, filters, mapper) {
            var transaction = db.transaction(table, modifyObj ? transactionModes.readwrite : transactionModes.readonly),
                store = transaction.objectStore(table),
                index = indexName ? store.index(indexName) : store,
                keyRange = type ? IDBKeyRange[type].apply(null, args) : null,
                results = [],
                indexArgs = [keyRange],
                counter = 0;

            limitRange = limitRange || null;
            filters = filters || [];
            if (cursorType !== 'count') {
                indexArgs.push(direction || 'next');
            }

            // create a function that will set in the modifyObj properties into
            // the passed record.
            var modifyKeys = modifyObj ? Object.keys(modifyObj) : false;
            var modifyRecord = function (record) {
                var i;
                for (i = 0; i < modifyKeys.length; i++) {
                    var key = modifyKeys[i];
                    var val = modifyObj[key];
                    if (val instanceof Function) { val = val(record); }
                    record[key] = val;
                }
                return record;
            };

            index[cursorType].apply(index, indexArgs).onsuccess = function (e) {
                var cursor = e.target.result;
                if (typeof cursor === 'number') {
                    results = cursor;
                } else if (cursor) {
                    if (limitRange !== null && limitRange[0] > counter) {
                        counter = limitRange[0];
                        cursor.advance(limitRange[0]);
                    } else if (limitRange !== null && counter >= (limitRange[0] + limitRange[1])) {
                        //out of limit range... skip
                    } else {
                        var matchFilter = true;
                        var result = 'value' in cursor ? cursor.value : cursor.key;

                        filters.forEach(function (filter) {
                            if (!filter || !filter.length) {
                                //Invalid filter do nothing
                            } else if (filter.length === 2) {
                                matchFilter = matchFilter && (result[filter[0]] === filter[1]);
                            } else {
                                matchFilter = matchFilter && filter[0].apply(undefined, [result]);
                            }
                        });

                        if (matchFilter) {
                            counter++;
                            results.push(mapper(result));
                            // if we're doing a modify, run it now
                            if (modifyObj) {
                                result = modifyRecord(result);
                                cursor.update(result);
                            }
                        }
                        cursor['continue']();
                    }
                }
            };

            return new Promise(function (resolve, reject) {
                transaction.oncomplete = function () {
                    resolve(results);
                };
                transaction.onerror = function (e) {
                    reject(e);
                };
                transaction.onabort = function (e) {
                    reject(e);
                };
            });
        };

        var Query = function (type, args) {
            var direction = 'next',
                cursorType = 'openCursor',
                filters = [],
                limitRange = null,
                mapper = defaultMapper,
                unique = false;

            var execute = function () {
                return runQuery(type, args, cursorType, unique ? direction + 'unique' : direction, limitRange, filters, mapper);
            };

            var limit = function () {
                limitRange = Array.prototype.slice.call(arguments, 0, 2);
                if (limitRange.length === 1) {
                    limitRange.unshift(0);
                }

                return {
                    execute: execute
                };
            };
            var count = function () {
                direction = null;
                cursorType = 'count';

                return {
                    execute: execute
                };
            };

            var filter, desc, distinct, modify, map;
            var keys = function () {
                cursorType = 'openKeyCursor';

                return {
                    desc: desc,
                    execute: execute,
                    filter: filter,
                    distinct: distinct,
                    map: map
                };
            };
            filter = function () {
                filters.push(Array.prototype.slice.call(arguments, 0, 2));

                return {
                    keys: keys,
                    execute: execute,
                    filter: filter,
                    desc: desc,
                    distinct: distinct,
                    modify: modify,
                    limit: limit,
                    map: map
                };
            };
            desc = function () {
                direction = 'prev';

                return {
                    keys: keys,
                    execute: execute,
                    filter: filter,
                    distinct: distinct,
                    modify: modify,
                    map: map
                };
            };
            distinct = function () {
                unique = true;
                return {
                    keys: keys,
                    count: count,
                    execute: execute,
                    filter: filter,
                    desc: desc,
                    modify: modify,
                    map: map
                };
            };
            modify = function (update) {
                modifyObj = update;
                return {
                    execute: execute
                };
            };
            map = function (fn) {
                mapper = fn;

                return {
                    execute: execute,
                    count: count,
                    keys: keys,
                    filter: filter,
                    desc: desc,
                    distinct: distinct,
                    modify: modify,
                    limit: limit,
                    map: map
                };
            };

            return {
                execute: execute,
                count: count,
                keys: keys,
                filter: filter,
                desc: desc,
                distinct: distinct,
                modify: modify,
                limit: limit,
                map: map
            };
        };

        ['only', 'bound', 'upperBound', 'lowerBound'].forEach(function (name) {
            that[name] = function () {
                return new Query(name, arguments);
            };
        });

        this.filter = function () {
            var query = new Query(null, null);
            return query.filter.apply(query, arguments);
        };

        this.all = function () {
            return this.filter();
        };
    };

    var createSchema = function (e, schema, db) {
        if (typeof schema === 'function') {
            schema = schema();
        }

        var tableName;
        for (tableName in schema) {
            var table = schema[tableName];
            var store;
            if (!hasOwn.call(schema, tableName) || db.objectStoreNames.contains(tableName)) {
                store = e.currentTarget.transaction.objectStore(tableName);
            } else {
                store = db.createObjectStore(tableName, table.key);
            }

            var indexKey;
            for (indexKey in table.indexes) {
                var index = table.indexes[indexKey];
                try {
                    store.index(indexKey);
                } catch (err) {
                    store.createIndex(indexKey, index.key || indexKey, Object.keys(index).length ? index : { unique: false });
                }
            }
        }
    };

    var open = function (e, server, version, schema) {
        var db = e.target.result;
        var s = new Server(db, server);
        var upgrade;

        dbCache[server] = db;

        return Promise.resolve(s);
    };

    var db = {
        version: '0.10.2',
        open: function (options) {
            var request;

            return new Promise(function (resolve, reject) {
                if (dbCache[options.server]) {
                    open({
                        target: {
                            result: dbCache[options.server]
                        }
                    }, options.server, options.version, options.schema)
                        .then(resolve, reject);
                } else {
                    request = getIndexedDB().open(options.server, options.version);

                    request.onsuccess = function (e) {
                        open(e, options.server, options.version, options.schema)
                            .then(resolve, reject);
                    };

                    request.onupgradeneeded = function (e) {
                        createSchema(e, options.schema, e.target.result);
                    };
                    request.onerror = function (e) {
                        reject(e);
                    };
                }
            });
        },
        'delete': function (dbName) {
            var request;

            return new Promise(function (resolve, reject) {
                request = indexedDB.deleteDatabase(dbName);

                request.onsuccess = function () {
                    resolve();
                };
                request.onerror = function (e) {
                    reject(e);
                };
                request.onblocked = function (e) {
                    reject(e);
                };
            });
        }
    };

    if (module !== undefined && module.exports !== undefined) {
        module.exports = db;
    } else if (typeof define === 'function' && define.amd) {
        define(function () { return db; });
    } else {
        window.db = db;
    }
} (window));
<|endoftext|>


<commit_before>
module.exports = {
  env: {
    // Browser global variables
    browser: true,

    // jQuery global variables
    jquery: true,

    // CommonJS global variables and CommonJS scoping.
    commonjs: true,

    // Disable node environment
    node: false,

    // Try to support ES5
    es6: false,
  },

  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module',
  },

  globals: {
    tresdb: true,
  },
};
<commit_msg>Exceptions to eslint configuration on client directory<commit_after>
module.exports = {
  env: {
    // Browser global variables
    browser: true,

    // jQuery global variables
    jquery: true,

    // CommonJS global variables and CommonJS scoping.
    commonjs: true,

    // Disable node environment
    node: false,

    // Try to support ES5
    es6: false,
  },

  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module',
  },
  rules: {
    'no-var': 'off',
    'prefer-arrow-callback': 'off',
    'prefer-const': 'off',
  },

  globals: {
    tresdb: true,
  },
};
<|endoftext|>


<commit_before>(function () {

	window.bh = {};

	window.bh.getByteArray = function (data) {
		var bytes;
		if (typeof data == 'string') {
			bytes = [];
			for (var i = 0; i < data.length; i++)
				bytes.push(data.charCodeAt(i) % 256);
		} else if (data instanceof Array) {
			for (var i = 0; i < data.length; i++)
				if (data[i] < 0 || data > 255)
					throw 'Invalid array';
			bytes = data;
		} else
			throw 'Invalid parameter type';

		return bytes;
	};

	window.bh.padding = function (bytes) {
		bytes.push(0x80);
		while (bytes.length % 64 != 56)
			bytes.push(0)
	};

	window.bh.rotateLeft = function (val, count) {
		return (val << count) | (val >>> (32 - count));
	};

	window.bh.rotateRight = function (val, count) {
		return (val << (32 - count)) | (val >>> count);
	};

	window.bh.bytesToIntLE = function (bytes, from) {
		var result = 0;
		result |= bytes[from];
		result |= bytes[from + 1] << 8;
		result |= bytes[from + 2] << 16;
		result |= bytes[from + 3] << 24;
		return result;
	};

	window.bh.intToBytesLE = function (num) {
		return [
			num & 0xff,
			(num >>> 8) & 0xff,
			(num >>> 16) & 0xff,
			(num >>> 24) & 0xff
		];
	};

	window.bh.intToBytesBE = function (num) {
		return [
			(num >>> 24) & 0xff,
			(num >>> 16) & 0xff,
			(num >>> 8) & 0xff,
			num & 0xff
		];
	};

	window.bh.byteArrayToHex = function (arr) {
		return arr.map(function (byte) {
			return byte < 16 ? '0' + byte.toString(16) : byte.toString(16);
		}).join('');
	};

	var hexChars = [];
	for (var i = 0; i < 16; i++)
		hexChars.push(i.toString(16).toUpperCase());

	window.bh.hexToByteArray = function (str) {
		if (typeof str != 'string')
			throw 'Invalid parameter';
		if (str.length % 2 == 1)
			throw 'Invalid string';

		var bytes = [];
		for (var i = 0; i < str.length / 2; i++) {
			var byteStr = str.substring(i * 2, i * 2 + 2).toUpperCase();
			if (hexChars.indexOf(byteStr.charAt(0)) == -1 || hexChars.indexOf(byteStr.charAt(1)) == -1)
				throw 'Invalid symbol';
			var byte = parseInt(byteStr, 16);
			bytes.push(byte);
		}

		return bytes;
	};

})();<commit_msg>Added zero padding<commit_after>(function () {

	window.bh = {};

	window.bh.getByteArray = function (data) {
		var bytes;
		if (typeof data == 'string') {
			bytes = [];
			for (var i = 0; i < data.length; i++)
				bytes.push(data.charCodeAt(i) % 256);
		} else if (data instanceof Array) {
			for (var i = 0; i < data.length; i++)
				if (data[i] < 0 || data > 255)
					throw 'Invalid array';
			bytes = data;
		} else
			throw 'Invalid parameter type';

		return bytes;
	};

	window.bh.padding = function (bytes) {
		bytes.push(0x80);
		while (bytes.length % 64 != 56)
			bytes.push(0)
	};

	window.bh.rotateLeft = function (val, count) {
		return (val << count) | (val >>> (32 - count));
	};

	window.bh.rotateRight = function (val, count) {
		return (val << (32 - count)) | (val >>> count);
	};

	window.bh.bytesToIntLE = function (bytes, from) {
		var result = 0;
		result |= bytes[from];
		result |= bytes[from + 1] << 8;
		result |= bytes[from + 2] << 16;
		result |= bytes[from + 3] << 24;
		return result;
	};

	window.bh.intToBytesLE = function (num) {
		return [
			num & 0xff,
			(num >>> 8) & 0xff,
			(num >>> 16) & 0xff,
			(num >>> 24) & 0xff
		];
	};

	window.bh.intToBytesBE = function (num) {
		return [
			(num >>> 24) & 0xff,
			(num >>> 16) & 0xff,
			(num >>> 8) & 0xff,
			num & 0xff
		];
	};

	window.bh.byteArrayToHex = function (arr) {
		return arr.map(function (byte) {
			return byte < 16 ? '0' + byte.toString(16) : byte.toString(16);
		}).join('');
	};

	var hexChars = [];
	for (var i = 0; i < 16; i++)
		hexChars.push(i.toString(16).toUpperCase());

	window.bh.hexToByteArray = function (str) {
		if (typeof str != 'string')
			throw 'Invalid parameter';
		if (str.length % 2 == 1)
			throw 'Invalid string';

		var bytes = [];
		for (var i = 0; i < str.length / 2; i++) {
			var byteStr = str.substring(i * 2, i * 2 + 2).toUpperCase();
			if (hexChars.indexOf(byteStr.charAt(0)) == -1 || hexChars.indexOf(byteStr.charAt(1)) == -1)
				throw 'Invalid symbol';
			var byte = parseInt(byteStr, 16);
			bytes.push(byte);
		}

		return bytes;
	};

	window.bh.stringToByteArray = function (str) {
		var array = new Array(str.length * 2);
		for (var i = 0; i < str.length; i++) {
			var code = str.charCodeAt(i);
			array[2 * i] = code & 0xff;
			array[2 * i + 1] = (code >>> 8) & 0xff;
		}
		return array;
	};

	window.bh.byteArrayToString = function (bytes) {
		var str = '';
		for (var i = 0; i < bytes.length >>> 1; i++) {
			var code = 0;
			code = code | bytes[2 * i];
			code = code | (bytes[2 * i + 1] << 8);
			str += String.fromCharCode(code);
		}
		return str;
	};

	window.bh.paddings = {};

	window.bh.paddings.zero = {
		pad: function (bytes, multiplicity) {
			while (bytes.length % multiplicity != 0)
				bytes.push(0);
		},
		unpad: function (bytes) {
			while (bytes[bytes.length - 1] == 0)
				bytes.pop();
		}
	};

})();<|endoftext|>


<commit_before>"use strict";

var WebGMEGlobal = { 'version': 'x',    //will be set from Node's package.json
    'SUPPORTS_TOUCH': 'ontouchstart' in window || navigator.msMaxTouchPoints }; //touch device detection}

// let require load all the toplevel needed script and call us on domReady
define(['logManager',
    'bin/getconfig',
    'text!package.json',
    'js/client',
    'js/Constants',
    'clientUtil',
    'js/Utils/GMEConcepts',
    'js/Utils/GMEVisualConcepts',
    'js/Utils/ExportManager',
    'js/Utils/ImportManager',
    'js/Utils/StateManager',
    'js/LayoutManager/LayoutManager',
    'js/Decorators/DecoratorManager',
    'js/KeyboardManager/KeyboardManager',
    'js/PanelManager/PanelManager',
    './WebGME.History',
    'js/Utils/METAAspectHelper',
    'js/Utils/PreferencesHelper',
    'js/ConstraintManager/ConstraintManager',
    'js/SnapInterpreter',
    'js/Utils/InterpreterManager'], function (logManager,
                                            CONFIG,
                                            packagejson,
                                            Client,
                                            CONSTANTS,
                                            util,
                                            GMEConcepts,
                                            GMEVisualConcepts,
                                            ExportManager,
                                            ImportManager,
                                            StateManager,
                                            LayoutManager,
                                            DecoratorManager,
                                            KeyboardManager,
                                            PanelManager,
                                            WebGMEHistory,
                                            METAAspectHelper,
                                            PreferencesHelper,
                                            ConstraintManager,
                                            SnapInterpreter,
                                            InterpreterManager) {

    var npmJSON = JSON.parse(packagejson);
    WebGMEGlobal.version = npmJSON.version;

    var _webGMEStart = function () {
        var lm,
            client,
            loadPanels,
            layoutToLoad = util.getURLParameterByName('layout') || 'DefaultLayout',
            commitToLoad = util.getURLParameterByName('commit').toLowerCase(),
            projectToLoad = util.getURLParameterByName('project'),
            objectToLoad = util.getURLParameterByName('obj').toLowerCase(),
            createNewProject = util.getURLParameterByName('create') === "true" ? true : false,
            logger = logManager.create('WebGME'),
            selectObject,
            loadBranch,
            branchToLoad = util.getURLParameterByName('branch') || CONFIG.branch;

        lm = new LayoutManager();
        lm.loadLayout(layoutToLoad, function () {
            var panels = [],
                layoutPanels = lm._currentLayout.panels,
                len = layoutPanels ? layoutPanels.length : 0,
                i;

            client = new Client(CONFIG);

            WebGMEGlobal.ConstraintManager = new ConstraintManager(client);

            WebGMEGlobal.InterpreterManager = new InterpreterManager(client);

            Object.defineProperty(WebGMEGlobal, 'State', {value : StateManager.initialize(),
                writable : false,
                enumerable : true,
                configurable : false});

            WebGMEHistory.initialize();

            GMEConcepts.initialize(client);
            GMEVisualConcepts.initialize(client);

            METAAspectHelper.initialize(client);
            PreferencesHelper.initialize(client);

            ExportManager.initialize(client);
            ImportManager.initialize(client);

            //hook up branch changed to set read-only mode on panels
            client.addEventListener(client.events.BRANCH_CHANGED, function (__project, branchName) {
                lm.setPanelReadOnly(client.isCommitReadOnly() || client.isProjectReadOnly());
            });
            client.addEventListener(client.events.PROJECT_OPENED, function (__project, projectName) {
                lm.setPanelReadOnly(client.isProjectReadOnly());
            });

            //on project close clear the current state
            client.addEventListener(client.events.PROJECT_CLOSED, function (__project, projectName) {
                WebGMEGlobal.State.clear();
            });

            client.decoratorManager = new DecoratorManager();

            for (i = 0; i < len; i += 1) {
                panels.push({'panel': layoutPanels[i].panel,
                    'container': layoutPanels[i].container,
                    'control': layoutPanels[i].control,
                    'params' : {'client': client}});
            }

            //load the panels
            loadPanels(panels);

            //as of now it's a global variable just to make access to it easier
            //TODO: might need to be changed
            WebGMEGlobal.KeyboardManager = KeyboardManager;
            WebGMEGlobal.KeyboardManager.setEnabled(true);
            WebGMEGlobal.PanelManager = new PanelManager();
        });

        loadPanels = function (panels) {
            var p = panels.splice(0, 1)[0];

            lm.loadPanel(p, function () {
                if (panels.length > 0) {
                    loadPanels(panels);
                } else {
                    new SnapInterpreter(client);
                    if(createNewProject && projectToLoad !== ""){
                        client.connectToDatabaseAsync({},function(err){
                            if(err){
                                logger.error(err);
                            } else {
                                client.getAvailableProjectsAsync(function(err,projectArray){
                                    if(err){
                                        logger.error(err);
                                    } else {
                                        if(projectArray.indexOf(projectToLoad) !== -1){
                                            //we fallback to loading
                                            client.selectProjectAsync(projectToLoad,function(err){
                                                if(err){
                                                    logger.error(err);
                                                } else {
                                                    if (branchToLoad && branchToLoad !== '') {
                                                        loadBranch(branchToLoad);
                                                    } else  if (commitToLoad && commitToLoad !== "") {
                                                        client.selectCommitAsync(commitToLoad, function (err) {
                                                            if (err) {
                                                                logger.error(err);
                                                            } else {
                                                                selectObject();
                                                            }
                                                        });
                                                    } else {
                                                        selectObject();
                                                    }
                                                }
                                            });
                                        } else {
                                            //we create the project
                                            client.createProjectAsync(projectToLoad,function(err){
                                                if(err){
                                                    logger.error(err);
                                                } else {
                                                    client.selectProjectAsync(projectToLoad,function(err) {
                                                        if (err) {
                                                            logger.error(err);
                                                        } else {
                                                            GMEConcepts.createBasicProjectSeed();
                                                        }
                                                        //otherwise we are pretty much done cause we ignore the other parameters
                                                    });
                                                }
                                            });
                                        }
                                    }
                                });
                            }
                        });
                    } else {
                        projectToLoad = projectToLoad === "" ? CONFIG.project : projectToLoad;
                        client.connectToDatabaseAsync({'open': projectToLoad,
                            'project': projectToLoad}, function (err) {
                            if (err) {
                                logger.error(err);
                            } else {
                                if (branchToLoad && branchToLoad !== '') {
                                    loadBranch(branchToLoad);
                                } else  if (commitToLoad && commitToLoad !== "") {
                                    client.selectCommitAsync(commitToLoad, function (err) {
                                        if (err) {
                                            logger.error(err);
                                        } else {
                                            selectObject();
                                        }
                                    });
                                } else {
                                    selectObject();
                                }
                            }
                        });
                    }
                }
            });
        };

        selectObject = function () {
            if (objectToLoad && objectToLoad !== "") {
                if (objectToLoad.toLowerCase() === 'root') {
                    objectToLoad = CONSTANTS.PROJECT_ROOT_ID;
                }
                setTimeout(function () {
                    WebGMEGlobal.State.setActiveObject(objectToLoad);
                }, 1000);
            }
        };

        loadBranch = function (branchName) {
            client.selectBranchAsync(branchName, function (err) {
                if (err) {
                    logger.error(err);
                }
            });
        };
    };

    return {
        start : _webGMEStart
    };
});
<commit_msg>Removed old interpreter button<commit_after>"use strict";

var WebGMEGlobal = { 'version': 'x',    //will be set from Node's package.json
    'SUPPORTS_TOUCH': 'ontouchstart' in window || navigator.msMaxTouchPoints }; //touch device detection}

// let require load all the toplevel needed script and call us on domReady
define(['logManager',
    'bin/getconfig',
    'text!package.json',
    'js/client',
    'js/Constants',
    'clientUtil',
    'js/Utils/GMEConcepts',
    'js/Utils/GMEVisualConcepts',
    'js/Utils/ExportManager',
    'js/Utils/ImportManager',
    'js/Utils/StateManager',
    'js/LayoutManager/LayoutManager',
    'js/Decorators/DecoratorManager',
    'js/KeyboardManager/KeyboardManager',
    'js/PanelManager/PanelManager',
    './WebGME.History',
    'js/Utils/METAAspectHelper',
    'js/Utils/PreferencesHelper',
    'js/ConstraintManager/ConstraintManager',
    'js/Utils/InterpreterManager'], function (logManager,
                                            CONFIG,
                                            packagejson,
                                            Client,
                                            CONSTANTS,
                                            util,
                                            GMEConcepts,
                                            GMEVisualConcepts,
                                            ExportManager,
                                            ImportManager,
                                            StateManager,
                                            LayoutManager,
                                            DecoratorManager,
                                            KeyboardManager,
                                            PanelManager,
                                            WebGMEHistory,
                                            METAAspectHelper,
                                            PreferencesHelper,
                                            ConstraintManager,
                                            InterpreterManager) {

    var npmJSON = JSON.parse(packagejson);
    WebGMEGlobal.version = npmJSON.version;

    var _webGMEStart = function () {
        var lm,
            client,
            loadPanels,
            layoutToLoad = util.getURLParameterByName('layout') || 'DefaultLayout',
            commitToLoad = util.getURLParameterByName('commit').toLowerCase(),
            projectToLoad = util.getURLParameterByName('project'),
            objectToLoad = util.getURLParameterByName('obj').toLowerCase(),
            createNewProject = util.getURLParameterByName('create') === "true" ? true : false,
            logger = logManager.create('WebGME'),
            selectObject,
            loadBranch,
            branchToLoad = util.getURLParameterByName('branch') || CONFIG.branch;

        lm = new LayoutManager();
        lm.loadLayout(layoutToLoad, function () {
            var panels = [],
                layoutPanels = lm._currentLayout.panels,
                len = layoutPanels ? layoutPanels.length : 0,
                i;

            client = new Client(CONFIG);

            WebGMEGlobal.ConstraintManager = new ConstraintManager(client);

            WebGMEGlobal.InterpreterManager = new InterpreterManager(client);

            Object.defineProperty(WebGMEGlobal, 'State', {value : StateManager.initialize(),
                writable : false,
                enumerable : true,
                configurable : false});

            WebGMEHistory.initialize();

            GMEConcepts.initialize(client);
            GMEVisualConcepts.initialize(client);

            METAAspectHelper.initialize(client);
            PreferencesHelper.initialize(client);

            ExportManager.initialize(client);
            ImportManager.initialize(client);

            //hook up branch changed to set read-only mode on panels
            client.addEventListener(client.events.BRANCH_CHANGED, function (__project, branchName) {
                lm.setPanelReadOnly(client.isCommitReadOnly() || client.isProjectReadOnly());
            });
            client.addEventListener(client.events.PROJECT_OPENED, function (__project, projectName) {
                lm.setPanelReadOnly(client.isProjectReadOnly());
            });

            //on project close clear the current state
            client.addEventListener(client.events.PROJECT_CLOSED, function (__project, projectName) {
                WebGMEGlobal.State.clear();
            });

            client.decoratorManager = new DecoratorManager();

            for (i = 0; i < len; i += 1) {
                panels.push({'panel': layoutPanels[i].panel,
                    'container': layoutPanels[i].container,
                    'control': layoutPanels[i].control,
                    'params' : {'client': client}});
            }

            //load the panels
            loadPanels(panels);

            //as of now it's a global variable just to make access to it easier
            //TODO: might need to be changed
            WebGMEGlobal.KeyboardManager = KeyboardManager;
            WebGMEGlobal.KeyboardManager.setEnabled(true);
            WebGMEGlobal.PanelManager = new PanelManager();
        });

        loadPanels = function (panels) {
            var p = panels.splice(0, 1)[0];

            lm.loadPanel(p, function () {
                if (panels.length > 0) {
                    loadPanels(panels);
                } else {
                    if(createNewProject && projectToLoad !== ""){
                        client.connectToDatabaseAsync({},function(err){
                            if(err){
                                logger.error(err);
                            } else {
                                client.getAvailableProjectsAsync(function(err,projectArray){
                                    if(err){
                                        logger.error(err);
                                    } else {
                                        if(projectArray.indexOf(projectToLoad) !== -1){
                                            //we fallback to loading
                                            client.selectProjectAsync(projectToLoad,function(err){
                                                if(err){
                                                    logger.error(err);
                                                } else {
                                                    if (branchToLoad && branchToLoad !== '') {
                                                        loadBranch(branchToLoad);
                                                    } else  if (commitToLoad && commitToLoad !== "") {
                                                        client.selectCommitAsync(commitToLoad, function (err) {
                                                            if (err) {
                                                                logger.error(err);
                                                            } else {
                                                                selectObject();
                                                            }
                                                        });
                                                    } else {
                                                        selectObject();
                                                    }
                                                }
                                            });
                                        } else {
                                            //we create the project
                                            client.createProjectAsync(projectToLoad,function(err){
                                                if(err){
                                                    logger.error(err);
                                                } else {
                                                    client.selectProjectAsync(projectToLoad,function(err) {
                                                        if (err) {
                                                            logger.error(err);
                                                        } else {
                                                            GMEConcepts.createBasicProjectSeed();
                                                        }
                                                        //otherwise we are pretty much done cause we ignore the other parameters
                                                    });
                                                }
                                            });
                                        }
                                    }
                                });
                            }
                        });
                    } else {
                        projectToLoad = projectToLoad === "" ? CONFIG.project : projectToLoad;
                        client.connectToDatabaseAsync({'open': projectToLoad,
                            'project': projectToLoad}, function (err) {
                            if (err) {
                                logger.error(err);
                            } else {
                                if (branchToLoad && branchToLoad !== '') {
                                    loadBranch(branchToLoad);
                                } else  if (commitToLoad && commitToLoad !== "") {
                                    client.selectCommitAsync(commitToLoad, function (err) {
                                        if (err) {
                                            logger.error(err);
                                        } else {
                                            selectObject();
                                        }
                                    });
                                } else {
                                    selectObject();
                                }
                            }
                        });
                    }
                }
            });
        };

        selectObject = function () {
            if (objectToLoad && objectToLoad !== "") {
                if (objectToLoad.toLowerCase() === 'root') {
                    objectToLoad = CONSTANTS.PROJECT_ROOT_ID;
                }
                setTimeout(function () {
                    WebGMEGlobal.State.setActiveObject(objectToLoad);
                }, 1000);
            }
        };

        loadBranch = function (branchName) {
            client.selectBranchAsync(branchName, function (err) {
                if (err) {
                    logger.error(err);
                }
            });
        };
    };

    return {
        start : _webGMEStart
    };
});
<|endoftext|>


<commit_before>var pull = require('../')
var path = require('path')
var fs   = require('fs')
var test = require('tape')

var start = path.resolve(__dirname, '..')

function ls_r (start, type) {
  type = type || pull.depthFirst
  return type(start, function (dir) {
    var def = pull.defer()
    fs.readdir(dir, function (err, ls) {
      if(err)
        return def.abort(err.code === 'ENOTDIR' ? true : err)

      def.resolve(
        pull.values(ls || [])
        .pipe(pull.map(function (file) {
          return path.resolve(dir, file)
        }))
      )
    })

    return def
  })
}

test('widthFirst', function (t) {
  var max = 0
  ls_r(start, pull.widthFirst)
    .pipe(pull.map(function (file) {
      return file.split('/').length
    }))
    .pipe(pull.filter(function (d) {
      t.ok(d >= max)
      if(d > max)
        return max = d, true
    }))
    .pipe(pull.through(console.log))
    .pipe(pull.onEnd(function () {
       t.end()
    }))
})

test('depthFirst', function (t) {
  var seen = {}
  seen[start] = true
  //assert that for each item,
  //you have seen the dir already
  ls_r(start, pull.depthFirst)
    .pipe(pull.through(function (file) {
      var dir = path.dirname(file)
      t.ok(seen[dir])
      seen[file] = true
    }))
    .pipe(pull.onEnd(function () {
      t.end()
    }))

})

test('leafFirst', function (t) {
  var seen = {}
  var expected = {}
  //  expected[start] = true
  //assert that for each item,
  //you have seen the dir already
  ls_r(start, pull.leafFirst)
    .pipe(pull.through(function (file) {
      var dir = path.dirname(file)
      t.ok(!seen[dir])
      expected[dir] = true
      if(expected[file])
        delete expected[file]
    }))
    .pipe(pull.onEnd(function () {
      delete expected[start]
      for(var k in expected)
        t.ok(false, k)
      t.end()
    }))

})

<commit_msg>update tests to include current directory<commit_after>var pull = require('../')
var path = require('path')
var fs   = require('fs')
var test = require('tape')

var start = path.resolve(__dirname, '..')

function ls_r (start, type) {
  type = type || pull.depthFirst
  return type(start, function (dir) {
    var def = pull.defer()
    fs.readdir(dir, function (err, ls) {
      if(err)
        return def.abort(err.code === 'ENOTDIR' ? true : err)

      def.resolve(
        pull.values(ls || [])
        .pipe(pull.map(function (file) {
          return path.resolve(dir, file)
        }))
      )
    })

    return def
  })
}

test('widthFirst', function (t) {
  var max = 0, didStart

  ls_r(start, pull.widthFirst)
    .pipe(pull.map(function (file) {
      if(file === start) didStart = true
      return file.split('/').length
    }))
    .pipe(pull.filter(function (d) {
      t.ok(d >= max)
      if(d > max)
        return max = d, true
    }))
    .pipe(pull.through(console.log))
    .pipe(pull.drain(null, function () {
      t.ok(didStart)
      t.end()
    }))
})

test('depthFirst', function (t) {
  var seen = {}
  //assert that for each item,
  //you have seen the dir already
  ls_r(start, pull.depthFirst)
    .pipe(pull.through(function (file) {
      if(file != start) {
        var dir = path.dirname(file)
        t.ok(seen[dir])
      }
      //console.log(dir)
      seen[file] = true
    }))
    .pipe(pull.onEnd(function () {
      t.end()
    }))

})

test('leafFirst', function (t) {
  var seen = {}
  var expected = {}
    expected[start] = true
  //assert that for each item,
  //you have seen the dir already
  ls_r(start, pull.leafFirst)
    .pipe(pull.through(function (file) {
      if(file !== start) {
        var dir = path.dirname(file)
        t.ok(!seen[dir])
        expected[dir] = true
      }
      if(expected[file])
        delete expected[file]
    }))
    .pipe(pull.drain(null, function () {
      for(var k in expected)
        t.ok(false, k)
      t.end()
    }))

})

<|endoftext|>


<commit_before>var $ = require('jquery'),
	store = require('store'),
	EventEmitter = require('events').EventEmitter;

var Comments = require('./comments'),
	Crates = require('./crates');

var $cratedigger,
	$rightColumn,
	$pageNumber,
	$about,
	$bottomBar,
	$buttonPrev,
	$buttonShow,
	$buttonNext,
	$buttonPrevPage,
	$buttonNextPage,
	$buttonListen,
	$trackArtist,
    $trackTitle,
    $trackYear,
    $trackLabel,
    $trackDescription,
    $trackLinks,
    $buttonPrevTrack,
    $buttonNextTrack,
    $buttonAutoplay,
    $buttonTrackPanelToggle,

    curentTrackId,
    pagesCount,
    autoplay = store.get('autoplay') === undefined ? true : store.get('autoplay'),

    emitter = new EventEmitter();

function init() {

	$cratedigger = $('#cratedigger');
	$rightColumn = $('.right-column');
	$pageNumber = $('.page-number');

	$about = $('.about');

	$bottomBar  = $('#bottom-bar');
	$buttonPrev = $bottomBar.find('.bottom-bar-prev-button');
	$buttonShow = $bottomBar.find('.bottom-bar-mid-button');
	$buttonNext = $bottomBar.find('.bottom-bar-next-button');

	$buttonPrevPage = $('.button-prev-page');
	$buttonNextPage = $('.button-next-page');

	$buttonListen = $( '#cratedigger-record-listen' );

	$trackArtist = $( '.track .track-artist' );
    $trackTitle = $( '.track .track-title' );
    $trackYear = $( '.track .track-year' );
    $trackLabel = $( '.track .track-label' );
    $trackDescription = $( '.track .track-description' );
    $trackLinks = $( '.track .track-links' );

	$buttonPrevTrack = $( '.button-prev-track' );
    $buttonNextTrack = $( '.button-next-track' );

    $buttonAutoplay = $( '.button-autoplay' );
	$buttonTrackPanelToggle = $( '.track-panel-toggle-button' );

	$buttonPrev.on('click', Crates.selectPrevRecord);
	$buttonShow.on('click', Crates.showRecord);
	$buttonNext.on('click', Crates.selectNextRecord);

	$buttonListen.on('click', onButtonListenClick);
	$buttonPrevPage.on('click', onButtonPrevPageClick);
	$buttonNextPage.on('click', onButtonNextPageClick);
	$buttonPrevTrack.on('click', onButtonPrevTrackClick);
	$buttonNextTrack.on('click', onButtonNextTrackClick);
	$buttonAutoplay.on('click', onButtonAutoplayClick);

	$buttonTrackPanelToggle.on('click', onButtonTrackPanelToggleClick);

	pagesCount = getPagesCount();

	updateAutoplay();

}

function updateTrackView(dig) {

	if ( curentTrackId !== dig._id ) {

		hideAbout();
		showTrackPanel();

		var trackArtists = dig.artists.join( ', ' );
		var trackFullTitle = trackArtists + ' - ' + dig.title;

		curentTrackId = dig._id;

		$trackArtist.text( trackArtists );
		$trackTitle.text( dig.title );
		$trackYear.text( dig.year );
		$trackLabel.text( dig.label || '' );
		$trackDescription.text( dig.description || '' );

		$trackLinks.empty();

		for ( var link in dig.links ) {

        	if ( dig.links.hasOwnProperty( link ) ) {

        		$trackLinks.append('' + link + '');

        	}
        }

		Comments.loadCommentsForTrack( dig, trackFullTitle );

	}
}

function hideBottomBar() {

	$bottomBar.addClass('closed');

}

function showBottomBar() {

	$bottomBar.removeClass('closed');

}

function onButtonPrevPageClick() {

	emitter.emit('page:prev');
	return false;

}

function onButtonNextPageClick() {

	emitter.emit('page:next');
	return false;

}

function onButtonListenClick() {

	emitter.emit('dig:listen');
	return false;

}

function onButtonPrevTrackClick() {

	emitter.emit('track:prev');
	return false;

}

function onButtonNextTrackClick() {

	emitter.emit('track:next');
	return false;

}

function onButtonAutoplayClick() {

	autoplay = !autoplay;
	store.set('autoplay', autoplay);
	updateAutoplay();
	return false;

}

function onButtonTrackPanelToggleClick() {
	$rightColumn.toggleClass('hidden');
}

function hideTrackPanel() {
	$rightColumn.addClass('hidden');
}

function showTrackPanel() {
	$rightColumn.removeClass('hidden');
}

function updateAutoplay() {

	$buttonAutoplay.text( 'Autoplay ' + (autoplay ? 'On' : 'Off') );

}

function onPageChange(pageId) {

	$cratedigger.attr('data-cratedigger-page', pageId);
	$pageNumber.text(pageId);

	$buttonPrevPage.show();
	$buttonNextPage.show();

	if ( pageId === 1 ) {

		$buttonPrevPage.hide();

	}

	if ( pageId === pagesCount ) {

		$buttonNextPage.hide();

	}
}

function updateTitle( dig, page ) {

	var title = 'Digging Into Hip Hop';

	if ( dig ) {

		title = dig.artist + ' - ' + dig.title + ' | ' + title;

	}

	if ( page && page > 1 ) {

		title = title + ' -¨Page ' + page;

	}

	document.title = title;

}

function hideAbout() {

	$about.addClass('hidden');

}

function showAbout() {

	$about.removeClass('hidden');

}

function getCurrentPageId() {
	return parseInt($cratedigger.attr('data-cratedigger-page'));
}

function getPagesCount() {
	return parseInt($cratedigger.attr('data-cratedigger-pages-count'));
}

function getCurrentDigId() {
	return $cratedigger.attr('data-cratedigger-record') || null;
}

function getAutoplay() {
	return autoplay;
}

module.exports =  {
    init: init,
    updateTrackView: updateTrackView,
    hideBottomBar: hideBottomBar,
	showBottomBar: showBottomBar,
	onPageChange: onPageChange,
	updateTitle: updateTitle,
	hideAbout: hideAbout,
	showAbout: showAbout,
	hideTrackPanel: hideTrackPanel,
	showTrackPanel: showTrackPanel,
	getCurrentPageId: getCurrentPageId,
	getPagesCount: getPagesCount,
	getCurrentDigId: getCurrentDigId,
	getAutoplay: getAutoplay,
	on: emitter.on.bind(emitter)
};
<commit_msg>Hide track panel on scene focus<commit_after>var $ = require('jquery'),
	store = require('store'),
	EventEmitter = require('events').EventEmitter;

var Comments = require('./comments'),
	Crates = require('./crates');

var $cratedigger,
	$rightColumn,
	$pageNumber,
	$about,
	$bottomBar,
	$buttonPrev,
	$buttonShow,
	$buttonNext,
	$buttonPrevPage,
	$buttonNextPage,
	$buttonListen,
	$trackArtist,
    $trackTitle,
    $trackYear,
    $trackLabel,
    $trackDescription,
    $trackLinks,
    $buttonPrevTrack,
    $buttonNextTrack,
    $buttonAutoplay,
    $buttonTrackPanelToggle,

    curentTrackId,
    pagesCount,
    autoplay = store.get('autoplay') === undefined ? true : store.get('autoplay'),

    emitter = new EventEmitter();

function init() {

	$cratedigger = $('#cratedigger');
	$rightColumn = $('.right-column');
	$pageNumber = $('.page-number');

	$about = $('.about');

	$bottomBar  = $('#bottom-bar');
	$buttonPrev = $bottomBar.find('.bottom-bar-prev-button');
	$buttonShow = $bottomBar.find('.bottom-bar-mid-button');
	$buttonNext = $bottomBar.find('.bottom-bar-next-button');

	$buttonPrevPage = $('.button-prev-page');
	$buttonNextPage = $('.button-next-page');

	$buttonListen = $( '#cratedigger-record-listen' );

	$trackArtist = $( '.track .track-artist' );
    $trackTitle = $( '.track .track-title' );
    $trackYear = $( '.track .track-year' );
    $trackLabel = $( '.track .track-label' );
    $trackDescription = $( '.track .track-description' );
    $trackLinks = $( '.track .track-links' );

	$buttonPrevTrack = $( '.button-prev-track' );
    $buttonNextTrack = $( '.button-next-track' );

    $buttonAutoplay = $( '.button-autoplay' );
	$buttonTrackPanelToggle = $( '.track-panel-toggle-button' );

	$cratedigger.on('click', onCratediggerClick);

	$buttonPrev.on('click', onButtonPrevClick);
	$buttonShow.on('click', onButtonShowClick);
	$buttonNext.on('click', onButtonNextClick);

	$buttonListen.on('click', onButtonListenClick);
	$buttonPrevPage.on('click', onButtonPrevPageClick);
	$buttonNextPage.on('click', onButtonNextPageClick);
	$buttonPrevTrack.on('click', onButtonPrevTrackClick);
	$buttonNextTrack.on('click', onButtonNextTrackClick);
	$buttonAutoplay.on('click', onButtonAutoplayClick);

	$buttonTrackPanelToggle.on('click', onButtonTrackPanelToggleClick);

	pagesCount = getPagesCount();

	updateAutoplay();

}

function updateTrackView(dig) {

	if ( curentTrackId !== dig._id ) {

		hideAbout();
		showTrackPanel();

		var trackArtists = dig.artists.join( ', ' );
		var trackFullTitle = trackArtists + ' - ' + dig.title;

		curentTrackId = dig._id;

		$trackArtist.text( trackArtists );
		$trackTitle.text( dig.title );
		$trackYear.text( dig.year );
		$trackLabel.text( dig.label || '' );
		$trackDescription.text( dig.description || '' );

		$trackLinks.empty();

		for ( var link in dig.links ) {

        	if ( dig.links.hasOwnProperty( link ) ) {

        		$trackLinks.append('' + link + '');

        	}
        }

		Comments.loadCommentsForTrack( dig, trackFullTitle );

	}
}

function hideBottomBar() {

	$bottomBar.addClass('closed');

}

function showBottomBar() {

	$bottomBar.removeClass('closed');

}

function onCratediggerClick() {

	hideTrackPanel();

}

function onButtonPrevPageClick() {

	hideTrackPanel();
	emitter.emit('page:prev');
	return false;

}

function onButtonNextPageClick() {

	hideTrackPanel();
	emitter.emit('page:next');
	return false;

}

function onButtonListenClick() {

	hideTrackPanel();
	emitter.emit('dig:listen');
	return false;

}

function onButtonPrevTrackClick() {

	emitter.emit('track:prev');
	return false;

}

function onButtonNextTrackClick() {

	emitter.emit('track:next');
	return false;

}

function onButtonAutoplayClick() {

	autoplay = !autoplay;
	store.set('autoplay', autoplay);
	updateAutoplay();
	return false;

}

function onButtonTrackPanelToggleClick() {
	$rightColumn.toggleClass('hidden');
}

function onButtonPrevClick() {

	hideTrackPanel();
	Crates.selectPrevRecord();
	return false;
}

function onButtonShowClick() {

	hideTrackPanel();
	Crates.showRecord();
	return false;
}

function onButtonNextClick() {

	hideTrackPanel();
	Crates.selectNextRecord();
	return false;
}

function hideTrackPanel() {
	$rightColumn.addClass('hidden');
}

function showTrackPanel() {
	$rightColumn.removeClass('hidden');
}

function updateAutoplay() {

	$buttonAutoplay.text( 'Autoplay ' + (autoplay ? 'On' : 'Off') );

}

function onPageChange(pageId) {

	$cratedigger.attr('data-cratedigger-page', pageId);
	$pageNumber.text(pageId);

	$buttonPrevPage.show();
	$buttonNextPage.show();

	if ( pageId === 1 ) {

		$buttonPrevPage.hide();

	}

	if ( pageId === pagesCount ) {

		$buttonNextPage.hide();

	}
}

function updateTitle( dig, page ) {

	var title = 'Digging Into Hip Hop';

	if ( dig ) {

		title = dig.artist + ' - ' + dig.title + ' | ' + title;

	}

	if ( page && page > 1 ) {

		title = title + ' -¨Page ' + page;

	}

	document.title = title;

}

function hideAbout() {

	$about.addClass('hidden');

}

function showAbout() {

	$about.removeClass('hidden');

}

function getCurrentPageId() {
	return parseInt($cratedigger.attr('data-cratedigger-page'));
}

function getPagesCount() {
	return parseInt($cratedigger.attr('data-cratedigger-pages-count'));
}

function getCurrentDigId() {
	return $cratedigger.attr('data-cratedigger-record') || null;
}

function getAutoplay() {
	return autoplay;
}

module.exports =  {
    init: init,
    updateTrackView: updateTrackView,
    hideBottomBar: hideBottomBar,
	showBottomBar: showBottomBar,
	onPageChange: onPageChange,
	updateTitle: updateTitle,
	hideAbout: hideAbout,
	showAbout: showAbout,
	hideTrackPanel: hideTrackPanel,
	showTrackPanel: showTrackPanel,
	getCurrentPageId: getCurrentPageId,
	getPagesCount: getPagesCount,
	getCurrentDigId: getCurrentDigId,
	getAutoplay: getAutoplay,
	on: emitter.on.bind(emitter)
};
<|endoftext|>