<commit_before>(function() {
    $(document).ready(function() {
        /*
         * Loads the list of Downloaded files that are on the server
         */
        var loadFiles = function() {
            $.ajax({
                url: '/files',
                type: 'get',
                cache: false,
                dataType: 'json'
            }).done(function(data){
                $('#rss_files tbody').empty();
                // Sort files by Filename
                data.sort(function(a, b) {
                    a = a.filename.toLowerCase();
                    b = b.filename.toLowerCase();
                    return a > b ? 1 : a < b ? -1 : 0;
                });
                var tr, td = [], a, icon, del, s, i;
                for(i in data) {
                    $('#rss_files tbody').append(fileRow(data[i]));
                }
            }).fail(function(){

            });
        };
        /*
         * Loads List of TV-Shows direct from monitored RSS
         *
         */
        var loadRssTV = function(type) {
            var div, rssTV = document.getElementById('rss_TV');
            $.ajax({
                url: '/tv',
                type: 'get',
                dataType: 'json',
                cache: false
            }).done(function(data) {
                for(var i in data) {
                    rssTV.appendChild(siteRow(data[i]));
                }
            }).fail(function(data) {
                msg.set('Error loading TV-Shows');
            });
        };
        /*
         * Loads list of Movies as Thumbnails from db
         *
         */
        var loadRssMovies = function() {
            $.ajax({
                url: '/movies',
                type: 'get',
                dataType: 'json',
                cache: false,
            }).done(function(json) {
                var div, i;
                json.sort(function(a, b) {
                    a = new Date(a.lastUpdate);
                    b = new Date(b.lastUpdate);
                    return a > b ? -1 : a < b ? 1 : 0;
                });
                // Start creating Movie-Thumbs
                var li;
                for(i = 0; i < json.length; i++) {
                    div = thumbPosterWithInfoClickable(json[i]);
                    li = document.createElement('li');
                    li.className = 'col-lg-1 col-md-2 col-sm-3 col-xs-4';
                    li.appendChild(div);
                    //div.style.float = 'left';
                    $('#rss_Movies').append(li);
                }
            }).fail(function(data) {
                msg.set('Error while loading movies');
            });
        };
        loadRssTV();
        loadRssMovies();
        loadFiles();
        /*
         * Creates a siteRow which can be parsed
         *
         * @param site  {object} {title, pubdate, link, description}
         *
         *
         */
        var siteRow = function(sites) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            if(sites.title !== undefined) {
                var domain = sites.link.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
                var date = new Date(sites.pubdate);
                div.innerHTML = sites.title + ' (' + date.easy() + ' @' + domain[1] + ')';
                sites = [sites];
            } else {
                div.textContent = '>- rip All Sites -<';
            }
            div.onclick = (function(sites) {
                return function() {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: sites
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                };
            })(sites);
            return div;
        };
        /*
         * Process returned online links
         */
        var processLinks = function(data) {
            /* structure of data; example
                [
                  {
                    "status": "0",
                    "filename": "Sm.2013.720p-iFT",
                    "extension": "mkv",
                    "size": "4920000000",
                    "link": "http://ul.to/08otd5be"
                  }
                  { etc. }
                ]
            */
            msg.set('found ' + data.length + ' links.')
            makeTableChecked(data);
            // Add links to textarea for exporting
            $('#paste').html(data.map(function(elem) {
                return elem.link;
            }).join(' '));
            $('.nav-tabs a[href="#tabLinks"]').tab('show');
        };

        /*
         * One Row of FileExplorer
         */
        var fileRow = function(file) {
            var tr = document.createElement('tr');
            var td = [];
            for(s = 0; s < 4; s++) {
                td.push(document.createElement('td'));
            }
            var a = null,
                icon = null,
                del = null,
                s = 0,
                i = 0;
            // Filename Link
            a = document.createElement('a');
            a.href = 'files/' + file.link;
            a.textContent = file.filename;
            td[0].appendChild(a);
            td[1].textContent = bytesToSize(file.size);
            // Filetype Icon
            icon = document.createElement('div');
            icon.className = 'icon icon' + file.extension;
            icon.title = file.extension;
            td[2].appendChild(icon);
            // DELETE Link
            del = document.createElement('div');
            del.className = 'a';
            del.onclick = function() {
                $.ajax({
                    url: 'files/' + file.link + '/delete',
                    type: 'DELETE',
                    dataType: 'json'
                }).done(function(err) {
                    err === null && msg.set('File Deleted', 'fadeout');
                    loadFiles(); // reload files-table
                }).fail(function() {
                    msg.set('Problem with connection; try again.', 'fadeout');
                });
            };
            del.textContent = 'delete';
            td[3].appendChild(del);
            for(s = 0; s < 4; s++) {
                tr.appendChild(td[s]);
            }
            return tr;
        };

        /**
         * Creates a HTML Movie-Thumb from the Movie-Poster
         *
         * @param {string} imageUrl The Url of the Movie-Poster-Image
         * @param {string} title Title of the Movie as title-tag
         *
         * @returns {Object} the DOM-Object of the div
         */
        var thumbPoster = function(imageUrl, title, year) {
            var img = document.createElement('img');
            img.src = imageUrl;
            img.className = 'thumbPosterImg thumb thumbnail';
            img.style.height = '150px';
            img.title = title + ' (' + year + ')';
            var divTitle = document.createElement('div');
            var div = document.createElement('div');
            div.className = 'thumbPoster';
            divTitle.title = title + ' (' + year + ')';
            divTitle.className = 'thumbPosterTitle';
            divTitle.textContent = title;
            if(imageUrl === 'http://image.tmdb.org/t/p/w500null' || imageUrl === '' || (/poster_default/).test(imageUrl)) {
                img.src = '/images/default.jpg';
                //div.appendChild(divTitle);

            }
            div.appendChild(img);
            return div;
        };
        /**
         * Adds info to the movie-Thumb (Resolution, etc.)
         */
        var thumbPosterWithInfo = function(imageUrl, title, year, resolutions) {
            var thumb = thumbPoster(imageUrl, title, year);
            var divRes = document.createElement('div');
            divRes.className = 'resolutionBar';
            divRes.textContent = resolutions.join(', ');
            //thumb.appendChild(divRes);
            return thumb;
        };
        var thumbPosterWithInfoClickable = function(mData) {
            imgUrl = mData.info.posters !== undefined ? mData.info.posters.thumbnail : '';
            var div = thumbPosterWithInfo(imgUrl, mData.title, mData.info.year, mData.resolutions);
            div.style.cursor = 'pointer';
            div.onclick = (function(_id, title, info, image, sites, div) {
                return function() {
                    $('.nav-tabs a[href="#tabLinks"]').tab('show');
                    $('#linksDetails').empty();
                    $('#linksDetails').append(divMovieInfo(_id, title, image, info.runtime ? info.runtime : '?', info.year, 'imdb-Rating', info.synopsis === '' ? 'no synopsis' : info.synopsis, 'actors', div));
                    // Site-Links for ripping links
                    var linkList = document.getElementById('linksDetails');
                    // Link to Rip all links at the same time
                    linkList.appendChild(siteRow(sites));
                    // Single Links that can be parsed
                    for(var key in sites) {
                        linkList.appendChild(siteRow(sites[key]));
                    }
                };
            })(mData._id, mData.title, mData.info, imgUrl, mData.sites, div);
            return div;
        };
        /**
         * Creates the Movie-Info-Card
         */
        var divMovieInfo = function(_id, title, posterUrl, runtime, year, imdb, synopsis, actors, thumbDiv) {
            var div = document.createElement('div');
            div.className = 'movieDigest';
            var divOuter = document.createElement('div');
            divOuter.className = 'movieInfo';
            var divTitle = document.createElement('h2');
            divTitle.className = 'movieInfoTitle';
            divTitle.textContent = title;
            var divDetails = document.createElement('div');
            divDetails.className = 'movieInfoLine';
            divDetails.textContent = 'Length: ' + runtime + 'min, Year: ' + year + ', ';
            var spanRemove = createElementSpanRemove(_id, thumbDiv);
            divDetails.appendChild(spanRemove);
            divDetails.appendChild(createElementSpanSpace());
            var spanUpdate = createElementSpanUpdate(_id);
            divDetails.appendChild(spanUpdate);
            var divSynopsis = document.createElement('div');
            divSynopsis.className = 'movieInfoLine';
            divSynopsis.textContent = synopsis;
            divSynopsis.style.fontStyle = 'italic';
            var poster = thumbPoster(posterUrl, title, year);
            poster.style.float = 'left';
            divOuter.appendChild(divTitle);
            divOuter.appendChild(divDetails);
            divOuter.appendChild(divSynopsis);
            div.appendChild(poster);
            div.appendChild(divOuter);
            return div;
        };
        /**
         * creates a space-span of len white spaces
         */
        var createElementSpanSpace = function(len) {
            if(len === undefined) len = 1;
            var span = document.createElement('span');
            var space = '';
            for(var i = 0; i < len; i++) {
                space += ' ';
            }
            span.textContent = space;
            return span;
        };
        /**
         * Creates a link which removes a movie from future display
         */
        var createElementSpanRemove = function(id, thumbDiv) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'remove';
            span.title = 'don\'t display this movie anymore.';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/hide', function(data) {
                    msg.set('Movie will not be shown anymore!', 'fadeout');
                    $('.nav-tabs a[href="#tabHome"]').tab('show');
                    thumbDiv.parentNode.removeChild(thumbDiv);
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Creates a link which updates a movie-info
         */
        var createElementSpanUpdate = function(id) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'update';
            span.title = 'update info to this movie';
            span.className = 'glyphicon glyphicon-refresh';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/update', function(data) {
                    msg.set('Movie-Info Updated', 'fadeout');
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Create a Link that can be parsed (for one or multiple Links)
         */
        var parseLink = function(text, sites, clickEvent) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            div.textContent = text;
            div.onclick = function() {
                clickEvent(sites);
            };
            return div;
        };

        /*
         * Table with ul.to links that have been checked for availability
         *
         * @param {array} files an Array containing all checked ul.to links
         */
        var makeTableChecked = function(files) {
            // one tab for every extension; integer is filecount per extension
            var extensions = {
                mp4: 0,
                mkv: 0,
                avi: 0,
                rar: 0,
                default: 0
            };
            var rowcols = ['link', 'size', 'extension', 'jd', 'cloud'];
            var target = '#tabs-links-';
            // empty all tabs
            for(var i in extensions) $(target + i + ' tbody').empty();
            var cols = function() {
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                return tds;
            };
            // sort files by extension
            files.sort(function(a, b) {
                return a.extension  b.extension ? -1 : 0;
            });
            var makeRow = function(filename, href, extension, size) {
                // create new DOM-table-row
                var tr = document.createElement('tr');
                // create cells
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                // Link/Name Col
                var link = document.createElement('a');
                link.href = href;
                link.textContent = filename;
                tds[0].appendChild(link);
                // Size Col
                tds[1].textContent = bytesToSize(size);
                // Extension Col
                var extension = document.createElement('div');
                extension.className = 'icon icon' + extension;
                extension.title = extension;
                tds[2].appendChild(extension);
                // J-Downloader Col
                tds[3].appendChild(jDLink(link));
                // Download to Server Col
                var cloud = document.createElement('div');
                cloud.className = 'icon iconcloud';
                cloud.title = 'download to diskstation';
                cloud.onclick = (function(link) {
                    return function() {
                        DownloadStation(link);
                    };
                })(href);
                tds[4].appendChild(cloud);
                for(var key in tds) tr.appendChild(tds[key]);
                return tr;
            };
            // Loop through all files
            for(i in files) {
                var t = (extensions[files[i].extension] !== undefined) ? files[i].extension : 'default';
                extensions[t]++;
                var tr = makeRow(files[i].filename, files[i].link, files[i].extension, files[i].size);
                $(target + t + ' tbody').append(tr);
            }
            // update files per extension
            if(extensions.mp4 === 0) {
                $('.nav-tabs a[href="#tabLinks"]').tab('show');
            } else {
                $('.nav-tabs a[href="#tabs-links-mkv"]').tab('show');
            }
            // Update Tab-title counter
            for(var i in extensions) {
                $('#rssLinks ul:first li:eq(' + (Object.keys(extensions)).indexOf(i) + ') a').text(i + '(' + extensions[i] + ')');
            }
        };

        (function(){
            var bParse = document.getElementById('go');
            bParse.onclick = function(){
                var data = document.getElementById('data').value;
                if (validateURL(data)) {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: [{link:data}]
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                }
            };
        })();

    });
})();<commit_msg>update grid after removal<commit_after>(function() {
    $(document).ready(function() {
        var movies = [];

        /*
         * Loads the list of Downloaded files that are on the server
         */
        var loadFiles = function() {
            $.ajax({
                url: '/files',
                type: 'get',
                cache: false,
                dataType: 'json'
            }).done(function(data){
                $('#rss_files tbody').empty();
                // Sort files by Filename
                data.sort(function(a, b) {
                    a = a.filename.toLowerCase();
                    b = b.filename.toLowerCase();
                    return a > b ? 1 : a < b ? -1 : 0;
                });
                var tr, td = [], a, icon, del, s, i;
                for(i in data) {
                    $('#rss_files tbody').append(fileRow(data[i]));
                }
            }).fail(function(){

            });
        };
        /*
         * Loads List of TV-Shows direct from monitored RSS
         *
         */
        var loadRssTV = function(type) {
            var div, rssTV = document.getElementById('rss_TV');
            $.ajax({
                url: '/tv',
                type: 'get',
                dataType: 'json',
                cache: false
            }).done(function(data) {
                for(var i in data) {
                    rssTV.appendChild(siteRow(data[i]));
                }
            }).fail(function(data) {
                msg.set('Error loading TV-Shows');
            });
        };
        /*
         * Loads list of Movies as Thumbnails from db
         *
         */
        var loadRssMovies = function() {
            $.ajax({
                url: '/movies',
                type: 'get',
                dataType: 'json',
                cache: false,
            }).done(function(json) {
                var div, i;
                json.sort(function(a, b) {
                    a = new Date(a.lastUpdate);
                    b = new Date(b.lastUpdate);
                    return a > b ? -1 : a < b ? 1 : 0;
                });
                movies = json;
                movieGrid(movies);
            }).fail(function(data) {
                msg.set('Error while loading movies');
            });
        };
        loadRssTV();
        loadRssMovies();
        loadFiles();

        /*
         * Creates a grid of all movies clickable
         *
         *
         */
        var movieGrid = function(movies) {
            var li, div, container;
            container = document.getElementById('rss_Movies');
            // empty container
            while (container.firstChild) {
                container.removeChild(container.firstChild);
            }
            // Insert new movie-thumbs into container
            for(i = 0; i < movies.length; i++) {
                div = thumbPosterWithInfoClickable(movies[i]);
                li = document.createElement('li');
                li.className = 'col-lg-1 col-md-2 col-sm-3 col-xs-4';
                li.appendChild(div);
                container.appendChild(li);
            }
        };

        /*
         * Creates a siteRow which can be parsed
         *
         * @param site  {object} {title, pubdate, link, description}
         *
         *
         */
        var siteRow = function(sites) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            if(sites.title !== undefined) {
                var domain = sites.link.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
                var date = new Date(sites.pubdate);
                div.innerHTML = sites.title + ' (' + date.easy() + ' @' + domain[1] + ')';
                sites = [sites];
            } else {
                div.textContent = '>- rip All Sites -<';
            }
            div.onclick = (function(sites) {
                return function() {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: sites
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                };
            })(sites);
            return div;
        };
        /*
         * Process returned online links
         */
        var processLinks = function(data) {
            /* structure of data; example
                [
                  {
                    "status": "0",
                    "filename": "Sm.2013.720p-iFT",
                    "extension": "mkv",
                    "size": "4920000000",
                    "link": "http://ul.to/08otd5be"
                  }
                  { etc. }
                ]
            */
            msg.set('found ' + data.length + ' links.')
            makeTableChecked(data);
            // Add links to textarea for exporting
            $('#paste').html(data.map(function(elem) {
                return elem.link;
            }).join(' '));
            $('.nav-tabs a[href="#tabLinks"]').tab('show');
        };

        /*
         * One Row of FileExplorer
         */
        var fileRow = function(file) {
            var tr = document.createElement('tr');
            var td = [];
            for(s = 0; s < 4; s++) {
                td.push(document.createElement('td'));
            }
            var a = null,
                icon = null,
                del = null,
                s = 0,
                i = 0;
            // Filename Link
            a = document.createElement('a');
            a.href = 'files/' + file.link;
            a.textContent = file.filename;
            td[0].appendChild(a);
            td[1].textContent = bytesToSize(file.size);
            // Filetype Icon
            icon = document.createElement('div');
            icon.className = 'icon icon' + file.extension;
            icon.title = file.extension;
            td[2].appendChild(icon);
            // DELETE Link
            del = document.createElement('div');
            del.className = 'a';
            del.onclick = function() {
                $.ajax({
                    url: 'files/' + file.link + '/delete',
                    type: 'DELETE',
                    dataType: 'json'
                }).done(function(err) {
                    err === null && msg.set('File Deleted', 'fadeout');
                    loadFiles(); // reload files-table
                }).fail(function() {
                    msg.set('Problem with connection; try again.', 'fadeout');
                });
            };
            del.textContent = 'delete';
            td[3].appendChild(del);
            for(s = 0; s < 4; s++) {
                tr.appendChild(td[s]);
            }
            return tr;
        };

        /**
         * Creates a HTML Movie-Thumb from the Movie-Poster
         *
         * @param {string} imageUrl The Url of the Movie-Poster-Image
         * @param {string} title Title of the Movie as title-tag
         *
         * @returns {Object} the DOM-Object of the div
         */
        var thumbPoster = function(imageUrl, title, year) {
            var img = document.createElement('img');
            img.src = imageUrl;
            img.className = 'thumbPosterImg thumb thumbnail';
            img.style.height = '150px';
            img.title = title + ' (' + year + ')';
            var divTitle = document.createElement('div');
            var div = document.createElement('div');
            div.className = 'thumbPoster';
            divTitle.title = title + ' (' + year + ')';
            divTitle.className = 'thumbPosterTitle';
            divTitle.textContent = title;
            if(imageUrl === 'http://image.tmdb.org/t/p/w500null' || imageUrl === '' || (/poster_default/).test(imageUrl)) {
                img.src = '/images/default.jpg';
                //div.appendChild(divTitle);

            }
            div.appendChild(img);
            return div;
        };
        /**
         * Adds info to the movie-Thumb (Resolution, etc.)
         */
        var thumbPosterWithInfo = function(imageUrl, title, year, resolutions) {
            var thumb = thumbPoster(imageUrl, title, year);
            var divRes = document.createElement('div');
            divRes.className = 'resolutionBar';
            divRes.textContent = resolutions.join(', ');
            //thumb.appendChild(divRes);
            return thumb;
        };
        var thumbPosterWithInfoClickable = function(mData) {
            imgUrl = mData.info.posters !== undefined ? mData.info.posters.thumbnail : '';
            var div = thumbPosterWithInfo(imgUrl, mData.title, mData.info.year, mData.resolutions);
            div.style.cursor = 'pointer';
            div.onclick = (function(_id, title, info, image, sites, div) {
                return function() {
                    $('.nav-tabs a[href="#tabLinks"]').tab('show');
                    $('#linksDetails').empty();
                    $('#linksDetails').append(divMovieInfo(_id, title, image, info.runtime ? info.runtime : '?', info.year, 'imdb-Rating', info.synopsis === '' ? 'no synopsis' : info.synopsis, 'actors', div));
                    // Site-Links for ripping links
                    var linkList = document.getElementById('linksDetails');
                    // Link to Rip all links at the same time
                    linkList.appendChild(siteRow(sites));
                    // Single Links that can be parsed
                    for(var key in sites) {
                        linkList.appendChild(siteRow(sites[key]));
                    }
                };
            })(mData._id, mData.title, mData.info, imgUrl, mData.sites, div);
            return div;
        };
        /**
         * Creates the Movie-Info-Card
         */
        var divMovieInfo = function(_id, title, posterUrl, runtime, year, imdb, synopsis, actors, thumbDiv) {
            var div = document.createElement('div');
            div.className = 'movieDigest';
            var divOuter = document.createElement('div');
            divOuter.className = 'movieInfo';
            var divTitle = document.createElement('h2');
            divTitle.className = 'movieInfoTitle';
            divTitle.textContent = title;
            var divDetails = document.createElement('div');
            divDetails.className = 'movieInfoLine';
            divDetails.textContent = 'Length: ' + runtime + 'min, Year: ' + year + ', ';
            var spanRemove = createElementSpanRemove(_id, thumbDiv);
            divDetails.appendChild(spanRemove);
            divDetails.appendChild(createElementSpanSpace());
            var spanUpdate = createElementSpanUpdate(_id);
            divDetails.appendChild(spanUpdate);
            var divSynopsis = document.createElement('div');
            divSynopsis.className = 'movieInfoLine';
            divSynopsis.textContent = synopsis;
            divSynopsis.style.fontStyle = 'italic';
            var poster = thumbPoster(posterUrl, title, year);
            poster.style.float = 'left';
            divOuter.appendChild(divTitle);
            divOuter.appendChild(divDetails);
            divOuter.appendChild(divSynopsis);
            div.appendChild(poster);
            div.appendChild(divOuter);
            return div;
        };
        /**
         * creates a space-span of len white spaces
         */
        var createElementSpanSpace = function(len) {
            if(len === undefined) len = 1;
            var span = document.createElement('span');
            var space = '';
            for(var i = 0; i < len; i++) {
                space += ' ';
            }
            span.textContent = space;
            return span;
        };
        /**
         * Creates a link which removes a movie from future display
         */
        var createElementSpanRemove = function(id, thumbDiv) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'remove';
            span.title = 'don\'t display this movie anymore.';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/hide', function(data) {
                    for (var i = 0; i<movies.length;i++) {
                        if (movies[i]._id === id) {
                            movies = movies.splice(i,1);
                            break;
                        }
                    }
                    movieGrid(movies);
                    msg.set('Movie will not be shown anymore!', 'fadeout');
                    $('.nav-tabs a[href="#tabHome"]').tab('show');
                    thumbDiv.parentNode.removeChild(thumbDiv);
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Creates a link which updates a movie-info
         */
        var createElementSpanUpdate = function(id) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'update';
            span.title = 'update info to this movie';
            span.className = 'glyphicon glyphicon-refresh';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/update', function(data) {
                    msg.set('Movie-Info Updated', 'fadeout');
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Create a Link that can be parsed (for one or multiple Links)
         */
        var parseLink = function(text, sites, clickEvent) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            div.textContent = text;
            div.onclick = function() {
                clickEvent(sites);
            };
            return div;
        };

        /*
         * Table with ul.to links that have been checked for availability
         *
         * @param {array} files an Array containing all checked ul.to links
         */
        var makeTableChecked = function(files) {
            // one tab for every extension; integer is filecount per extension
            var extensions = {
                mp4: 0,
                mkv: 0,
                avi: 0,
                rar: 0,
                default: 0
            };
            var rowcols = ['link', 'size', 'extension', 'jd', 'cloud'];
            var target = '#tabs-links-';
            // empty all tabs
            for(var i in extensions) $(target + i + ' tbody').empty();
            var cols = function() {
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                return tds;
            };
            // sort files by extension
            files.sort(function(a, b) {
                return a.extension  b.extension ? -1 : 0;
            });
            var makeRow = function(filename, href, extension, size) {
                // create new DOM-table-row
                var tr = document.createElement('tr');
                // create cells
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                // Link/Name Col
                var link = document.createElement('a');
                link.href = href;
                link.textContent = filename;
                tds[0].appendChild(link);
                // Size Col
                tds[1].textContent = bytesToSize(size);
                // Extension Col
                var extension = document.createElement('div');
                extension.className = 'icon icon' + extension;
                extension.title = extension;
                tds[2].appendChild(extension);
                // J-Downloader Col
                tds[3].appendChild(jDLink(link));
                // Download to Server Col
                var cloud = document.createElement('div');
                cloud.className = 'icon iconcloud';
                cloud.title = 'download to diskstation';
                cloud.onclick = (function(link) {
                    return function() {
                        DownloadStation(link);
                    };
                })(href);
                tds[4].appendChild(cloud);
                for(var key in tds) tr.appendChild(tds[key]);
                return tr;
            };
            // Loop through all files
            for(i in files) {
                var t = (extensions[files[i].extension] !== undefined) ? files[i].extension : 'default';
                extensions[t]++;
                var tr = makeRow(files[i].filename, files[i].link, files[i].extension, files[i].size);
                $(target + t + ' tbody').append(tr);
            }
            // update files per extension
            if(extensions.mp4 === 0) {
                $('.nav-tabs a[href="#tabLinks"]').tab('show');
            } else {
                $('.nav-tabs a[href="#tabs-links-mkv"]').tab('show');
            }
            // Update Tab-title counter
            for(var i in extensions) {
                $('#rssLinks ul:first li:eq(' + (Object.keys(extensions)).indexOf(i) + ') a').text(i + '(' + extensions[i] + ')');
            }
        };

        // Manual parser Button
        (function(){
            var bParse = document.getElementById('go');
            bParse.onclick = function(){
                var data = document.getElementById('data').value;
                if (validateURL(data)) {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: [{link:data}]
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                }
            };
        })();

    });
})();<|endoftext|>


<commit_before>$('document').ready(() => {
  console.log('index.js ready')
  function updateBatchList() {
    $.get('/batchList', (data) => {
      for (let batchName of data.CommonPrefixes) {
        let $batch = $('<a />');
        $batch.attr('href', `/batch/${batchName.Prefix}`).text(batchName.Prefix.slice(0, -1)).addClass('batch-link');
        $('#batch-list').append($batch);
      }
    });
  }

  function uploadToS3(file, signedRequest, callback) {
    $.ajax({
      method: 'PUT',
      url: signedRequest,
      contentType: file.type,
      processData: false,
      data: file,
      success: (data) => {
        console.log('the file has been uploaded');
        callback(true);
      },
      error: (err) => {
        console.log('there was an error uploading:', err);
        callback(false);
      }
    });
  }

  function getSignedRequest(files, batchName) {
    let count = 0;
    const batchFolder = `${batchName}/`;
    for (let file of files) {
      $.get( `/sign-s3?file-name=${batchFolder}${file.name}&file-type=${file.type}`, (data) => {
        if (data) {
          uploadToS3(file, data.signedRequest, (success) => {
            if (!success) {
              alert('There was a problem uploading. Please check and try again');
              return;
            }
            count++;
            $('#to-upload').text(files.length - count);
            if (count === files.length) {
              location.reload();
              $('.loading').addClass('hidden');
              alert('your photos have been uploaded');
            }
          });
        } else {
          console.log('could not get signed url')
        }
      });
    }
  }

  $('#file-input').on('submit', (event) => {
    event.preventDefault();
    const files = $('#files').prop('files');
    const batchName = $('#batch-name').val();
    if (files.length === 0) {
      alert('Uh oh~ No files were selected!');
      return;
    }
    getSignedRequest(files, batchName);
    $('.loading').removeClass('hidden');
  });

  function chk(e){

    if (!$("form").valid())
        return false;

       const files = $('#files').prop('files');
    const batchName = $('#batch-name').val();
    if (files.length === 0) {
      alert('Uh oh~ No files were selected!');
      return;
    }
    getSignedRequest(files, batchName);
    $('.loading').removeClass('hidden');

    return false;
}

  updateBatchList();
});<commit_msg>I hate ios<commit_after>$('document').ready(() => {
  console.log('index.js ready')
  function updateBatchList() {
    $.get('/batchList', (data) => {
      for (let batchName of data.CommonPrefixes) {
        let $batch = $('<a />');
        $batch.attr('href', `/batch/${batchName.Prefix}`).text(batchName.Prefix.slice(0, -1)).addClass('batch-link');
        $('#batch-list').append($batch);
      }
    });
  }

  function uploadToS3(file, signedRequest, callback) {
    $.ajax({
      method: 'PUT',
      url: signedRequest,
      contentType: file.type,
      processData: false,
      data: file,
      success: (data) => {
        console.log('the file has been uploaded');
        callback(true);
      },
      error: (err) => {
        console.log('there was an error uploading:', err);
        callback(false);
      }
    });
  }

  function getSignedRequest(files, batchName) {
    let count = 0;
    const batchFolder = `${batchName}/`;
    for (let file of files) {
      $.get( `/sign-s3?file-name=${batchFolder}${file.name}&file-type=${file.type}`, (data) => {
        if (data) {
          uploadToS3(file, data.signedRequest, (success) => {
            if (!success) {
              alert('There was a problem uploading. Please check and try again');
              return;
            }
            count++;
            $('#to-upload').text(files.length - count);
            if (count === files.length) {
              location.reload();
              $('.loading').addClass('hidden');
              alert('your photos have been uploaded');
            }
          });
        } else {
          console.log('could not get signed url')
        }
      });
    }
  }

  $('#file-input').on('submit', (event) => {
    event.preventDefault();
    alert('submit')
    const files = $('#files').prop('files');
    const batchName = $('#batch-name').val();
    if (files.length === 0) {
      alert('Uh oh~ No files were selected!');
      return;
    }
    getSignedRequest(files, batchName);
    $('.loading').removeClass('hidden');
  });

  function chk(e){
    alert('chk')
    if (!$("form").valid())
        return false;

       const files = $('#files').prop('files');
    const batchName = $('#batch-name').val();
    if (files.length === 0) {
      alert('Uh oh~ No files were selected!');
      return;
    }
    getSignedRequest(files, batchName);
    $('.loading').removeClass('hidden');

    return false;
}

  updateBatchList();
});<|endoftext|>


<commit_before>$(document).ready(function () {
  var timeData = [],
    temperatureData = [],
    humidityData = [],
  pm2Data = [],
  pm10Data = [];
 //---------yanji start 1/2------------

  //20170913
  var pm10Data = [],
      pm25Data = [];
  var result;
 // android 20170912 23:29
  var humilength = humidityData.length;
  // 20170913
  var templength = temperatureData.length;
  var pm10length = pm10Data.length;
  var pm25length = pm25Data.length;
  var rpmData = [];
  var rpm2Data = [];

   var aaaa = 50;
  //---------yanji end 1/2------------
  document.getElementById("pm2").innerHTML = "50";
  document.getElementById("pm10").innerHTML = "30";
  document.getElementById("temp").innerHTML = "10";
  document.getElementById("humi").innerHTML = "80";
  document.getElementById("rpm").innerHTML = "1200";
  document.getElementById("rpm2").innerHTML = "1000";
  var data = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Temp',
        yAxisID: 'Temperature',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: temperatureData
      },
      {
        fill: false,
        label: 'pm2.5',
        yAxisID: 'pm2.5',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: pm2Data
      }
    ]
  }

  var basicOption = {
    title: {
      display: true,
      text: 'Temperature & pm2.5 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Temperature',
        type: 'linear',
        scaleLabel: {
          labelString: 'Temp(C)',
          display: true
        },
        position: 'left',
      }, {
          id: 'pm2.5',
          type: 'linear',
          scaleLabel: {
            labelString: 'pm2.5(ug/m3)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  var data2 = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Motor1',
        yAxisID: 'Motor1',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: rpmData
      },
      {
        fill: false,
        label: 'Motor2',
        yAxisID: 'Motor2',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: rpm2Data
      }
    ]
  }

  var basicOption2 = {
    title: {
      display: true,
      text: 'Mortor1 & Mortor2 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Motor1',
        type: 'linear',
        scaleLabel: {
          labelString: 'rpm(r/min)',
          display: true
        },
        position: 'left',
      }, {
          id: 'Motor2',
          type: 'linear',
          scaleLabel: {
            labelString: 'rpm(r/min)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  //Get the context of the canvas element we want to select
  var ctx = document.getElementById("myChart").getContext("2d");
  var optionsNoAnimation = { animation: false }
  var myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: basicOption
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ctx2 = document.getElementById("myChart2").getContext("2d");
  var optionsNoAnimation2 = { animation: false }
  var myLineChart2 = new Chart(ctx2, {
    type: 'line',
    data: data2,
    options: basicOption2
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ws = new WebSocket('wss://' + location.host);
  ws.onopen = function () {
    console.log('Successfully connect WebSocket');
  }
  ws.onmessage = function (message) {
    console.log('receive message' + message.data);
    try {
      var obj = JSON.parse(message.data);
      if(!obj.time || !obj.params.Temperature) {
        return;
      }
      document.getElementById("pm2").innerHTML = obj.params.pm2;
  	  document.getElementById("pm10").innerHTML = obj.params.pm10;
	  document.getElementById("temp").innerHTML = obj.params.Temperature;
	  document.getElementById("humi").innerHTML = obj.params.Humidity;
	  document.getElementById("rpm").innerHTML = obj.params.rpm;
	  document.getElementById("rpm2").innerHTML = obj.params.rpm2;
      timeData.push(obj.time);
      temperatureData.push(obj.params.Temperature);
      // only keep no more than 50 points in the line chart
      const maxLen = 10;
      var len = timeData.length;
      if (len > maxLen) {
        timeData.shift();
        temperatureData.shift();
      }

      if (obj.params.Humidity) {
        humidityData.push(obj.params.Humidity);
      }
      if (humidityData.length > maxLen) {
        humidityData.shift();
      }
	  if (obj.params.pm2) {
		  pm2Data.push(obj.params.pm2);
	  }
	  if (pm2Data.length > maxLen)
	  {
		  pm2Data.shift();
	  }
	  if (obj.params.rpm) {
		  alert(obj.params.rpm);
		  rpmData.push(obj.params.rpm);
	  }
	  if (rpmData.length > maxLen)
	  {
		  rpmData.shift();
	  }
	  if (obj.params.rpm2) {
		  rpm2Data.push(obj.params.rpm2);
	  }
	  if (rpm2Data.length > maxLen)
	  {
		  rpm2Data.shift();
	  }

 myLineChart2.update();

      myLineChart.update();

 //---------yanji start 2/2------------
  //20170913 pm Data push
      pm10Data.push(obj.params.pm10);
      pm25Data.push(obj.params.pm2);

      //android 20170912 23:29
//       if(humilength==0 || templength == 0 || pm10length ==0 || pm25length ==0){

//            }
//           }else{
//             humilength = humidityData.length;
//             templength = temperatureData.length;
//             pm10length = pm10Data.length;
//             pm25length = pm25Data.length;
//            insertDatas(pm25Data[pm25length],humidityData[humilength],temperatureData[templength],humidityData[humilength]);
//         }
      //20170913

     if((pm25length<pm25Data.length || pm25length == pm25Data.length)&&(pm10length<pm10Data.length || pm10length == pm10Data.length)&&(templength<temperatureData.length || templength == temperatureData.length)&&(humilength<humidityData.length || humilength == humidityData.length)){
          pm25length = pm25Data.length;
          pm10length = pm10Data.length;
          humilength = humidityData.length;
          templength = temperatureData.length;

          insertDatas(pm25Data[pm25length-1],pm10Data[pm10length-1],temperatureData[templength-1],humidityData[humilength-1]);

          }

      //android 20170912 23:29
      function insertDatas(p2,p1,t,h){
         var p2State;
         if(p2<31){
           p2State = "좋음";
         }else if(p2<81){
           p2State = "보통";
         }else if(p2<151){
           p2State = "나쁨";
         }else{
           p2State = "매우나쁨";
         }
         Ao.showResult(p2,p1,t,h,p2State);
      }

//---------yanji end 2/2------------

    } catch (err) {
      console.error(err);
    }
  }
});
<commit_msg>Update index.js<commit_after>$(document).ready(function () {
  var timeData = [],
    temperatureData = [],
    humidityData = [],
  pm2Data = [],
  pm10Data = [];
 //---------yanji start 1/2------------

  //20170913
  var pm10Data = [],
      pm25Data = [];
  var result;
 // android 20170912 23:29
  var humilength = humidityData.length;
  // 20170913
  var templength = temperatureData.length;
  var pm10length = pm10Data.length;
  var pm25length = pm25Data.length;
  var rpmData = [];
  var rpm2Data = [];

   var aaaa = 50;
  //---------yanji end 1/2------------
  document.getElementById("pm2").innerHTML = "50";
  document.getElementById("pm10").innerHTML = "30";
  document.getElementById("temp").innerHTML = "10";
  document.getElementById("humi").innerHTML = "80";
  document.getElementById("rpm").innerHTML = "1200";
  document.getElementById("rpm2").innerHTML = "1000";
  var data = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Temp',
        yAxisID: 'Temperature',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: rpmData
      },
      {
        fill: false,
        label: 'pm2.5',
        yAxisID: 'pm2.5',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: rpm2Data
      }
    ]
  }

  var basicOption = {
    title: {
      display: true,
      text: 'Temperature & pm2.5 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Temperature',
        type: 'linear',
        scaleLabel: {
          labelString: 'Temp(C)',
          display: true
        },
        position: 'left',
      }, {
          id: 'pm2.5',
          type: 'linear',
          scaleLabel: {
            labelString: 'pm2.5(ug/m3)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  var data2 = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Motor1',
        yAxisID: 'Motor1',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: rpmData
      },
      {
        fill: false,
        label: 'Motor2',
        yAxisID: 'Motor2',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: rpm2Data
      }
    ]
  }

  var basicOption2 = {
    title: {
      display: true,
      text: 'Mortor1 & Mortor2 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Motor1',
        type: 'linear',
        scaleLabel: {
          labelString: 'rpm(r/min)',
          display: true
        },
        position: 'left',
      }, {
          id: 'Motor2',
          type: 'linear',
          scaleLabel: {
            labelString: 'rpm(r/min)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  //Get the context of the canvas element we want to select
  var ctx = document.getElementById("myChart").getContext("2d");
  var optionsNoAnimation = { animation: false }
  var myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: basicOption
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ctx2 = document.getElementById("myChart2").getContext("2d");
  var optionsNoAnimation2 = { animation: false }
  var myLineChart2 = new Chart(ctx2, {
    type: 'line',
    data: data2,
    options: basicOption2
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ws = new WebSocket('wss://' + location.host);
  ws.onopen = function () {
    console.log('Successfully connect WebSocket');
  }
  ws.onmessage = function (message) {
    console.log('receive message' + message.data);
    try {
      var obj = JSON.parse(message.data);
      if(!obj.time || !obj.params.Temperature) {
        return;
      }
      document.getElementById("pm2").innerHTML = obj.params.pm2;
  	  document.getElementById("pm10").innerHTML = obj.params.pm10;
	  document.getElementById("temp").innerHTML = obj.params.Temperature;
	  document.getElementById("humi").innerHTML = obj.params.Humidity;
	  document.getElementById("rpm").innerHTML = obj.params.rpm;
	  document.getElementById("rpm2").innerHTML = obj.params.rpm2;
      timeData.push(obj.time);
      temperatureData.push(obj.params.Temperature);
      // only keep no more than 50 points in the line chart
      const maxLen = 10;
      var len = timeData.length;
      if (len > maxLen) {
        timeData.shift();
        temperatureData.shift();
      }

      if (obj.params.Humidity) {
        humidityData.push(obj.params.Humidity);
      }
      if (humidityData.length > maxLen) {
        humidityData.shift();
      }
	  if (obj.params.pm2) {
		  pm2Data.push(obj.params.pm2);
	  }
	  if (pm2Data.length > maxLen)
	  {
		  pm2Data.shift();
	  }
	  if (obj.params.rpm) {
		  rpmData.push(obj.params.rpm);
	  }
	  if (rpmData.length > maxLen)
	  {
		  rpmData.shift();
	  }
	  if (obj.params.rpm2) {
		  rpm2Data.push(obj.params.rpm2);
	  }
	  if (rpm2Data.length > maxLen)
	  {
		  rpm2Data.shift();
	  }

 myLineChart2.update();

      myLineChart.update();

 //---------yanji start 2/2------------
  //20170913 pm Data push
      pm10Data.push(obj.params.pm10);
      pm25Data.push(obj.params.pm2);

      //android 20170912 23:29
//       if(humilength==0 || templength == 0 || pm10length ==0 || pm25length ==0){

//            }
//           }else{
//             humilength = humidityData.length;
//             templength = temperatureData.length;
//             pm10length = pm10Data.length;
//             pm25length = pm25Data.length;
//            insertDatas(pm25Data[pm25length],humidityData[humilength],temperatureData[templength],humidityData[humilength]);
//         }
      //20170913

     if((pm25length<pm25Data.length || pm25length == pm25Data.length)&&(pm10length<pm10Data.length || pm10length == pm10Data.length)&&(templength<temperatureData.length || templength == temperatureData.length)&&(humilength<humidityData.length || humilength == humidityData.length)){
          pm25length = pm25Data.length;
          pm10length = pm10Data.length;
          humilength = humidityData.length;
          templength = temperatureData.length;

          insertDatas(pm25Data[pm25length-1],pm10Data[pm10length-1],temperatureData[templength-1],humidityData[humilength-1]);

          }

      //android 20170912 23:29
      function insertDatas(p2,p1,t,h){
         var p2State;
         if(p2<31){
           p2State = "좋음";
         }else if(p2<81){
           p2State = "보통";
         }else if(p2<151){
           p2State = "나쁨";
         }else{
           p2State = "매우나쁨";
         }
         Ao.showResult(p2,p1,t,h,p2State);
      }

//---------yanji end 2/2------------

    } catch (err) {
      console.error(err);
    }
  }
});
<|endoftext|>


<commit_before>/*global module: false, require: false */
'use strict';

var React = require('react');
var _ = require('underscore');
require('muts-needle-plot/src/js/d3-svg-legend');
require('./css/d3Lollipop.css');
var Mutneedles = require("muts-needle-plot");
var PureRenderMixin = require('./PureRenderMixin');

var {Grid, Row, Nav, NavItem} = require('react-bootstrap');

var brca12JSON = {
    BRCA1: {
        brcaDomainFile: require('raw!../content/brca1LollipopDomain.json')
    },
    BRCA2: {
        brcaDomainFile: require('raw!../content/brca2LollipopDomain.json')
    }
};
var d3Lollipop = {};

d3Lollipop.drawStuffWithD3 = function(ref, muts, domain, id, varlink, data) {
    var xAxisLabel = '';
    var minPos = 0;
    var maxPos = 1;
    if (id === 'BRCA1') {
        xAxisLabel = 'Coordinate Selection (GRCh38 chr 17)';
        minPos = 43030000;
        maxPos = 43130000;
    } else if (id === 'BRCA2') {
        xAxisLabel = 'Coordinate Selection (GRCh38 chr 13)';
        minPos = 32300000;
        maxPos = 32410000;
    }
    var legends = {x: xAxisLabel, y: ""};
    var colorMap = {
      // mutation categories
      "Pathogenic": "red",
      "Benign": "lightblue"
    };
    var config = {variantDetailLink: varlink, minCoord: minPos, maxCoord: maxPos, mutationData: muts, regionData: domain, targetElement: ref.id, legends: legends, colorMap: colorMap };
    var instance =  new Mutneedles(config);
    return function() {
        instance.tip.destroy();
        instance.selectionTip.destroy();
    };
};

var D3Lollipop = React.createClass({
    mixins: [PureRenderMixin],
    render: function () {
        return (

        );
    },
    filterAttributes: function (obj) {
        var oldObj = _(obj).pick('Genomic_Coordinate_hg38', 'Pathogenicity_default');
        var parts = oldObj.Genomic_Coordinate_hg38.split(':');
        var chrCoordinate = parseInt(oldObj.Genomic_Coordinate_hg38.split(':')[parts.length - 2]);
        var alleleChange = _.last(parts);
        var refAllele = alleleChange.split('>')[0];
        var altAllele = alleleChange.split('>')[1];
        if (altAllele.length > refAllele.length) {
            chrCoordinate = String(chrCoordinate) + '-' + String(chrCoordinate + altAllele.length - 1);
        } else {
            chrCoordinate = String(chrCoordinate);
        }
        if (oldObj.Pathogenicity_default == 'Not Yet Classified'){
            oldObj.Pathogenicity_default = "Uncertain";
        }
        if (oldObj.Pathogenicity_default == 'Benign / Little Clinical Significance'){
            oldObj.Pathogenicity_default = "Benign";
        }
        var newObj = {category: oldObj.Pathogenicity_default, coord: chrCoordinate, value: 1, oldData: obj};
        return newObj;
    },

     componentDidMount: function() {
        var {data, brcakey, onRowClick, ...opts} = this.props;
        var subSetData = data.map(this.filterAttributes);
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        var domainBRCA = JSON.parse(brca12JSON[brcakey].brcaDomainFile);
        this.cleanupBRCA = d3Lollipop.drawStuffWithD3(d3svgBrcaRef, subSetData, domainBRCA, brcakey, onRowClick);
    },

    componentWillReceiveProps: function(newProps) {
        this.cleanupBRCA();
        var {data, brcakey, onRowClick, ...opts} = newProps;
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        while (d3svgBrcaRef.hasChildNodes() ) {
            d3svgBrcaRef.removeChild(d3svgBrcaRef.lastChild);
        }
        var subSetData = data.map(this.filterAttributes);
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        while (d3svgBrcaRef.hasChildNodes() ) {
            d3svgBrcaRef.removeChild(d3svgBrcaRef.lastChild);
        }
        var domainBRCA = JSON.parse(brca12JSON[brcakey].brcaDomainFile);
        this.cleanupBRCA = d3Lollipop.drawStuffWithD3(d3svgBrcaRef, subSetData, domainBRCA, brcakey, onRowClick);
    },
    componentWillUnmount: function() {
        this.cleanupBRCA();
    }
});

var Lollipop = React.createClass({
    getInitialState: function () {
        return {
            brcakey: "BRCA1",
            data: []
        };
    },
    shouldComponentUpdate: function (nextProps, nextState) {
       return (
            //Update if it's the first time rendering
            this.state.data.length === 0 ||
            !_.isEqual(this.props.opts, nextProps.opts) ||
            !_.isEqual(this.state, nextState)
        );
    },
    componentWillReceiveProps: function (newProps) {
        this.fetchData(newProps.opts);
    },
    componentWillMount: function () {
        this.fetchData = _.debounce(this.fetchData, 600, true);
        this.fetchData(this.props.opts);
    },
    fetchData: function (opts) {
        this.props.fetch(opts).subscribe(
            function (d) {
                this.setState({data: d.data});
            }.bind(this));
    },
    onSelect: function (key) {
        this.setState({brcakey: key});
    },
    render: function () {
        return (
            <Grid>

                    <Row style={{marginBottom: '2px', marginTop: '2px'}}>

                            <NavItem eventKey="BRCA1">BRCA1</NavItem>
                            <NavItem eventKey="BRCA2">BRCA2</NavItem>

                         this.props.onHeaderClick('Lollipop Plots')}/>
                        <D3Lollipop data={this.state.data} opts={this.props.opts} key={this.state.brcakey} brcakey={this.state.brcakey} onRowClick={this.props.onRowClick} id='brcaLollipop' ref='d3svgBrca'/>
                    </Row>

            </Grid>
        );
    }
});

module.exports = Lollipop;
<commit_msg>Add back PureRenderMixin to Lollipop<commit_after>/*global module: false, require: false */
'use strict';

var React = require('react');
var _ = require('underscore');
require('muts-needle-plot/src/js/d3-svg-legend');
require('./css/d3Lollipop.css');
var Mutneedles = require("muts-needle-plot");
var PureRenderMixin = require('./PureRenderMixin');

var {Grid, Row, Nav, NavItem} = require('react-bootstrap');

var brca12JSON = {
    BRCA1: {
        brcaDomainFile: require('raw!../content/brca1LollipopDomain.json')
    },
    BRCA2: {
        brcaDomainFile: require('raw!../content/brca2LollipopDomain.json')
    }
};
var d3Lollipop = {};

d3Lollipop.drawStuffWithD3 = function(ref, muts, domain, id, varlink, data) {
    var xAxisLabel = '';
    var minPos = 0;
    var maxPos = 1;
    if (id === 'BRCA1') {
        xAxisLabel = 'Coordinate Selection (GRCh38 chr 17)';
        minPos = 43030000;
        maxPos = 43130000;
    } else if (id === 'BRCA2') {
        xAxisLabel = 'Coordinate Selection (GRCh38 chr 13)';
        minPos = 32300000;
        maxPos = 32410000;
    }
    var legends = {x: xAxisLabel, y: ""};
    var colorMap = {
      // mutation categories
      "Pathogenic": "red",
      "Benign": "lightblue"
    };
    var config = {variantDetailLink: varlink, minCoord: minPos, maxCoord: maxPos, mutationData: muts, regionData: domain, targetElement: ref.id, legends: legends, colorMap: colorMap };
    var instance =  new Mutneedles(config);
    return function() {
        instance.tip.destroy();
        instance.selectionTip.destroy();
    };
};

var D3Lollipop = React.createClass({
    mixins: [PureRenderMixin],
    render: function () {
        return (

        );
    },
    filterAttributes: function (obj) {
        var oldObj = _(obj).pick('Genomic_Coordinate_hg38', 'Pathogenicity_default');
        var parts = oldObj.Genomic_Coordinate_hg38.split(':');
        var chrCoordinate = parseInt(oldObj.Genomic_Coordinate_hg38.split(':')[parts.length - 2]);
        var alleleChange = _.last(parts);
        var refAllele = alleleChange.split('>')[0];
        var altAllele = alleleChange.split('>')[1];
        if (altAllele.length > refAllele.length) {
            chrCoordinate = String(chrCoordinate) + '-' + String(chrCoordinate + altAllele.length - 1);
        } else {
            chrCoordinate = String(chrCoordinate);
        }
        if (oldObj.Pathogenicity_default == 'Not Yet Classified'){
            oldObj.Pathogenicity_default = "Uncertain";
        }
        if (oldObj.Pathogenicity_default == 'Benign / Little Clinical Significance'){
            oldObj.Pathogenicity_default = "Benign";
        }
        var newObj = {category: oldObj.Pathogenicity_default, coord: chrCoordinate, value: 1, oldData: obj};
        return newObj;
    },

     componentDidMount: function() {
        var {data, brcakey, onRowClick, ...opts} = this.props;
        var subSetData = data.map(this.filterAttributes);
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        var domainBRCA = JSON.parse(brca12JSON[brcakey].brcaDomainFile);
        this.cleanupBRCA = d3Lollipop.drawStuffWithD3(d3svgBrcaRef, subSetData, domainBRCA, brcakey, onRowClick);
    },

    componentWillReceiveProps: function(newProps) {
        this.cleanupBRCA();
        var {data, brcakey, onRowClick, ...opts} = newProps;
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        while (d3svgBrcaRef.hasChildNodes() ) {
            d3svgBrcaRef.removeChild(d3svgBrcaRef.lastChild);
        }
        var subSetData = data.map(this.filterAttributes);
        var d3svgBrcaRef = React.findDOMNode(this.refs.d3svgBrca);
        while (d3svgBrcaRef.hasChildNodes() ) {
            d3svgBrcaRef.removeChild(d3svgBrcaRef.lastChild);
        }
        var domainBRCA = JSON.parse(brca12JSON[brcakey].brcaDomainFile);
        this.cleanupBRCA = d3Lollipop.drawStuffWithD3(d3svgBrcaRef, subSetData, domainBRCA, brcakey, onRowClick);
    },
    componentWillUnmount: function() {
        this.cleanupBRCA();
    }
});

var Lollipop = React.createClass({
    mixins: [PureRenderMixin],
    getInitialState: function () {
        return {
            brcakey: "BRCA1",
            data: []
        };
    },
    componentWillReceiveProps: function (newProps) {
        this.fetchData(newProps.opts);
    },
    componentWillMount: function () {
        this.fetchData = _.debounce(this.fetchData, 600, true);
        this.fetchData(this.props.opts);
    },
    fetchData: function (opts) {
        this.props.fetch(opts).subscribe(
            function (d) {
                this.setState({data: d.data});
            }.bind(this));
    },
    onSelect: function (key) {
        this.setState({brcakey: key});
    },
    render: function () {
        return (
            <Grid>

                    <Row style={{marginBottom: '2px', marginTop: '2px'}}>

                            <NavItem eventKey="BRCA1">BRCA1</NavItem>
                            <NavItem eventKey="BRCA2">BRCA2</NavItem>

                         this.props.onHeaderClick('Lollipop Plots')}/>
                        <D3Lollipop data={this.state.data} opts={this.props.opts} key={this.state.brcakey} brcakey={this.state.brcakey} onRowClick={this.props.onRowClick} id='brcaLollipop' ref='d3svgBrca'/>
                    </Row>

            </Grid>
        );
    }
});

module.exports = Lollipop;
<|endoftext|>


<commit_before>'use strict'

const getTiming = require('timing_commonjs')
const post = require('./post')
const getPostion = require('./getPostion')
const getNav = require('./nav')

window.onload = () => {
  const ua = navigator.userAgent
  const timing = getTiming()
  const url = window.location.href
  const nav = getNav()

  navigator.geolocation.getCurrentPosition((postion) => {
    const ps = getPostion(postion)
    post({ua, timing, url, nav, ps})
  }, () => {
    post({ua, timing, url, nav})
  })
}
<commit_msg>:art:<commit_after>'use strict'

const getTiming = require('timing_commonjs')
const post = require('./post')
const getPostion = require('./getPostion')
const getNav = require('./nav')

window.onload = () => {
  const ua = navigator.userAgent
  const timing = getTiming()
  const url = window.location.href
  const nav = getNav()

  navigator.geolocation.getCurrentPosition((postion) => {
    const ps = getPostion(postion)
    post({ua, timing, url, nav, ps})
  }, () => {
    post({ua, timing, url, nav})
  })
}
<|endoftext|>


<commit_before>define(["js/data/Entity", "js/core/List", "flow", "underscore"], function (Entity, List, flow, _) {

    var FETCHSTATE = {
        CREATED: 0,
        LOADING: 1,
        LOADED: 2,
        ERROR: -1
    };

    var STATE = {
        NEW: 0,
        CREATED: 1,
        DELETED: -1
    };

    var Model = Entity.inherit("js.data.Model", {

        ctor: function (attributes) {

            // stores the current fetch state
            this._fetch = {
                callbacks: [],
                state: FETCHSTATE.CREATED
            };

            this.callBase(attributes);
        },

        schema: {
            href: {
                type: String,
                generated: true,
                required: false,
                includeInIndex: true
            }
        },

        hrefField: "href",          // contains the href to the resource
        updatedField: "updated",    // saves/returns the updated date
        createdField: "created",    // saves/returns the created date

        $isEntity: false,
        $isDependentObject: false,

        /***
         *
         * persistent the model over the data-source in which it was created
         *
         * @param options
         * @param callback
         */
        save: function (options, callback) {

            options = options || {};
            _.defaults(options, {
                invalidatePageCache: false
            });

            // TODO: handle multiple access
            try {
                var status = this._status();
                var self = this;
                if (status === STATE.NEW || status === STATE.CREATED) {
                    this.$context.$dataSource.saveModel(this, options, function(err){
                        if(!err && self.$collection && options.invalidatePageCache) {
                            self.$collection.invalidatePageCache();
                        }
                        callback && callback(err, self, options);
                    });
                } else {
                    throw new Error("status '" + status + "' doesn't allow save");
                }
            } catch(e) {
                if (callback) {
                    callback(e);
                }
            }

        },
        /***
         *
         * @param options
         * @param callback
         */
        validateAndSave: function (options, callback) {
            var self = this;

            flow()
                .seq(function (cb) {
                    self.validate(options, cb);
                })
                .seq(function (cb) {
                    if (self.isValid()) {
                        self.save(options, cb);
                    } else {
                        cb("Model is not valid!");
                    }
                })
                .exec(function (err) {
                    callback(err, self);
                });
        },

        getCollection: function (key) {
            var schemaDefinition = this.schema[key];
            if (!schemaDefinition) {
                throw "Couldn't find '" + key + "' in schema";
            }
            var collection = this.get(key);
            if (!collection) {
                var context = this.getContextForChild(schemaDefinition.type);
                if (context) {
                    collection = context.createCollection(schemaDefinition.type, null);
                    collection.$parent = this;
                    this.set(key, collection);
                } else {
                    throw "Couldn't determine context for " + key;
                }
            }
            return collection;

        },

        prepare: function (attributes, action) {
            attributes = this.callBase();

            if (action === "create") {
                // remove id
                delete(attributes.id);
            }

            return attributes;

        },

        /**
         * @param options
         * @param options.fetchSubModels
         * @param {Function} callback - function(err, model, options)
         */
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            if (this._fetch.state === FETCHSTATE.LOADING) {
                // currently fetching -> register callback
                this._fetch.callbacks.push(function (err, model) {
                    modelFetchedComplete(err, model, options, callback);
                });
            } else if (this._fetch.state == FETCHSTATE.LOADED) {
                // completed loaded -> execute
                modelFetchedComplete(null, this, options, callback);
            } else {
                // set state and start loading
                self._fetch.state = FETCHSTATE.LOADING;

                this.$context.$dataSource.loadModel(this, options, function (err, model) {
                    self._fetch.state = err ? FETCHSTATE.ERROR : FETCHSTATE.LOADED;

                    // execute callbacks
                    modelFetchedComplete.call(self, err, model, options, callback);

                    _.each(self._fetch.callbacks, function (cb) {
                        cb.call(self, err, model);
                    });

                });
            }
        },

        remove: function (options, callback) {
            // TODO: handle multiple access
            try {
                var status = this._status();
                var self = this;
                if (status === STATE.CREATED) {
                    this.$context.$dataSource.removeModel(this, options, function (err) {
                        if (!err) {
                            self.set('id', false);
                            if(self.$collection){
                                self.$collection.remove(self);
                            }
                        }
                        callback && callback(err);
                    });
                } else {
                    throw new Error("status '" + status + "' doesn't allow delete");
                }
            } catch(e) {
                callback && callback(e);
            }
        },

        validateSubEntity: function (entity, callback) {
            if (entity instanceof Model) {
                // does nothing :)
                callback();
            } else {
                this.callBase();
            }
        },

        _status: function () {
            if (this.identifier() === false) {
                return STATE.DELETED;
            } else {
                return this.identifier() ? STATE.CREATED : STATE.NEW;
            }
        }.onChange('id'),

        isNew: function () {
            return this._status() === STATE.NEW;
        }.onChange('id'),

        isCreated: function() {
            return this._status() === STATE.CREATED;
        }.onChange('id')

    });

    function fetchSubModels(attributes, subModelTypes, delegates) {
        _.each(attributes, function (value, key) {
            if (value instanceof Model || value instanceof require('js/data/Collection')) {
                // check if the model is required
                var subModelTypeEntry = subModelTypes[key];

                if (subModelTypeEntry) {
                    // model required -> create delegate
                    subModelTypeEntry.found = true;

                    delegates.push(function (cb) {
                        value.fetch({
                            fetchSubModels: subModelTypeEntry.subModels
                        }, cb);
                    });
                }
            } else if (value instanceof Object) {
                // TODO: causes in some cases an unfinity loop
                // fetchSubModels(value, subModelTypes, delegates);
            }
        });
    }

    function modelFetchedComplete(err, model, options, originalCallback) {

        var callback = function (err, model) {
            if (originalCallback) {
                originalCallback(err, model, options);
            }
        };

        if (err) {
            callback(err, model);
        } else {

            var delegates = [];

            if (options.fetchSubModels && options.fetchSubModels.length > 0) {

                // for example fetch an article with ["currency", "product/design", "product/productType"]
                var subModels = Model.createSubModelLoadingChain(model, options.fetchSubModels);

                fetchSubModels(model.$, subModels, delegates);

                // check that all subResources where found
                var missingSubModels = _.filter(subModels, function (subModel) {
                    return !subModel.found;
                });

                if (missingSubModels.length > 0) {
                    // TODO load again with fullData=true if not laoded with fullData=false
                    this.log(["requested submodel missing", missingSubModels], "warn");

                    callback("requested submodel missing", model);
                    return;
                }
            }

            // execute all delegates in parallel and then execute callback
            flow()
                .par(delegates)
                .exec(function (err) {
                    callback(err, model);
                });
        }
    }

    Model.createSubModelLoadingChain = function (model, subModels) {
        var ret = {};

        _.each(subModels, function (item) {
            if (item) {
                var parts = item.split("/");
                var subModelKey = parts.shift(), subModelEntry = ret[subModelKey] || {};
                ret[subModelKey] = subModelEntry;
                subModelEntry.found = false;
                subModelEntry.type = subModelKey;
                subModelEntry.subModels = [] || subModelEntry.subModels;
                if (parts.length > 0) {
                    subModelEntry.subModels.push(parts.join("/"));
                }
            }
        });

        return ret;
    };

    Model.STATE = STATE;
    Model.FETCHSTATE = FETCHSTATE;

    return Model;
});<commit_msg>added convertIdentifier method<commit_after>define(["js/data/Entity", "js/core/List", "flow", "underscore"], function (Entity, List, flow, _) {

    var FETCHSTATE = {
        CREATED: 0,
        LOADING: 1,
        LOADED: 2,
        ERROR: -1
    };

    var STATE = {
        NEW: 0,
        CREATED: 1,
        DELETED: -1
    };

    var Model = Entity.inherit("js.data.Model", {

        ctor: function (attributes) {

            // stores the current fetch state
            this._fetch = {
                callbacks: [],
                state: FETCHSTATE.CREATED
            };

            this.callBase(attributes);
        },

        schema: {
            href: {
                type: String,
                generated: true,
                required: false,
                includeInIndex: true
            }
        },

        hrefField: "href",          // contains the href to the resource
        updatedField: "updated",    // saves/returns the updated date
        createdField: "created",    // saves/returns the created date

        $isEntity: false,
        $isDependentObject: false,

        /***
         *
         * persistent the model over the data-source in which it was created
         *
         * @param options
         * @param callback
         */
        save: function (options, callback) {

            options = options || {};
            _.defaults(options, {
                invalidatePageCache: false
            });

            // TODO: handle multiple access
            try {
                var status = this._status();
                var self = this;
                if (status === STATE.NEW || status === STATE.CREATED) {
                    this.$context.$dataSource.saveModel(this, options, function(err){
                        if(!err && self.$collection && options.invalidatePageCache) {
                            self.$collection.invalidatePageCache();
                        }
                        callback && callback(err, self, options);
                    });
                } else {
                    throw new Error("status '" + status + "' doesn't allow save");
                }
            } catch(e) {
                if (callback) {
                    callback(e);
                }
            }

        },
        /***
         *
         * @param options
         * @param callback
         */
        validateAndSave: function (options, callback) {
            var self = this;

            flow()
                .seq(function (cb) {
                    self.validate(options, cb);
                })
                .seq(function (cb) {
                    if (self.isValid()) {
                        self.save(options, cb);
                    } else {
                        cb("Model is not valid!");
                    }
                })
                .exec(function (err) {
                    callback(err, self);
                });
        },

        getCollection: function (key) {
            var schemaDefinition = this.schema[key];
            if (!schemaDefinition) {
                throw "Couldn't find '" + key + "' in schema";
            }
            var collection = this.get(key);
            if (!collection) {
                var context = this.getContextForChild(schemaDefinition.type);
                if (context) {
                    collection = context.createCollection(schemaDefinition.type, null);
                    collection.$parent = this;
                    this.set(key, collection);
                } else {
                    throw "Couldn't determine context for " + key;
                }
            }
            return collection;

        },

        prepare: function (attributes, action) {
            attributes = this.callBase();

            if (action === "create") {
                // remove id
                delete(attributes.id);
            }

            return attributes;

        },

        /**
         * @param options
         * @param options.fetchSubModels
         * @param {Function} callback - function(err, model, options)
         */
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            if (this._fetch.state === FETCHSTATE.LOADING) {
                // currently fetching -> register callback
                this._fetch.callbacks.push(function (err, model) {
                    modelFetchedComplete(err, model, options, callback);
                });
            } else if (this._fetch.state == FETCHSTATE.LOADED) {
                // completed loaded -> execute
                modelFetchedComplete(null, this, options, callback);
            } else {
                // set state and start loading
                self._fetch.state = FETCHSTATE.LOADING;

                this.$context.$dataSource.loadModel(this, options, function (err, model) {
                    self._fetch.state = err ? FETCHSTATE.ERROR : FETCHSTATE.LOADED;

                    // execute callbacks
                    modelFetchedComplete.call(self, err, model, options, callback);

                    _.each(self._fetch.callbacks, function (cb) {
                        cb.call(self, err, model);
                    });

                });
            }
        },

        remove: function (options, callback) {
            // TODO: handle multiple access
            try {
                var status = this._status();
                var self = this;
                if (status === STATE.CREATED) {
                    this.$context.$dataSource.removeModel(this, options, function (err) {
                        if (!err) {
                            self.set('id', false);
                            if(self.$collection){
                                self.$collection.remove(self);
                            }
                        }
                        callback && callback(err);
                    });
                } else {
                    throw new Error("status '" + status + "' doesn't allow delete");
                }
            } catch(e) {
                callback && callback(e);
            }
        },

        validateSubEntity: function (entity, callback) {
            if (entity instanceof Model) {
                // does nothing :)
                callback();
            } else {
                this.callBase();
            }
        },

        _status: function () {
            if (this.identifier() === false) {
                return STATE.DELETED;
            } else {
                return this.identifier() ? STATE.CREATED : STATE.NEW;
            }
        }.onChange('id'),

        isNew: function () {
            return this._status() === STATE.NEW;
        }.onChange('id'),

        isCreated: function() {
            return this._status() === STATE.CREATED;
        }.onChange('id'),

        /**
         * Converts the identifier to the given type in the schema
         * @param identifier
         * @return {*}
         */
        convertIdentifier: function (identifier) {
            var idField = this.idField;
            if (this.schema.hasOwnProperty(idField)) {
                var schemaObject = this.schema[idField];
                if (schemaObject.type && schemaObject.type === Number) {
                    return parseInt(identifier);
                }
            }
            return identifier;
        }
    });

    function fetchSubModels(attributes, subModelTypes, delegates) {
        _.each(attributes, function (value, key) {
            if (value instanceof Model || value instanceof require('js/data/Collection')) {
                // check if the model is required
                var subModelTypeEntry = subModelTypes[key];

                if (subModelTypeEntry) {
                    // model required -> create delegate
                    subModelTypeEntry.found = true;

                    delegates.push(function (cb) {
                        value.fetch({
                            fetchSubModels: subModelTypeEntry.subModels
                        }, cb);
                    });
                }
            } else if (value instanceof Object) {
                // TODO: causes in some cases an unfinity loop
                // fetchSubModels(value, subModelTypes, delegates);
            }
        });
    }

    function modelFetchedComplete(err, model, options, originalCallback) {

        var callback = function (err, model) {
            if (originalCallback) {
                originalCallback(err, model, options);
            }
        };

        if (err) {
            callback(err, model);
        } else {

            var delegates = [];

            if (options.fetchSubModels && options.fetchSubModels.length > 0) {

                // for example fetch an article with ["currency", "product/design", "product/productType"]
                var subModels = Model.createSubModelLoadingChain(model, options.fetchSubModels);

                fetchSubModels(model.$, subModels, delegates);

                // check that all subResources where found
                var missingSubModels = _.filter(subModels, function (subModel) {
                    return !subModel.found;
                });

                if (missingSubModels.length > 0) {
                    // TODO load again with fullData=true if not laoded with fullData=false
                    this.log(["requested submodel missing", missingSubModels], "warn");

                    callback("requested submodel missing", model);
                    return;
                }
            }

            // execute all delegates in parallel and then execute callback
            flow()
                .par(delegates)
                .exec(function (err) {
                    callback(err, model);
                });
        }
    }

    Model.createSubModelLoadingChain = function (model, subModels) {
        var ret = {};

        _.each(subModels, function (item) {
            if (item) {
                var parts = item.split("/");
                var subModelKey = parts.shift(), subModelEntry = ret[subModelKey] || {};
                ret[subModelKey] = subModelEntry;
                subModelEntry.found = false;
                subModelEntry.type = subModelKey;
                subModelEntry.subModels = [] || subModelEntry.subModels;
                if (parts.length > 0) {
                    subModelEntry.subModels.push(parts.join("/"));
                }
            }
        });

        return ret;
    };

    Model.STATE = STATE;
    Model.FETCHSTATE = FETCHSTATE;

    return Model;
});<|endoftext|>


<commit_before>$(document).ready(function () {
	(function() {
        var link = document.createElement('link');
        link.type = 'image/x-icon';
        link.rel = 'shortcut icon';
        link.href = '/images/favicon.ico';
        document.getElementsByTagName('head')[0].appendChild(link);
    }());

	$('#fullpage').fullpage({
		anchors: pages,
		loopBottom: true,
		loopHorizontal: true,
		menu: '#overlay',
		resize: false,
		afterLoad: function(anchorLink, index) {
			for (var i=0; i<pages.length; i++) {
				var page = pages[i];
				console.log(page, anchorLink);
				if (anchorLink === page) {
					// document.location.hash = page;
					if (page === '#') {
						var selector = '#home'
					} else {
						var selector = "a[href$=" + '"' + page + '"' + "]";
					}
					console.log(selector);
					currentPage = selector;
					$(selector).addClass('hover');
				}
			}
		},
		onLeave: function(index, nextIndex) {
			$(currentPage).removeClass('hover');
		}
	});

	$.fn.fullpage.setScrollingSpeed(500);
});

var pages = ['#', 'about', 'mpr', 'gp', 'lovers', 'fashion', 'everyday', 'video'];

var currentPage;<commit_msg>trying to fix nav header bug<commit_after>$(document).ready(function () {
	(function() {
        var link = document.createElement('link');
        link.type = 'image/x-icon';
        link.rel = 'shortcut icon';
        link.href = '/images/favicon.ico';
        document.getElementsByTagName('head')[0].appendChild(link);
    }());

	$('#fullpage').fullpage({
		anchors: pages,
		loopBottom: true,
		loopHorizontal: true,
		menu: '#overlay',
		resize: false,
		afterLoad: function(anchorLink, index) {
			for (var i=0; i<pages.length; i++) {
				var page = pages[i];
				console.log(page, anchorLink);
				if (anchorLink === page) {
					// document.location.hash = page;
					if (page === '#') {
						var selector = '#home'
					} else if (page === 'mpr' || page === 'gp') {
						// var selector = "a[href$=" + '"' + page + '"' + "]" + ', a[href=$"news"]';
					} else {
						var selector = "a[href$=" + '"' + page + '"' + "]";
					}
					console.log(selector);
					currentPage = selector;
					$(selector).addClass('hover');
				}
			}
		},
		onLeave: function(index, nextIndex) {
			$(currentPage).removeClass('hover');
		}
	});

	$.fn.fullpage.setScrollingSpeed(500);
});

var pages = ['#', 'about', 'mpr', 'gp', 'lovers', 'fashion', 'everyday', 'video'];

var currentPage;<|endoftext|>