<commit_before>// Began with a copy-and-paste from:
//   http://www.html5rocks.com/en/tutorials/getusermedia/intro/
//   https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas

if (typeof YAJT === 'undefined') {
    YAJT = {};
}

YAJT.core = {
    config: {
        selector: '#yajt',
        input_class: 'input',
        output_class: 'output',
        width: 200,
        height: 150,
        timeout: 500, // 0.5 seconds
        transforms: [],
        threshold: 128
    },
    timer_callback: function () {
        if (this.video.paused || this.video.ended) {
            return;
        }
        image_data = this.compute_image_data();
        console.log(YAJT.dimension_reduction.from_top(image_data));

        var self = this;
        setTimeout(function () {
            self.timer_callback();
        }, this.config.timeout);
    },
    init: function (options) {
        for (var key in options) {
            this.config[key] = options[key];
        }
        var w_h = {
            width: this.config.width,
            height: this.config.height
        };
        var selector = this.config.selector;
        var input_class = this.config.input_class;
        var output_class = this.config.output_class;

        $(selector)
                .append($('<video autoplay>').attr(w_h).hide())
                .append($('<canvas class="' + input_class + '">').attr(w_h).hide())
                .append($('<canvas class="' + output_class + '">').attr(w_h));
        this.video = $(selector + ' video')[0];
        this.input = $(selector + ' .' + input_class)[0].getContext('2d');
        this.output = $(selector + ' .' + output_class)[0].getContext('2d');

        var self = this;
        var video_obj = {'video': true},
        error_handler = function (error) {
            console.log('Video capture error: ', error.code);
        };
        if (navigator.getUserMedia) { // Standard
            navigator.getUserMedia(video_obj, function (stream) {
                self.video.src = stream;
                self.video.play();
            }, error_handler);
        } else if (navigator.webkitGetUserMedia) { // WebKit
            navigator.webkitGetUserMedia(video_obj, function (stream) {
                self.video.src = window.webkitURL.createObjectURL(stream);
                self.video.play();
            }, error_handler);
        } else if (navigator.mozGetUserMedia) { // Firefox
            navigator.mozGetUserMedia(video_obj, function (stream) {
                self.video.src = window.URL.createObjectURL(stream);
                self.video.play();
            }, error_handler);
        }

        this.video.addEventListener('play', function () {
            self.timer_callback();
        }, false);
    },
    compute_image_data: function () {
        this.input.drawImage(this.video, 0, 0, this.config.width, this.config.height);
        var image_data = this.input.getImageData(0, 0, this.config.width, this.config.height);
        ;
        var transforms = this.config.transforms;
        for (var i = 0; i < transforms.length; i++) {
            transforms[i](image_data.data);
        }
        this.output.putImageData(image_data, 0, 0);
        return image_data.data;
    }
};<commit_msg>Things are starting to get interesting: red line over image.<commit_after>// Began with a copy-and-paste from:
//   http://www.html5rocks.com/en/tutorials/getusermedia/intro/
//   https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas

if (typeof YAJT === 'undefined') {
    YAJT = {};
}

YAJT.core = {
    config: {
        selector: '#yajt',
        input_class: 'input',
        output_class: 'output',
        width: 200,
        height: 150,
        timeout: 500, // 0.5 seconds
        transforms: [],
        threshold: 32
    },
    timer_callback: function () {
        if (this.video.paused || this.video.ended) {
            return;
        }
        var image_data = this.compute_image_data();
        var reduction = YAJT.dimension_reduction.from_top(image_data);
        this.draw_graph(reduction);

        var self = this;
        setTimeout(function () {
            self.timer_callback();
        }, this.config.timeout);
    },
    init: function (options) {
        for (var key in options) {
            this.config[key] = options[key];
        }
        var w_h = {
            width: this.config.width,
            height: this.config.height
        };
        var selector = this.config.selector;
        var input_class = this.config.input_class;
        var output_class = this.config.output_class;

        $(selector)
                .append($('<video autoplay>').attr(w_h).hide())
                .append($('<canvas class="' + input_class + '">').attr(w_h).hide())
                .append($('<canvas class="' + output_class + '">').attr(w_h));
        this.video = $(selector + ' video')[0];
        this.input = $(selector + ' .' + input_class)[0].getContext('2d');
        this.output = $(selector + ' .' + output_class)[0].getContext('2d');

        var self = this;
        var video_obj = {'video': true},
        error_handler = function (error) {
            console.log('Video capture error: ', error.code);
        };
        if (navigator.getUserMedia) { // Standard
            navigator.getUserMedia(video_obj, function (stream) {
                self.video.src = stream;
                self.video.play();
            }, error_handler);
        } else if (navigator.webkitGetUserMedia) { // WebKit
            navigator.webkitGetUserMedia(video_obj, function (stream) {
                self.video.src = window.webkitURL.createObjectURL(stream);
                self.video.play();
            }, error_handler);
        } else if (navigator.mozGetUserMedia) { // Firefox
            navigator.mozGetUserMedia(video_obj, function (stream) {
                self.video.src = window.URL.createObjectURL(stream);
                self.video.play();
            }, error_handler);
        }

        this.video.addEventListener('play', function () {
            self.timer_callback();
        }, false);
    },
    compute_image_data: function () {
        this.input.drawImage(this.video, 0, 0, this.config.width, this.config.height);
        var image_data = this.input.getImageData(0, 0, this.config.width, this.config.height);
        var transforms = this.config.transforms;
        for (var i = 0; i < transforms.length; i++) {
            transforms[i](image_data.data);
        }
        this.output.putImageData(image_data, 0, 0);
        return image_data.data;
    },
    draw_graph: function(array) {
        this.output.strokeStyle = '#F00';
        this.output.lineWidth = 3;
        this.output.beginPath();
        this.output.moveTo(2, array[0]);
        for (var i = 0; i < array.length; i++) {
            this.output.lineTo(i+2, array[i]);
        }
        this.output.stroke();
    }
};<|endoftext|>


<commit_before>import { createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  html {
    box-sizing: border-box;
  }
  *, *:before, *:after {
    box-sizing: inherit;
  }
  body {
    position: relative;
    box-sizing: border-box;
    overflow-y: hidden;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
    font-family: 'Roboto', Arial, Helvetica, sans-serif;
    font-size: 13px;
  }
`

export default GlobalStyle
<commit_msg>style: minor style fixes<commit_after>import { createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  html {
    box-sizing: border-box;
  }
  *, *:before, *:after {
    box-sizing: inherit;
  }
  body {
    position: relative;
    overflow-y: hidden;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
    font-family: 'Roboto', Arial, Helvetica, sans-serif;
    font-size: 13px;
  }
`

export default GlobalStyle
<|endoftext|>


<commit_before>function(doc) {

    if (doc.doc_type !== "Tender") {return;}
    function get_eu_tender_bids(tender) {
        var qualified_bids = (tender.qualifications || []).map(function(qualification) {
            return qualification.bidID;
        });
        return (tender.bids || []).filter(function(bid) {
            return (qualified_bids.indexOf(bid.id) !== -1);
        });
    };

    function find_matched_revs(revisions, pattern) {
      return revisions.filter(function(rev) {
          var changes = rev['changes'].filter(function(change) {
             return (change['path'].indexOf(pattern) !== -1);
          });
          return (changes.length !== 0);
      });
    }

    function find_initial_bid_date(revisions, bid_index, bid_id) {
      var revs = find_matched_revs(revisions, '/bids/' + bid_index);
      if (revs.length !== 0){
        return revs[0]['date'];
      } else {
        var revs = find_matched_revs(revisions, '/bids');
        return revs[0]['date'];
      }
    }

    function filter_bids(bids) {
        var min_date =  Date.parse("2016-04-01T00:00:00+03:00");
        return bids.filter(function(bid) {
            var bid_date =  Date.parse(bid.date);
            return (((bid.status || "invalid") === "active") && (+bid_date > +min_date));
        });
    };

    function find_first_revision_date(doc) {
        if ((typeof doc.revisions === 'undefined') || (doc.revisions.length === 0)) {
            return '';
        }
        return doc.revisions[0].date || '';
    }

    var startDate = (doc.enquiryPeriod||{}).startDate;
    if (!startDate) {
        startDate = find_first_revision_date(doc);
    }

    if (doc.procurementMethod !== "open") {return;}
    if ((doc.mode || "") === "test") { return;}

    var bids_disclojure_date = (doc.qualificationPeriod || {}).startDate || (doc.awardPeriod || {}).startDate || null;
    if(!bids_disclojure_date) { return; }

    // payments should be calculated only from first stage of CD and only once
    if (['competitiveDialogueEU.stage2', 'competitiveDialogueUA.stage2'].indexOf(doc.procurementMethodType) !== -1) {
        log('Skipping tender stage2 ' + doc._id)
        return;
    }

    var id = doc._id;
    var tender_start_date = doc.tenderPeriod.startDate;
    var tenderID = doc.tenderID;
    var is_multilot = ( "lots" in doc )?true:false;
    var type = doc.procurementMethodType;

    function max_date(obj) {
        //helper function to find max date in object
        var dates = [];

        ['date', 'dateSigned', 'documents'].forEach(function(field){
            var date = obj[field] || '';
            if (date) {
                if (typeof date === "object") {
                    date.forEach(function(d) {
                        dates.push(new Date(d.datePublished));
                    });
                } else {
                    dates.push(new Date(date));
                }
            }
        });
        return new Date(Math.max.apply(null, dates));
    };

    function date_normalize(date) {
        //return date in UTC format
        var ddate = '';
        if (typeof date !== 'object') {
            ddate = new Date(date);
        } else {
            ddate = date;
        }
        return ddate.toISOString().slice(0, 23);
    };

    function find_bid_by_lot(id) {
        results = [];
        bids.forEach(function(bid) {
            bid.lotValues.forEach(function(value) {
                if ((value.relatedLot === id) && ((["invalid"].indexOf(value.status || "active") === -1))) {
                    results.push(bid);
                }
            });
        });
        return results;
    };

    function get_bids(tender) {
        switch (tender.procurementMethodType) {
            case 'aboveThresholdEU':
            case 'competitiveDialogueEU':
            case 'competitiveDialogueUA':
                return get_eu_tender_bids(tender);
            default:
                return filter_bids(tender.bids || []);
        }
    }

    function count_lot_bids(lot, tender) {
        var bids = get_bids(tender);
        return bids.map(function(bid) {
            return ( bid.lotValues || [] ).filter(function(value) {
                return value.relatedLot === lot.id;
            }).length;
        }).reduce(function( total, curr) {
            return total + curr;
        }, 0);
    };

     function count_lot_qualifications(qualifications, lot_id) {
        if ( (typeof qualifications === 'undefined') || (qualifications.length === 0) ) {
            return 0;
        }
        return qualifications.filter(function(qualification) {
            return qualification.lotID === lot_id;
        }).length;
    }

    function check_tender_bids(tender) {
        var type = tender.procurementMethodType;
        switch (type) {
            case 'aboveThresholdUA':
                if (tender.numberOfBids < 2) {
                    return false;
                }
                return true;

                break;
            case 'aboveThresholdEU':
                if ((tender.qualifications || []).length < 2) {
                    return false;
                }
                return true;
                break;
            case 'aboveThresholdUA.defense':
                if ((tender.numberOfBids < 2) && !('awards' in tender)) {
                    return false;
                }
                return true;
                break;
            case 'competitiveDialogueEU':
            case 'competitiveDialogueUA':
                if ((tender.qualifications || []).length < 3) {
                    return false;
                }
                return true;
                break;
            default:
                return true;
        }
    }

    function check_lot_bids(tender, lot) {
        var type = tender.procurementMethodType;
        switch (type) {
        case 'aboveThresholdUA':
            if (count_lot_bids(lot, tender) < 2) {
                return false;
            }
            return true;
            break;
        case 'aboveThresholdEU':
            if (count_lot_qualifications(tender.qualifications, lot.id) < 2) {
                return false;
            }
            return true;
            break;
        case 'aboveThresholdUA.defense':
            var lot_awards = ('awards' in tender) ? (
                tender.awards.filter(function(a) {
                    return a.lotID === lot.id;
                })
            ) : [];
            if (((count_lot_bids(lot, tender) < 2) && (lot_awards.length === 0))) {
                return false;
            }
            return true;
            break;
        case 'competitiveDialogueEU':
        case 'competitiveDialogueUA':
            if (count_lot_qualifications(tender.qualifications, lot.id) < 3) {
                return false;
            }
            return true;
            break;
        default:
            return true;
        }
    }

    function check_tender(tender) {
        switch(tender.status) {
        case "cancelled":
            if ('date' in tender) {
                if ((new Date(tender.date)) < (new Date(bids_disclojure_date))) {
                    return false;
                }

            } else {
                var tender_cancellations = ( tender.cancellations || [] ).filter(function(cancellation) {
                    return (cancellation.status === 'active') && (cancellation.cancellationOf === 'tender');
                });
                if (tender_cancellations.length === 0) {
                    return false;
                }
                if (tender_cancellations.length > 1) {
                    cancel = tender_cancellations.reduce(function(prev_doc, curr_doc) {
                        return (max_date( prev_doc ) > max_date( curr_doc ))? curr_doc : prev_doc;
                    });

                    if (max_date( cancel ) < (new Date( bids_disclojure_date ))) {
                        return false;
                    }
                } else {
                    if (max_date( tender_cancellations[0] ) < (new Date( bids_disclojure_date ))) {
                        return false;
                    }
                }

            }
            if (! check_tender_bids(tender)) {
                return false;
            }
            return true;
        case "unsuccessful":
            if (! check_tender_bids(tender)) {
                return false;
            }
            return true;
        default:
            return true;
        }
    }

    function check_lot(tender, lot){
        switch (lot.status) {
        case "cancelled":
            if ('date' in lot) {
                if ((new Date(lot.date)) < (new Date(bids_disclojure_date))) {
                    return false;
                }
            } else {
                lot_cancellation = (tender.cancellations || []).filter(function(cancellation) {
                    if ((cancellation.status === 'active') && (cancellation.cancellationOf === 'lot') && (cancellation.relatedLot === lot.id)) {
                        return true;
                    }
                });
                if (lot_cancellation.length > 0) {
                    if (lot_cancellation.length > 1) {
                        cancel = lot_cancellation.reduce(function(prev_doc, curr_doc) {
                            return (max_date(prev_doc) > max_date(curr_doc)) ? curr_doc : prev_doc;
                        });

                        if (max_date(cancel) < (new Date(bids_disclojure_date))) {
                            return false;
                        }
                    } else {
                        if (max_date(lot_cancellation[0]) < (new Date(bids_disclojure_date))) {
                            return false;
                        }
                    }

                }
            }
            if (! check_lot_bids(tender, lot)) {
                return false;
            }

            return true;
        case "unsuccessful":
            if (! check_lot_bids(tender, lot)) {
                return false;
            }
            return true;
        default:
            return true;
        }
    };

    var emitter = {
        lot: function(owner, date, bid, lot, audits, init_date) {
            emit([owner, date, bid.id, lot.id], {
                tender: id,
                lot: lot.id,
                value: lot.value.amount,
                currency: lot.value.currency,
                bid: bid.id,
                startdate: startDate,
                audits: audits,
                tender_start_date: tender_start_date,
                tenderID: tenderID,
                initialDate: init_date
            });
        },
        tender: function(owner, date, bid, tender, audits){
            emit([owner, date, bid.id], {
                tender: id,
                value: tender.value.amount,
                currency: tender.value.currency,
                bid: bid.id,
                audits: audits,
                startdate: startDate,
                tender_start_date: tender_start_date,
                tenderID: tenderID,
                initialDate: init_date
            });
        }
    };

    function emit_results(tender) {

        var bids = get_bids(tender);
        if ("bids" in tender) {
            if(is_multilot) {
                (bids || []).forEach(function(bid) {
                    var init_date = find_initial_bid_date(tender.revisions, tender.bids.indexOf(bid), bid.id);
                    bid.lotValues.forEach(function(value) {
                        tender.lots.forEach(function(lot) {
                            if (check_lot(tender, lot)) {
                                if (value.relatedLot === lot.id) {
                                    var audits = (tender.documents || []).filter(function(tender_doc) {
                                        return tender_doc.title.indexOf("audit_" + id + "_" + lot.id) === 0;
                                    });
                                    var audit = '';
                                    if (audits.length > 1) {
                                        audit = audits.reduce(function(prev_doc, curr_doc) {
                                            return (prev_doc.dateModified > curr_doc.dateModified) ? curr_doc : prev_doc;
                                        });
                                    } else {
                                        audit = audits[0] || null;
                                    }
                                    emitter.lot(bid.owner, date_normalize(bids_disclojure_date), bid, lot, audit, init_date);
                                }
                            }
                        });
                    });
                });
            } else {
                if (!(check_tender(tender))) { return; }
                var audits = (tender.documents || []).filter(function(tender_doc) {
                    return tender_doc.title.match(/audit/);
                });
                var audit = '';
                if (audits.length > 1) {
                    audit = audits.reduce(function(prev_doc, curr_doc) {
                        return (prev_doc.dateModified > curr_doc.dateModified) ? curr_doc : prev_doc;
                    });
                } else {
                    audit = audits[0] || null;
                }
                (bids || []).forEach(function(bid) {
                    var init_date = find_initial_bid_date(tender.revisions, tender.bids.indexOf(bid), bid.id);
                    emitter.tender(bid.owner, date_normalize(bids_disclojure_date), bid, tender, audit, init_date);
                });
            }

        }
    };

    emit_results(doc);
}
<commit_msg>Fix error when initial date is undefined<commit_after>function(doc) {

    if (doc.doc_type !== "Tender") {return;}
    function get_eu_tender_bids(tender) {
        var qualified_bids = (tender.qualifications || []).map(function(qualification) {
            return qualification.bidID;
        });
        return (tender.bids || []).filter(function(bid) {
            return (qualified_bids.indexOf(bid.id) !== -1);
        });
    };

    function find_matched_revs(revisions, pattern) {
      return revisions.filter(function(rev) {
          var changes = rev['changes'].filter(function(change) {
             return (change['path'].indexOf(pattern) !== -1);
          });
          return (changes.length !== 0);
      });
    }

    function find_initial_bid_date(revisions, bid_index, bid_id) {
      var revs = find_matched_revs(revisions, '/bids/' + bid_index);
      if (revs.length !== 0){
        return revs[0]['date'] || '';
      } else {
        var revs = find_matched_revs(revisions, '/bids');
        return revs[0]['date'] || '';
      }
    }

    function filter_bids(bids) {
        var min_date =  Date.parse("2016-04-01T00:00:00+03:00");
        return bids.filter(function(bid) {
            var bid_date =  Date.parse(bid.date);
            return (((bid.status || "invalid") === "active") && (+bid_date > +min_date));
        });
    };

    function find_first_revision_date(doc) {
        if ((typeof doc.revisions === 'undefined') || (doc.revisions.length === 0)) {
            return '';
        }
        return doc.revisions[0].date || '';
    }

    var startDate = (doc.enquiryPeriod||{}).startDate;
    if (!startDate) {
        startDate = find_first_revision_date(doc);
    }

    if (doc.procurementMethod !== "open") {return;}
    if ((doc.mode || "") === "test") { return;}

    var bids_disclojure_date = (doc.qualificationPeriod || {}).startDate || (doc.awardPeriod || {}).startDate || null;
    if(!bids_disclojure_date) { return; }

    // payments should be calculated only from first stage of CD and only once
    if (['competitiveDialogueEU.stage2', 'competitiveDialogueUA.stage2'].indexOf(doc.procurementMethodType) !== -1) {
        log('Skipping tender stage2 ' + doc._id)
        return;
    }

    var id = doc._id;
    var tender_start_date = doc.tenderPeriod.startDate;
    var tenderID = doc.tenderID;
    var is_multilot = ( "lots" in doc )?true:false;
    var type = doc.procurementMethodType;

    function max_date(obj) {
        //helper function to find max date in object
        var dates = [];

        ['date', 'dateSigned', 'documents'].forEach(function(field){
            var date = obj[field] || '';
            if (date) {
                if (typeof date === "object") {
                    date.forEach(function(d) {
                        dates.push(new Date(d.datePublished));
                    });
                } else {
                    dates.push(new Date(date));
                }
            }
        });
        return new Date(Math.max.apply(null, dates));
    };

    function date_normalize(date) {
        //return date in UTC format
        var ddate = '';
        if (typeof date !== 'object') {
            ddate = new Date(date);
        } else {
            ddate = date;
        }
        return ddate.toISOString().slice(0, 23);
    };

    function find_bid_by_lot(id) {
        results = [];
        bids.forEach(function(bid) {
            bid.lotValues.forEach(function(value) {
                if ((value.relatedLot === id) && ((["invalid"].indexOf(value.status || "active") === -1))) {
                    results.push(bid);
                }
            });
        });
        return results;
    };

    function get_bids(tender) {
        switch (tender.procurementMethodType) {
            case 'aboveThresholdEU':
            case 'competitiveDialogueEU':
            case 'competitiveDialogueUA':
                return get_eu_tender_bids(tender);
            default:
                return filter_bids(tender.bids || []);
        }
    }

    function count_lot_bids(lot, tender) {
        var bids = get_bids(tender);
        return bids.map(function(bid) {
            return ( bid.lotValues || [] ).filter(function(value) {
                return value.relatedLot === lot.id;
            }).length;
        }).reduce(function( total, curr) {
            return total + curr;
        }, 0);
    };

     function count_lot_qualifications(qualifications, lot_id) {
        if ( (typeof qualifications === 'undefined') || (qualifications.length === 0) ) {
            return 0;
        }
        return qualifications.filter(function(qualification) {
            return qualification.lotID === lot_id;
        }).length;
    }

    function check_tender_bids(tender) {
        var type = tender.procurementMethodType;
        switch (type) {
            case 'aboveThresholdUA':
                if (tender.numberOfBids < 2) {
                    return false;
                }
                return true;

                break;
            case 'aboveThresholdEU':
                if ((tender.qualifications || []).length < 2) {
                    return false;
                }
                return true;
                break;
            case 'aboveThresholdUA.defense':
                if ((tender.numberOfBids < 2) && !('awards' in tender)) {
                    return false;
                }
                return true;
                break;
            case 'competitiveDialogueEU':
            case 'competitiveDialogueUA':
                if ((tender.qualifications || []).length < 3) {
                    return false;
                }
                return true;
                break;
            default:
                return true;
        }
    }

    function check_lot_bids(tender, lot) {
        var type = tender.procurementMethodType;
        switch (type) {
        case 'aboveThresholdUA':
            if (count_lot_bids(lot, tender) < 2) {
                return false;
            }
            return true;
            break;
        case 'aboveThresholdEU':
            if (count_lot_qualifications(tender.qualifications, lot.id) < 2) {
                return false;
            }
            return true;
            break;
        case 'aboveThresholdUA.defense':
            var lot_awards = ('awards' in tender) ? (
                tender.awards.filter(function(a) {
                    return a.lotID === lot.id;
                })
            ) : [];
            if (((count_lot_bids(lot, tender) < 2) && (lot_awards.length === 0))) {
                return false;
            }
            return true;
            break;
        case 'competitiveDialogueEU':
        case 'competitiveDialogueUA':
            if (count_lot_qualifications(tender.qualifications, lot.id) < 3) {
                return false;
            }
            return true;
            break;
        default:
            return true;
        }
    }

    function check_tender(tender) {
        switch(tender.status) {
        case "cancelled":
            if ('date' in tender) {
                if ((new Date(tender.date)) < (new Date(bids_disclojure_date))) {
                    return false;
                }

            } else {
                var tender_cancellations = ( tender.cancellations || [] ).filter(function(cancellation) {
                    return (cancellation.status === 'active') && (cancellation.cancellationOf === 'tender');
                });
                if (tender_cancellations.length === 0) {
                    return false;
                }
                if (tender_cancellations.length > 1) {
                    cancel = tender_cancellations.reduce(function(prev_doc, curr_doc) {
                        return (max_date( prev_doc ) > max_date( curr_doc ))? curr_doc : prev_doc;
                    });

                    if (max_date( cancel ) < (new Date( bids_disclojure_date ))) {
                        return false;
                    }
                } else {
                    if (max_date( tender_cancellations[0] ) < (new Date( bids_disclojure_date ))) {
                        return false;
                    }
                }

            }
            if (! check_tender_bids(tender)) {
                return false;
            }
            return true;
        case "unsuccessful":
            if (! check_tender_bids(tender)) {
                return false;
            }
            return true;
        default:
            return true;
        }
    }

    function check_lot(tender, lot){
        switch (lot.status) {
        case "cancelled":
            if ('date' in lot) {
                if ((new Date(lot.date)) < (new Date(bids_disclojure_date))) {
                    return false;
                }
            } else {
                lot_cancellation = (tender.cancellations || []).filter(function(cancellation) {
                    if ((cancellation.status === 'active') && (cancellation.cancellationOf === 'lot') && (cancellation.relatedLot === lot.id)) {
                        return true;
                    }
                });
                if (lot_cancellation.length > 0) {
                    if (lot_cancellation.length > 1) {
                        cancel = lot_cancellation.reduce(function(prev_doc, curr_doc) {
                            return (max_date(prev_doc) > max_date(curr_doc)) ? curr_doc : prev_doc;
                        });

                        if (max_date(cancel) < (new Date(bids_disclojure_date))) {
                            return false;
                        }
                    } else {
                        if (max_date(lot_cancellation[0]) < (new Date(bids_disclojure_date))) {
                            return false;
                        }
                    }

                }
            }
            if (! check_lot_bids(tender, lot)) {
                return false;
            }

            return true;
        case "unsuccessful":
            if (! check_lot_bids(tender, lot)) {
                return false;
            }
            return true;
        default:
            return true;
        }
    };

    var emitter = {
        lot: function(owner, date, bid, lot, audits, init_date) {
            emit([owner, date, bid.id, lot.id], {
                tender: id,
                lot: lot.id,
                value: lot.value.amount,
                currency: lot.value.currency,
                bid: bid.id,
                startdate: startDate,
                audits: audits,
                tender_start_date: tender_start_date,
                tenderID: tenderID,
                initialDate: init_date
            });
        },
        tender: function(owner, date, bid, tender, audits, init_date){
            emit([owner, date, bid.id], {
                tender: id,
                value: tender.value.amount,
                currency: tender.value.currency,
                bid: bid.id,
                audits: audits,
                startdate: startDate,
                tender_start_date: tender_start_date,
                tenderID: tenderID,
                initialDate: init_date
            });
        }
    };

    function emit_results(tender) {

        var bids = get_bids(tender);
        if ("bids" in tender) {
            if(is_multilot) {
                (bids || []).forEach(function(bid) {
                    var init_date = find_initial_bid_date(tender.revisions || [], tender.bids.indexOf(bid), bid.id);
                    bid.lotValues.forEach(function(value) {
                        tender.lots.forEach(function(lot) {
                            if (check_lot(tender, lot)) {
                                if (value.relatedLot === lot.id) {
                                    var audits = (tender.documents || []).filter(function(tender_doc) {
                                        return tender_doc.title.indexOf("audit_" + id + "_" + lot.id) === 0;
                                    });
                                    var audit = '';
                                    if (audits.length > 1) {
                                        audit = audits.reduce(function(prev_doc, curr_doc) {
                                            return (prev_doc.dateModified > curr_doc.dateModified) ? curr_doc : prev_doc;
                                        });
                                    } else {
                                        audit = audits[0] || null;
                                    }
                                    emitter.lot(bid.owner, date_normalize(bids_disclojure_date), bid, lot, audit, init_date);
                                }
                            }
                        });
                    });
                });
            } else {
                if (!(check_tender(tender))) { return; }
                var audits = (tender.documents || []).filter(function(tender_doc) {
                    return tender_doc.title.match(/audit/);
                });
                var audit = '';
                if (audits.length > 1) {
                    audit = audits.reduce(function(prev_doc, curr_doc) {
                        return (prev_doc.dateModified > curr_doc.dateModified) ? curr_doc : prev_doc;
                    });
                } else {
                    audit = audits[0] || null;
                }
                (bids || []).forEach(function(bid) {
                    var init_date = find_initial_bid_date(tender.revisions, tender.bids.indexOf(bid), bid.id);
                    emitter.tender(bid.owner, date_normalize(bids_disclojure_date), bid, tender, audit, init_date);
                });
            }

        }
    };

    emit_results(doc);
}
<|endoftext|>


<commit_before>//PieChart extends Chart

GeoDash.PieChart = ezoop.ExtendedClass(GeoDash.Chart, {
  className: 'PieChart',
  defaults: {
    label: 'label',
    value: 'value',
    colors: ["#f00", "#0f0", "#00f"],
    innerRadius: 10,
    opacity: 1,
    drawX: true,
    drawY: true,
    title: false,
    padding: 10,
    legend: false
  },
  initialize: function (el, options) {

  },
  drawChart: function(){
    var self = this;

    this.width = (this.options.width === 'auto' || this.options.width === undefined ? parseInt(d3.select(this.el).style('width')) : this.options.width);
    this.height = (this.options.height === 'auto' || this.options.width === undefined ? parseInt(d3.select(this.el).style('height')) : this.options.height);
    this.width = this.width - this.options.padding*2;
    this.height = this.height - this.options.padding*2;
    if(this.options.title) {
      this.height  = this.height - 21;
    }

    this.radius = Math.min(this.width, this.height) / 2.2;

    this.color = d3.scale.ordinal()
      .range(this.options.colors);

    this.x = d3.scale.ordinal()
      .range([0, this.width-2]);

    this.y = d3.scale.linear()
      .range([this.height-2, 0]);

    this.xAxis = d3.svg.axis()
      .scale(this.x)
      .orient("bottom")
      .tickSize(10,0,0)
      .tickFormat(function(d){
        return '';
      });

    this.yAxis = d3.svg.axis()
      .scale(this.y)
      .orient("left")
      //.ticks(0)
      .tickSize(10, 0, 0)
      .tickFormat(function(d){
        return '';
      });

    this.arc = d3.svg.arc()
      .outerRadius(this.radius)
      .innerRadius(this.options.innerRadius);

    this.pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d[self.options.value]; });

    this.svg = d3.select(this.el).append("svg")
      .attr("width", this.width)
      .attr("height", this.height)
      .attr("class", "piechart-svg")
      .append("g")
        .attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")");

    if(this.options.drawX){
      this.svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + (this.width/2)*-1 + "," + 0 + ")")
        .call(this.xAxis);
      this.svg.select('.x.axis').selectAll(".tick")
        .attr("transform", "translate(0,-5)");
    }

    if(this.options.drawY){
      this.svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(" + 0 + "," + (this.height/2)*-1 + ")")
        .call(this.yAxis);
      this.svg.select('.y.axis').selectAll(".tick")
        .attr("transform", "translate(5,0)");
    }

    if(this.options.legend) {
      d3.select(this.options.legend).append('svg');
    }
  },
  update: function(data){
    var self = this;
    data.forEach(function(d) {
      d[self.options.value] = +d[self.options.value];
    });

    this.x.domain([0, 1]);
    this.y.domain([0, 1]);

    this.xAxis.tickValues([0, 1]);
    this.yAxis.tickValues([0, 1]);

    if(this.options.drawX){
      svg.select(".x.axis").transition()
        .call(this.xAxis);
    }

    if(this.options.drawY){
      svg.select(".y.axis").transition()
        .call(this.yAxis);
    }

    var g = this.svg.selectAll(".arc")
        .data(this.pie(data));

    g.select("path").transition().attr("d", this.arc);

    g.enter().append("g")
      .attr("class", "arc")
        .append("path")
        .attr("d", this.arc)
        .style("fill", function(d) { return self.color(d.data[self.options.label]); })
        .style("fill-opacity", this.options.opacity)
        .on('mouseover', function(d,i){
          d3.select(self.el).select('.hoverbox').html(d.value + '%');
          d3.select(this).style('fill-opacity', 1);
        })
        .on('mouseout', function(d,i){
          d3.select(self.el).select('.hoverbox').html('');
          d3.select(this).style('fill-opacity', self.options.opacity  );
        });

    if(this.options.legend) {
      var lWidth = parseInt(d3.select(this.options.legend).style('width'));
      var block = {width: 10, height: 10, padding: 5};
      var container = d3.select(this.options.legend).select('svg');
      var legend = container.selectAll(".legend-item")
          .data(this.color.domain().slice());

      legend.select(".legend-item").select("text").text(function(d) { return d; });

      var legenditem = legend.enter().append("g")
          .attr("class", "legend-item")
          .attr("transform", function(d, i) { return "translate(0," + i * (block.height + block.padding) + ")"; });

      legenditem.append("rect")
        .attr("x", 0)
        .attr("width", block.width)
        .attr("height", block.height)
        .style("fill", this.color);

      legenditem.append("text")
        .attr("x", (block.width + block.padding))
        .attr("y", 4)
        .attr("dy", ".35em")
        .style("text-anchor", "start")
        .text(function(d) { return d; });
    }
  }
});<commit_msg>hover option + hover formatting<commit_after>//PieChart extends Chart

GeoDash.PieChart = ezoop.ExtendedClass(GeoDash.Chart, {
  className: 'PieChart',
  defaults: {
    label: 'label',
    value: 'value',
    colors: ["#f00", "#0f0", "#00f"],
    innerRadius: 10,
    opacity: 1,
    drawX: true,
    drawY: true,
    title: false,
    padding: 10,
    legend: false,
    hover: false
  },
  initialize: function (el, options) {

  },
  drawChart: function(){
    var self = this;

    this.width = (this.options.width === 'auto' || this.options.width === undefined ? parseInt(d3.select(this.el).style('width')) : this.options.width);
    this.height = (this.options.height === 'auto' || this.options.width === undefined ? parseInt(d3.select(this.el).style('height')) : this.options.height);
    this.width = this.width - this.options.padding*2;
    this.height = this.height - this.options.padding*2;
    if(this.options.title) {
      this.height  = this.height - 21;
    }

    this.radius = Math.min(this.width, this.height) / 2.2;

    this.color = d3.scale.ordinal()
      .range(this.options.colors);

    this.x = d3.scale.ordinal()
      .range([0, this.width-2]);

    this.y = d3.scale.linear()
      .range([this.height-2, 0]);

    this.xAxis = d3.svg.axis()
      .scale(this.x)
      .orient("bottom")
      .tickSize(10,0,0)
      .tickFormat(function(d){
        return '';
      });

    this.yAxis = d3.svg.axis()
      .scale(this.y)
      .orient("left")
      //.ticks(0)
      .tickSize(10, 0, 0)
      .tickFormat(function(d){
        return '';
      });

    this.arc = d3.svg.arc()
      .outerRadius(this.radius)
      .innerRadius(this.options.innerRadius);

    this.pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d[self.options.value]; });

    this.formatHover = d3.format(',.0f');
    this.formatPercent = d3.format('.2f');

    this.svg = d3.select(this.el).append("svg")
      .attr("width", this.width)
      .attr("height", this.height)
      .attr("class", "piechart-svg")
      .append("g")
        .attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")");

    if(this.options.drawX){
      this.svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + (this.width/2)*-1 + "," + 0 + ")")
        .call(this.xAxis);
      this.svg.select('.x.axis').selectAll(".tick")
        .attr("transform", "translate(0,-5)");
    }

    if(this.options.drawY){
      this.svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(" + 0 + "," + (this.height/2)*-1 + ")")
        .call(this.yAxis);
      this.svg.select('.y.axis').selectAll(".tick")
        .attr("transform", "translate(5,0)");
    }

    if(this.options.legend) {
      d3.select(this.options.legend).append('svg');
    }
  },
  update: function(data){
    var self = this;
    self.total = 0;
    data.forEach(function(d) {
      d[self.options.value] = +d[self.options.value];
      self.total += +d[self.options.value];
    });

    this.x.domain([0, 1]);
    this.y.domain([0, 1]);

    this.xAxis.tickValues([0, 1]);
    this.yAxis.tickValues([0, 1]);

    if(this.options.drawX){
      svg.select(".x.axis").transition()
        .call(this.xAxis);
    }

    if(this.options.drawY){
      svg.select(".y.axis").transition()
        .call(this.yAxis);
    }

    var g = this.svg.selectAll(".arc")
        .data(this.pie(data));

    g.select("path").transition().attr("d", this.arc);

    g.enter().append("g")
      .attr("class", "arc")
        .append("path")
        .attr("d", this.arc)
        .style("fill", function(d) { return self.color(d.data[self.options.label]); })
        .style("fill-opacity", this.options.opacity)
        .on('mouseover', function(d,i){
          d3.select(this).style('fill-opacity', 1);
          if(self.options.hover) {
            var label = d.data[self.options.label];
            var total = self.formatHover(d.value);
            var percent = self.formatPercent((d.value/self.total)*100);
            d3.select(self.el).select('.hoverbox').html(label + ": " + total + ' (' + percent + '%)');
          }
        })
        .on('mouseout', function(d,i){
          d3.select(self.el).select('.hoverbox').html('');
          d3.select(this).style('fill-opacity', self.options.opacity  );
        });

    if(this.options.legend) {
      var lWidth = parseInt(d3.select(this.options.legend).style('width'));
      var block = {width: 10, height: 10, padding: 5};
      var container = d3.select(this.options.legend).select('svg');
      var legend = container.selectAll(".legend-item")
          .data(this.color.domain().slice());

      legend.select(".legend-item").select("text").text(function(d) { return d; });

      var legenditem = legend.enter().append("g")
          .attr("class", "legend-item")
          .attr("transform", function(d, i) { return "translate(0," + i * (block.height + block.padding) + ")"; });

      legenditem.append("rect")
        .attr("x", 0)
        .attr("width", block.width)
        .attr("height", block.height)
        .style("fill", this.color);

      legenditem.append("text")
        .attr("x", (block.width + block.padding))
        .attr("y", 4)
        .attr("dy", ".35em")
        .style("text-anchor", "start")
        .text(function(d) { return d; });
    }
  }
});<|endoftext|>


<commit_before>'use strict';

const { get } = require('lodash') ;
const ERROR_TEMPLATES = require('./errors');
const releaseMsg = require('./release');

module.exports = (config) => {
  return (releaseInfo, filterLabels) => {
    const user = get(config, 'github.user');
    const githubToSlakUsernames = get(config, 'slack.githubUsers');

    // TODO: add a config setting to notify only if there are filterred issues
    const attachments = releaseInfo.reduce((acc, repoInfo) => {
      if (isFailedReleaseAndFilteredChannel(repoInfo.failReason, filterLabels)) return acc;
      const attachment = repoInfo.failReason
        ? ERROR_TEMPLATES[repoInfo.failReason] || ERROR_TEMPLATES.UNkNOWN_ERROR
        : releaseMsg(repoInfo, filterLabels, user, githubToSlakUsernames);
      if (attachment) {
        attachment.title = repoInfo.repo;
        attachment.title_link = `https://github.com/${user}/${repoInfo.repo}`;
        acc.push(attachment);
      }
      return acc;
    }, []);

    if (attachments.length > 0) {
      return {
        attachments
      };
    }
  };

  function isFailedReleaseAndFilteredChannel(failReason, filterLabels) {
    return failReason && filterLabels && filterLabels.length > 0;
  }
};
<commit_msg>Fix the same bug for release templates<commit_after>'use strict';

const { get } = require('lodash') ;
const ERROR_TEMPLATES = require('./errors');
const releaseMsg = require('./release');

module.exports = (config) => {
  return (releaseInfo, filterLabels) => {
    const user = get(config, 'github.user');
    const githubToSlakUsernames = get(config, 'slack.githubUsers');

    // TODO: add a config setting to notify only if there are filterred issues
    const attachments = releaseInfo.reduce((acc, repoInfo) => {
      if (isFailedReleaseAndFilteredChannel(repoInfo.failReason, filterLabels)) return acc;
      const attachment = repoInfo.failReason
        ? ERROR_TEMPLATES[repoInfo.failReason] || ERROR_TEMPLATES.UNkNOWN_ERROR
        : releaseMsg(repoInfo, filterLabels, user, githubToSlakUsernames);
      if (attachment) {
        acc.push(Object.assign({}, attachment, {
          title: repoInfo.repo,
          title_link: `https://github.com/${user}/${repoInfo.repo}`
        }));
      }
      return acc;
    }, []);

    if (attachments.length > 0) {
      return {
        attachments
      };
    }
  };

  function isFailedReleaseAndFilteredChannel(failReason, filterLabels) {
    return failReason && filterLabels && filterLabels.length > 0;
  }
};
<|endoftext|>


<commit_before>import { decode as decodeJpegExif } from 'fast-jpeg';
import { decode as decodePng } from 'fast-png';
import imageType from 'image-type';
import { decode as decodeJpeg } from 'jpeg-js';
import { decode as decodeTiff } from 'tiff';

import Stack from '../../stack/Stack';
import { decode as base64Decode, toBase64URL } from '../../util/base64';
import Image from '../Image';
import { GREY, RGB } from '../model/model';

import { fetchBinary, DOMImage, createCanvas } from './environment';

const isDataURL = /^data:[a-z]+\/([a-z]+);base64,/;

/**
 * Load an image
 * @memberof Image
 * @static
 * @param {string|ArrayBuffer|Buffer|Uint8Array} image - URL of the image (browser, can be a dataURL) or path (Node.js)
 * or buffer containing the binary data
 * @param {object} [options] - In the browser, the options object is passed to the underlying `fetch` call.
 * @return {Promise<Image>}
 * @example
 * const image = await Image.load('https://example.com/image.png');
 */
export default function load(image, options) {
  if (typeof image === 'string') {
    return loadURL(image, options);
  } else if (image instanceof ArrayBuffer) {
    return Promise.resolve(loadBinary(new Uint8Array(image)));
  } else if (image.buffer) {
    return Promise.resolve(loadBinary(image));
  } else {
    throw new Error('argument to "load" must be a string or buffer.');
  }
}

function loadBinary(image, base64Url) {
  const type = imageType(image);
  if (type) {
    switch (type.mime) {
      case 'image/png':
        return loadPNG(image);
      case 'image/jpeg':
        return loadJPEG(image);
      case 'image/tiff':
        return loadTIFF(image);
      default:
        return loadGeneric(getBase64(type.mime));
    }
  }
  return loadGeneric(getBase64('application/octet-stream'));
  function getBase64(type) {
    if (base64Url) {
      return base64Url;
    } else {
      return toBase64URL(image, type);
    }
  }
}

function loadURL(url, options) {
  const dataURL = url.slice(0, 64).match(isDataURL);
  let binaryDataP;
  if (dataURL !== null) {
    binaryDataP = Promise.resolve(base64Decode(url.slice(dataURL[0].length)));
  } else {
    binaryDataP = fetchBinary(url, options);
  }
  return binaryDataP.then((binaryData) => {
    const uint8 = new Uint8Array(binaryData);
    return loadBinary(uint8, dataURL ? url : undefined);
  });
}

function loadPNG(data) {
  const png = decodePng(data);
  let channels = png.channels;
  let components;
  let alpha = 0;
  if (channels === 2 || channels === 4) {
    components = channels - 1;
    alpha = 1;
  } else {
    components = channels;
  }
  if (png.palette) {
    return loadPNGFromPalette(png);
  }

  return new Image(png.width, png.height, png.data, {
    components,
    alpha,
    bitDepth: png.depth,
  });
}

function loadPNGFromPalette(png) {
  const pixels = png.width * png.height;
  const channels = png.palette[0].length;
  const data = new Uint8Array(pixels * channels);
  const pixelsPerByte = 8 / png.depth;
  const factor = png.depth < 8 ? pixelsPerByte : 1;
  const mask = parseInt('1'.repeat(png.depth), 2);
  const hasAlpha = channels === 4;
  let dataIndex = 0;

  for (let i = 0; i < pixels; i++) {
    const index = Math.floor(i / factor);
    let value = png.data[index];
    if (png.depth < 8) {
      value =
        (value >>> (png.depth * (pixelsPerByte - 1 - (i % pixelsPerByte)))) &
        mask;
    }
    const paletteValue = png.palette[value];
    data[dataIndex++] = paletteValue[0];
    data[dataIndex++] = paletteValue[1];
    data[dataIndex++] = paletteValue[2];
    if (hasAlpha) {
      data[dataIndex++] = paletteValue[3];
    }
  }

  return new Image(png.width, png.height, data, {
    components: 3,
    alpha: hasAlpha,
    bitDepth: 8,
  });
}

function loadJPEG(data) {
  const decodedExif = decodeJpegExif(data);
  let meta;
  if (decodedExif.exif) {
    meta = getMetadata(decodedExif.exif);
  }
  const jpeg = decodeJpeg(data, { useTArray: true });
  return new Image(jpeg.width, jpeg.height, jpeg.data, { meta });
}

function loadTIFF(data) {
  let result = decodeTiff(data);
  if (result.length === 1) {
    return getImageFromIFD(result[0]);
  } else {
    return new Stack(result.map(getImageFromIFD));
  }
}

function getMetadata(image) {
  const metadata = {
    tiff: image,
  };
  if (image.exif) {
    metadata.exif = image.exif;
  }
  if (image.gps) {
    metadata.gps = image.gps;
  }
  return metadata;
}

function getImageFromIFD(image) {
  if (image.type === 3) {
    // Palette
    const data = new Uint16Array(3 * image.width * image.height);
    const palette = image.palette;
    let ptr = 0;
    for (let i = 0; i < image.data.length; i++) {
      const index = image.data[i];
      const color = palette[index];
      data[ptr++] = color[0];
      data[ptr++] = color[1];
      data[ptr++] = color[2];
    }
    return new Image(image.width, image.height, data, {
      components: 3,
      alpha: 0,
      colorModel: RGB,
      bitDepth: 16,
      meta: getMetadata(image),
    });
  } else {
    return new Image(image.width, image.height, image.data, {
      components: 1,
      alpha: 0,
      colorModel: GREY,
      bitDepth: image.bitsPerSample.length
        ? image.bitsPerSample[0]
        : image.bitsPerSample,
      meta: getMetadata(image),
    });
  }
}

function loadGeneric(url, options) {
  options = options || {};
  return new Promise(function (resolve, reject) {
    let image = new DOMImage();
    image.onload = function () {
      let w = image.width;
      let h = image.height;
      let canvas = createCanvas(w, h);
      let ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0, w, h);
      let data = ctx.getImageData(0, 0, w, h).data;
      resolve(new Image(w, h, data, options));
    };
    image.onerror = function () {
      reject(new Error(`Could not load ${url}`));
    };
    image.src = url;
  });
}
<commit_msg>fix: read color tiff<commit_after>import { decode as decodeJpegExif } from 'fast-jpeg';
import { decode as decodePng } from 'fast-png';
import imageType from 'image-type';
import { decode as decodeJpeg } from 'jpeg-js';
import { decode as decodeTiff } from 'tiff';

import Stack from '../../stack/Stack';
import { decode as base64Decode, toBase64URL } from '../../util/base64';
import Image from '../Image';
import { GREY, RGB } from '../model/model';

import { fetchBinary, DOMImage, createCanvas } from './environment';

const isDataURL = /^data:[a-z]+\/([a-z]+);base64,/;

/**
 * Load an image
 * @memberof Image
 * @static
 * @param {string|ArrayBuffer|Buffer|Uint8Array} image - URL of the image (browser, can be a dataURL) or path (Node.js)
 * or buffer containing the binary data
 * @param {object} [options] - In the browser, the options object is passed to the underlying `fetch` call.
 * @return {Promise<Image>}
 * @example
 * const image = await Image.load('https://example.com/image.png');
 */
export default function load(image, options) {
  if (typeof image === 'string') {
    return loadURL(image, options);
  } else if (image instanceof ArrayBuffer) {
    return Promise.resolve(loadBinary(new Uint8Array(image)));
  } else if (image.buffer) {
    return Promise.resolve(loadBinary(image));
  } else {
    throw new Error('argument to "load" must be a string or buffer.');
  }
}

function loadBinary(image, base64Url) {
  const type = imageType(image);
  if (type) {
    switch (type.mime) {
      case 'image/png':
        return loadPNG(image);
      case 'image/jpeg':
        return loadJPEG(image);
      case 'image/tiff':
        return loadTIFF(image);
      default:
        return loadGeneric(getBase64(type.mime));
    }
  }
  return loadGeneric(getBase64('application/octet-stream'));
  function getBase64(type) {
    if (base64Url) {
      return base64Url;
    } else {
      return toBase64URL(image, type);
    }
  }
}

function loadURL(url, options) {
  const dataURL = url.slice(0, 64).match(isDataURL);
  let binaryDataP;
  if (dataURL !== null) {
    binaryDataP = Promise.resolve(base64Decode(url.slice(dataURL[0].length)));
  } else {
    binaryDataP = fetchBinary(url, options);
  }
  return binaryDataP.then((binaryData) => {
    const uint8 = new Uint8Array(binaryData);
    return loadBinary(uint8, dataURL ? url : undefined);
  });
}

function loadPNG(data) {
  const png = decodePng(data);
  let channels = png.channels;
  let components;
  let alpha = 0;
  if (channels === 2 || channels === 4) {
    components = channels - 1;
    alpha = 1;
  } else {
    components = channels;
  }
  if (png.palette) {
    return loadPNGFromPalette(png);
  }

  return new Image(png.width, png.height, png.data, {
    components,
    alpha,
    bitDepth: png.depth,
  });
}

function loadPNGFromPalette(png) {
  const pixels = png.width * png.height;
  const channels = png.palette[0].length;
  const data = new Uint8Array(pixels * channels);
  const pixelsPerByte = 8 / png.depth;
  const factor = png.depth < 8 ? pixelsPerByte : 1;
  const mask = parseInt('1'.repeat(png.depth), 2);
  const hasAlpha = channels === 4;
  let dataIndex = 0;

  for (let i = 0; i < pixels; i++) {
    const index = Math.floor(i / factor);
    let value = png.data[index];
    if (png.depth < 8) {
      value =
        (value >>> (png.depth * (pixelsPerByte - 1 - (i % pixelsPerByte)))) &
        mask;
    }
    const paletteValue = png.palette[value];
    data[dataIndex++] = paletteValue[0];
    data[dataIndex++] = paletteValue[1];
    data[dataIndex++] = paletteValue[2];
    if (hasAlpha) {
      data[dataIndex++] = paletteValue[3];
    }
  }

  return new Image(png.width, png.height, data, {
    components: 3,
    alpha: hasAlpha,
    bitDepth: 8,
  });
}

function loadJPEG(data) {
  const decodedExif = decodeJpegExif(data);
  let meta;
  if (decodedExif.exif) {
    meta = getMetadata(decodedExif.exif);
  }
  const jpeg = decodeJpeg(data, { useTArray: true });
  return new Image(jpeg.width, jpeg.height, jpeg.data, { meta });
}

function loadTIFF(data) {
  let result = decodeTiff(data);
  if (result.length === 1) {
    return getImageFromIFD(result[0]);
  } else {
    return new Stack(result.map(getImageFromIFD));
  }
}

function getMetadata(image) {
  const metadata = {
    tiff: image,
  };
  if (image.exif) {
    metadata.exif = image.exif;
  }
  if (image.gps) {
    metadata.gps = image.gps;
  }
  return metadata;
}

function getImageFromIFD(image) {
  if (image.type === 3) {
    // Palette
    const data = new Uint16Array(3 * image.width * image.height);
    const palette = image.palette;
    let ptr = 0;
    for (let i = 0; i < image.data.length; i++) {
      const index = image.data[i];
      const color = palette[index];
      data[ptr++] = color[0];
      data[ptr++] = color[1];
      data[ptr++] = color[2];
    }
    return new Image(image.width, image.height, data, {
      components: 3,
      alpha: 0,
      colorModel: RGB,
      bitDepth: 16,
      meta: getMetadata(image),
    });
  } else {
    return new Image(image.width, image.height, image.data, {
      components: image.type === 2 ? 3 : 1,
      alpha: 0,
      colorModel: image.type === 2 ? RGB : GREY,
      bitDepth: image.bitsPerSample.length
        ? image.bitsPerSample[0]
        : image.bitsPerSample,
      meta: getMetadata(image),
    });
  }
}

function loadGeneric(url, options) {
  options = options || {};
  return new Promise(function (resolve, reject) {
    let image = new DOMImage();
    image.onload = function () {
      let w = image.width;
      let h = image.height;
      let canvas = createCanvas(w, h);
      let ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0, w, h);
      let data = ctx.getImageData(0, 0, w, h).data;
      resolve(new Image(w, h, data, options));
    };
    image.onerror = function () {
      reject(new Error(`Could not load ${url}`));
    };
    image.src = url;
  });
}
<|endoftext|>


<commit_before>const keyCodes = {

  '38': `up`,
  '40': `down`,
  '37': `left`,
  '39': `right`,

  '81': `q`,
  '87': `w`,
  '69': `e`,
  '65': `a`,
  '83': `s`,
  '68': `d`,

  '48': `0`,
  '49': `1`,
  '50': `2`,
  '51': `3`,
  '52': `4`,
  '53': `5`,
  '54': `6`,
  '55': `7`,
  '56': `8`,
  '57': `9`,

  '189': `-`,
  '187': `=`,

  '32': `space`,
  '13': `return`,
  '16': `shift`,
  '17': `ctrl`,
  '9': `tab`,
  '18': `alt`

};

export const inputs = {

  up: false,
  down: false,
  left: false,
  right: false,

  q: false,
  w: false,
  e: false,
  a: false,
  s: false,
  d: false,

  '0': false,
  '1': false,
  '2': false,
  '3': false,
  '4': false,
  '5': false,
  '6': false,
  '7': false,
  '8': false,
  '9': false,

  '-': false,
  '=': false,

  space: false,
  return: false,
  shift: false,
  ctrl: false,
  tab: false,
  alt: false,

  click: false

};

const parseKeyInfo =
  (keyCode, active = true) => {
    const key = keyCodes[keyCode];
    if(key) inputs[key] = active;
    return inputs[key];
  };

document.body.onkeyup = ({ keyCode }) => parseKeyInfo(keyCode, false);
document.body.onkeydown = ({ keyCode }) => parseKeyInfo(keyCode, true);
<commit_msg>Change input handling<commit_after>const keyCodes = {

  '38': `up`,
  '40': `down`,
  '37': `left`,
  '39': `right`,

  '81': `q`,
  '87': `w`,
  '69': `e`,
  '65': `a`,
  '83': `s`,
  '68': `d`,

  '48': `0`,
  '49': `1`,
  '50': `2`,
  '51': `3`,
  '52': `4`,
  '53': `5`,
  '54': `6`,
  '55': `7`,
  '56': `8`,
  '57': `9`,

  '189': `-`,
  '187': `=`,

  '32': `space`,
  '13': `return`,
  '16': `shift`,
  '17': `ctrl`,
  '9': `tab`,
  '18': `alt`

};

export const inputs = {

  up: 0,
  down: 0,
  left: 0,
  right: 0,

  q: 0,
  w: 0,
  e: 0,
  a: 0,
  s: 0,
  d: 0,

  '0': 0,
  '1': 0,
  '2': 0,
  '3': 0,
  '4': 0,
  '5': 0,
  '6': 0,
  '7': 0,
  '8': 0,
  '9': 0,

  '-': 0,
  '=': 0,

  space: 0,
  return: 0,
  shift: 0,
  ctrl: 0,
  tab: 0,
  alt: 0,

};

const parseKeyInfo =
  (keyCode, active = 1) => {
    const key = keyCodes[keyCode];
    if (key) inputs[key] = active;
    return inputs[key];
  };

document.body.onkeyup = ({ keyCode }) => parseKeyInfo(keyCode, 0);
document.body.onkeydown = ({ keyCode }) => parseKeyInfo(keyCode, 1);

export const updateInputs = () => {
  for (const [key, value] of inputs.entries()) {
    inputs[key] =
      value === 1
        ? 2
        : value;
  }
}

<|endoftext|>


<commit_before>module.exports = function(options) {
  var student = null;
  var teacher = null;

  if(options.mode == "node")
  {
    if(!options.url) {
      options.url = 'http://localhost:4000';
    }

    student = require('./node/student')(options);
    teacher = require('./node/teacher')(options);
  }
  else {
    if(!options.url) {
      options.url = 'ws://localhost:4000/ws';
    }

    student = require('./elixir/student')(options);
    teacher = require('./elixir/teacher')(options);
  }

  for(var i = 1; i <= options.numTeachers; i++) {
    teacher.start(i);
  }

  setTimeout(function() {
    for(var i = options.idStart + 1; i <= options.idStart + options.numStudents; i++) {
      student.start(i);
    }
  }, 100);
}
<commit_msg>Default url matches express io's default.<commit_after>module.exports = function(options) {
  var student = null;
  var teacher = null;

  if(options.mode == "node")
  {
    if(!options.url) {
      options.url = 'http://localhost:3000';
    }

    student = require('./node/student')(options);
    teacher = require('./node/teacher')(options);
  }
  else {
    if(!options.url) {
      options.url = 'ws://localhost:4000/ws';
    }

    student = require('./elixir/student')(options);
    teacher = require('./elixir/teacher')(options);
  }

  for(var i = 1; i <= options.numTeachers; i++) {
    teacher.start(i);
  }

  setTimeout(function() {
    for(var i = options.idStart + 1; i <= options.idStart + options.numStudents; i++) {
      student.start(i);
    }
  }, 100);
}
<|endoftext|>


<commit_before>import Ember from 'ember';

var a_slice = Array.prototype.slice;

function index(element, selector) {
  return element.parent().children(selector).index(element);
}

function applySortable(el, target, method, itemSelector, handleSelector, connectWith) {
  if (el) {
    var options = {
      start: function(e, ui) {
        ui.item.data('dragon-drop-old-index', index(ui.item, itemSelector));
        ui.item.__source__ = target;
      },

      update: function(e, ui) {
        var newIndex = index(ui.item, itemSelector);
        var oldIndex = ui.item.data('dragon-drop-old-index');
        var source = ui.item.__source__;

        if (ui.item.closest('.ember-drag-list').attr('id') === target.get('elementId')) {
          Ember.run(function() {
            target[method](oldIndex, newIndex, source);
          });
        }
      },

      receive: function (e, ui) {
        var source = ui.item.__source__;

        Ember.run(function() {
          target.viewReceived(Ember.View.views[ui.item.attr('id')], source);
        });
      }
    };

    options.connectWith = connectWith || false;

    if (itemSelector)   { options.item   = itemSelector;   }
    if (handleSelector) { options.handle = handleSelector; }

    el.sortable(options);
  }
}

function destroySortable(element) {
  if (element) {
    element.sortable('destroy');
  }
}

var get = Ember.get;

export default Ember.CollectionView.extend(Ember.TargetActionSupport, {
  //if updateOrder is true, component updates the collection objects' orders using the orderField
  //else lets the receiver of the itemWasMoved event handle updates
  updateOrder: true,
  orderField: "position",
  isVirtual: true,
  classNames: ['ember-drag-list'],
  content: Ember.computed.oneWay('context'),
  handleSelector: ".draggable-item-handle",
  itemSelector: '.draggable-item',
  target: Ember.computed.oneWay('controller'),

  init: function() {
    var itemView = this.get('itemView');
    var ItemViewClass;

    this._updateDisabled = 0;

    if (itemView) {
      ItemViewClass = this.container.lookupFactory('view:' + itemView);
    } else {
      ItemViewClass = this.get('itemViewClass');
    }

    this.set('itemViewClass', ItemViewClass.extend({
      cloneKeywords: function () {
        var templateData = get(this, 'templateData');

        var keywords = templateData ? Ember.copy(templateData.keywords) : {};

        this._clonedKeywords$ = this._clonedKeywords$ || {
          view: Ember.ObjectProxy.create({
            content: this._keywords$view = (this.isVirtual ? keywords.view : this)
          }),
          controller: Ember.ObjectProxy.create({
            content: this.get('controller'),
            container: this.container
          }),
          _view: Ember.ObjectProxy.create({
            content: this
          })
        };

        Ember.set(keywords, 'view', this._clonedKeywords$.view);
        Ember.set(keywords, '_view', this._clonedKeywords$._view);
        Ember.set(keywords, 'controller', this._clonedKeywords$.controller);

        return keywords;
      },
      isVirtual: true,
      context: Ember.computed.oneWay('content'),
      template: this.get('template'),
      classNames: ['draggable-item'],
      didInsertElement: function () {
        // hack to allow eventPropogation on virtualViews: https://github.com/emberjs/ember.js/pull/5179
        Ember.View.views[this.get('elementId')] = this;
      },

      willDestroyElement: function () {
        // hack to allow eventPropogation on virtualViews: https://github.com/emberjs/ember.js/pull/5179
        delete Ember.View.views[this.get('elementId')];
      }
    }));

    this._super.apply(this, arguments);
  },

  didInsertElement: function () {
    Ember.View.views[this.get('elementId')] = this;
    applySortable(this.$(), this, 'itemWasDragged', this.get('itemSelector'), this.get('handleSelector'), this.get('connectWith'));
  },

  willDestroyElement: function () {
    delete Ember.View.views[this.get('elementId')];
    destroySortable(this.$());
  },
  // lifted from Ember.Compontent
  sendAction: function(action) {
    var actionName;
    var contexts = a_slice.call(arguments, 1);

    // Send the default action
    if (action === undefined) {
      actionName = get(this, 'action');
    } else {
      actionName = get(this, action);
    }

    // If no action name for that action could be found, just abort.
    if (actionName === undefined) { return; }

    this.triggerAction({
      action: actionName,
      actionContext: contexts
    });
  },

  viewReceived: function(view /*, source */) {
    view.set('parentView', this.get('parentView'));
    view.set('_parentView', this);
    view._clonedKeywords$.view.set('content', this.templateData.keywords.view);
    view._clonedKeywords$.controller.set('content', this.templateData.keywords.controller);
    view._clonedKeywords$._view.set('content', this);
  },

  arrayWillChange: function() {
    if (this._updateDisabled > 0) { return ;}
    this._super.apply(this, arguments);
  },

  arrayDidChange: function() {
    if (this._updateDisabled > 0) { return ;}
    this._super.apply(this, arguments);
  },
  // - [x] ensure childViews is invalidated
  // - [x] nonVirtualChildViews (may be fixed by isVirtal)
  // - [ ] insertItem hook
  // - [ ] removeItem hook
  // - [x] "view" within children be from the outer scope (may be fixed by isVirtal)
  // - [x] keywords from outercontext should change when moved between trees (may be fixed by isVirtal)
  // - [ ] make eventDispatcher not block the move event stuff (caused by virtual)

  execWithoutRerender: function (func, context) {
    this._updateDisabled++;

    try {
      return func.call(context);
    } finally {
      this._updateDisabled--;
    }
  },
  updateItemPositions: function() {
    var index = 0;
    var items = this.get('context');
    var orderField = this.get('orderField');
    items.forEach(function(item) {
      index++;
      item.set(orderField, index);
    });
  },
  itemWasDragged: function (oldIndex, newIndex, source) {
    var sourceList = source.get('context');
    var targetList = this.get('context');

    var object = sourceList.objectAt(oldIndex);
    var entry = object.isController ? object.get('content') : object;
    var view = source._childViews.splice(oldIndex, 1)[0];

    this.execWithoutRerender(function(){
      source.execWithoutRerender(function() {
        this._childViews.splice(newIndex, 0,  view);

        sourceList.removeAt(oldIndex);
        targetList.insertAt(newIndex, entry);

        Ember.propertyDidChange(source, 'childViews');
        Ember.propertyDidChange(this, 'childViews');
      }, this);
    }, this);
    if (this.get('updateOrder')) {
      this.updateItemPositions();
    }
    this.sendAction('itemWasMoved', entry, oldIndex, newIndex, sourceList);
  }
});
<commit_msg>Remove updating of item positions. This should not be the responsibility of draggable-each. <commit_after>import Ember from 'ember';

var a_slice = Array.prototype.slice;

function index(element, selector) {
  return element.parent().children(selector).index(element);
}

function applySortable(el, target, method, itemSelector, handleSelector, connectWith) {
  if (el) {
    var options = {
      start: function(e, ui) {
        ui.item.data('dragon-drop-old-index', index(ui.item, itemSelector));
        ui.item.__source__ = target;
      },

      update: function(e, ui) {
        var newIndex = index(ui.item, itemSelector);
        var oldIndex = ui.item.data('dragon-drop-old-index');
        var source = ui.item.__source__;

        if (ui.item.closest('.ember-drag-list').attr('id') === target.get('elementId')) {
          Ember.run(function() {
            target[method](oldIndex, newIndex, source);
          });
        }
      },

      receive: function (e, ui) {
        var source = ui.item.__source__;

        Ember.run(function() {
          target.viewReceived(Ember.View.views[ui.item.attr('id')], source);
        });
      }
    };

    options.connectWith = connectWith || false;

    if (itemSelector)   { options.item   = itemSelector;   }
    if (handleSelector) { options.handle = handleSelector; }

    el.sortable(options);
  }
}

function destroySortable(element) {
  if (element) {
    element.sortable('destroy');
  }
}

var get = Ember.get;

export default Ember.CollectionView.extend(Ember.TargetActionSupport, {
  isVirtual: true,
  classNames: ['ember-drag-list'],
  content: Ember.computed.oneWay('context'),
  handleSelector: ".draggable-item-handle",
  itemSelector: '.draggable-item',
  target: Ember.computed.oneWay('controller'),

  init: function() {
    var itemView = this.get('itemView');
    var ItemViewClass;

    this._updateDisabled = 0;

    if (itemView) {
      ItemViewClass = this.container.lookupFactory('view:' + itemView);
    } else {
      ItemViewClass = this.get('itemViewClass');
    }

    this.set('itemViewClass', ItemViewClass.extend({
      cloneKeywords: function () {
        var templateData = get(this, 'templateData');

        var keywords = templateData ? Ember.copy(templateData.keywords) : {};

        this._clonedKeywords$ = this._clonedKeywords$ || {
          view: Ember.ObjectProxy.create({
            content: this._keywords$view = (this.isVirtual ? keywords.view : this)
          }),
          controller: Ember.ObjectProxy.create({
            content: this.get('controller'),
            container: this.container
          }),
          _view: Ember.ObjectProxy.create({
            content: this
          })
        };

        Ember.set(keywords, 'view', this._clonedKeywords$.view);
        Ember.set(keywords, '_view', this._clonedKeywords$._view);
        Ember.set(keywords, 'controller', this._clonedKeywords$.controller);

        return keywords;
      },
      isVirtual: true,
      context: Ember.computed.oneWay('content'),
      template: this.get('template'),
      classNames: ['draggable-item'],
      didInsertElement: function () {
        // hack to allow eventPropogation on virtualViews: https://github.com/emberjs/ember.js/pull/5179
        Ember.View.views[this.get('elementId')] = this;
      },

      willDestroyElement: function () {
        // hack to allow eventPropogation on virtualViews: https://github.com/emberjs/ember.js/pull/5179
        delete Ember.View.views[this.get('elementId')];
      }
    }));

    this._super.apply(this, arguments);
  },

  didInsertElement: function () {
    Ember.View.views[this.get('elementId')] = this;
    applySortable(this.$(), this, 'itemWasDragged', this.get('itemSelector'), this.get('handleSelector'), this.get('connectWith'));
  },

  willDestroyElement: function () {
    delete Ember.View.views[this.get('elementId')];
    destroySortable(this.$());
  },
  // lifted from Ember.Compontent
  sendAction: function(action) {
    var actionName;
    var contexts = a_slice.call(arguments, 1);

    // Send the default action
    if (action === undefined) {
      actionName = get(this, 'action');
    } else {
      actionName = get(this, action);
    }

    // If no action name for that action could be found, just abort.
    if (actionName === undefined) { return; }

    this.triggerAction({
      action: actionName,
      actionContext: contexts
    });
  },

  viewReceived: function(view /*, source */) {
    view.set('parentView', this.get('parentView'));
    view.set('_parentView', this);
    view._clonedKeywords$.view.set('content', this.templateData.keywords.view);
    view._clonedKeywords$.controller.set('content', this.templateData.keywords.controller);
    view._clonedKeywords$._view.set('content', this);
  },

  arrayWillChange: function() {
    if (this._updateDisabled > 0) { return ;}
    this._super.apply(this, arguments);
  },

  arrayDidChange: function() {
    if (this._updateDisabled > 0) { return ;}
    this._super.apply(this, arguments);
  },
  // - [x] ensure childViews is invalidated
  // - [x] nonVirtualChildViews (may be fixed by isVirtal)
  // - [ ] insertItem hook
  // - [ ] removeItem hook
  // - [x] "view" within children be from the outer scope (may be fixed by isVirtal)
  // - [x] keywords from outercontext should change when moved between trees (may be fixed by isVirtal)
  // - [ ] make eventDispatcher not block the move event stuff (caused by virtual)

  execWithoutRerender: function (func, context) {
    this._updateDisabled++;

    try {
      return func.call(context);
    } finally {
      this._updateDisabled--;
    }
  },
  itemWasDragged: function (oldIndex, newIndex, source) {
    var sourceList = source.get('context');
    var targetList = this.get('context');

    var object = sourceList.objectAt(oldIndex);
    var entry = object.isController ? object.get('content') : object;
    var view = source._childViews.splice(oldIndex, 1)[0];

    this.execWithoutRerender(function(){
      source.execWithoutRerender(function() {
        this._childViews.splice(newIndex, 0,  view);

        sourceList.removeAt(oldIndex);
        targetList.insertAt(newIndex, entry);

        Ember.propertyDidChange(source, 'childViews');
        Ember.propertyDidChange(this, 'childViews');
      }, this);
    }, this);
    this.sendAction('itemWasMoved', entry, oldIndex, newIndex, sourceList);
  }
});
<|endoftext|>


<commit_before>const Xray = require('x-ray');

const x = new Xray();

function getParentalGuide(url, cb) {
  x(url, {
    drugs: 'p[id="swiki.2.4.1"]',
  })((err, data) => {
    const parental = /(\d+\/10)(.*)/g.exec(data.drugs);
    cb(err, {
      rating: parental[1],
      summary: parental[2].replace(/\.(\S)/g, '. $1'),
    });
  });
}

module.exports = getParentalGuide;
<commit_msg>Some ratings have an optional closing paren we should ignore<commit_after>const Xray = require('x-ray');

const x = new Xray();

function getParentalGuide(url, cb) {
  x(url, {
    drugs: 'p[id="swiki.2.4.1"]',
  })((err, data) => {
    const parental = /(\d+\/10)\)?(.*)/g.exec(data.drugs);
    cb(err, {
      rating: parental[1],
      summary: parental[2].replace(/\.(\S)/g, '. $1'),
    });
  });
}

module.exports = getParentalGuide;
<|endoftext|>


<commit_before>/**
 * Created by Jérémy on 07/05/2017.
 */
const Ffmpeg = require('fluent-ffmpeg');
const config = require('../../config/app.json');
const options = require('../../config/youtube.json');
const path = require('path');
const fs = require('fs');
const moment = require('moment');
const winston = require('winston');

exports.process = function (job, done) {
    if (config.ffmpeg_path) {
        process.env['FFMPEG_PATH'] = config.ffmpeg_path;
    }
    if (config.ffmpeg_path) {
        process.env['FFPROBE_PATH'] = config.ffprobe_path;
    }

    winston.info('FFMPEG_PATH=', process.env.FFMPEG_PATH);
    winston.info('FFPROBE_PATH=', process.env.FFPROBE_PATH);

    let intro = null;
    let outro = null;
    let content = null;
    let partner = null;

    if (job) {
        if (job.episode && job.episode.serie) {
            if (job.episode.serie.intro) {
                intro = path.resolve(job.intro);
            }
            if (job.episode.serie.partner) {
                partner = path.resolve(job.partner);
            }
            if (job.episode.serie.outro) {
                outro = path.resolve(job.outro);
            }
        }
        if (job.path) {
            content = path.resolve(job.path);
        }
    }

    if (!intro) {
        intro = path.resolve(options.default_intro);
    }
    if (!outro) {
        outro = path.resolve(options.default_outro);
    }

    if (!content) {
        return done('no content to process !');
    }

    let outputDirectory = path.resolve(config.output_directory, path.basename(path.dirname(job.path)));

    if (!fs.existsSync(outputDirectory)) {
        fs.mkdirSync(outputDirectory);
    }

    let airDate = moment(options.intro_outro_air_date, 'YYYY/MM/DD HH:mm:ss');
    let publicDate = moment(job.episode.publishAt);
    winston.info(airDate, publicDate, publicDate.diff(airDate));
    let allow_intro = publicDate.diff(airDate) >= 0 && options.prepend_intro;
    let allow_outro = publicDate.diff(airDate) >= 0 && options.append_outro;

    let out = path.resolve(outputDirectory, job.episode.episode_number + '.mp4');

    if (!allow_intro && !allow_outro) {
        winston.info('nothing to process !');
        job.state = 'VIDEO_DONE';
        return job.save(done);
    }

    winston.info('processing video content', path.resolve(content));
    winston.info('output directory is', out);

    let command = new Ffmpeg();
    if (intro && allow_intro) {
        winston.info('adding intro to the video', path.resolve(intro));
        command.input(intro);
    }
    if (partner) {
        winston.info('adding partner to the video', path.resolve(partner));
        command.input(partner);
    }
    command.input(content);
    if (outro && allow_outro) {
        winston.info('adding outro to the video', path.resolve(outro));
        command.input(outro);
    }

    command.on('start', function (commandLine) {
        winston.info('Spawned ffmpeg with command', commandLine);
        job.state = 'VIDEO_PROCESSING';
        job.process_data = {
            totalSize: fs.statSync(content).size,
            startDate: moment().toDate()
        };
        job.save();
        job.markOnPlanning();
    });

    command.on('progress', function (progress) {
        job.process_data.progress = progress;
        job.markModified('process_data');
        job.save();
    });

    command.on('error', function (err) {
        winston.error(`FFMPEG err ${err}`);
        done(err);
    });

    command.on('end', function () {
        // TODO do not delete the video for now, more tests are necessary
        //fs.unlinkSync(job.episode.path);
        job.episode.path = out;
        job.episode.save(function (err, episode) {
            job.state = 'VIDEO_DONE';
            job.process_data.endDate = moment().toDate();
            job.markModified('process_data');
            job.save(done);
        });
    });

    command.mergeToFile(out, config.working_directory);

    winston.info('started');
};
<commit_msg>commented mark on planning when process is started<commit_after>/**
 * Created by Jérémy on 07/05/2017.
 */
const Ffmpeg = require('fluent-ffmpeg');
const config = require('../../config/app.json');
const options = require('../../config/youtube.json');
const path = require('path');
const fs = require('fs');
const moment = require('moment');
const winston = require('winston');

exports.process = function (job, done) {
    if (config.ffmpeg_path) {
        process.env['FFMPEG_PATH'] = config.ffmpeg_path;
    }
    if (config.ffmpeg_path) {
        process.env['FFPROBE_PATH'] = config.ffprobe_path;
    }

    winston.info('FFMPEG_PATH=', process.env.FFMPEG_PATH);
    winston.info('FFPROBE_PATH=', process.env.FFPROBE_PATH);

    let intro = null;
    let outro = null;
    let content = null;
    let partner = null;

    if (job) {
        if (job.episode && job.episode.serie) {
            if (job.episode.serie.intro) {
                intro = path.resolve(job.intro);
            }
            if (job.episode.serie.partner) {
                partner = path.resolve(job.partner);
            }
            if (job.episode.serie.outro) {
                outro = path.resolve(job.outro);
            }
        }
        if (job.path) {
            content = path.resolve(job.path);
        }
    }

    if (!intro) {
        intro = path.resolve(options.default_intro);
    }
    if (!outro) {
        outro = path.resolve(options.default_outro);
    }

    if (!content) {
        return done('no content to process !');
    }

    let outputDirectory = path.resolve(config.output_directory, path.basename(path.dirname(job.path)));

    if (!fs.existsSync(outputDirectory)) {
        fs.mkdirSync(outputDirectory);
    }

    let airDate = moment(options.intro_outro_air_date, 'YYYY/MM/DD HH:mm:ss');
    let publicDate = moment(job.episode.publishAt);
    winston.info(airDate, publicDate, publicDate.diff(airDate));
    let allow_intro = publicDate.diff(airDate) >= 0 && options.prepend_intro;
    let allow_outro = publicDate.diff(airDate) >= 0 && options.append_outro;

    let out = path.resolve(outputDirectory, job.episode.episode_number + '.mp4');

    if (!allow_intro && !allow_outro) {
        winston.info('nothing to process !');
        job.state = 'VIDEO_DONE';
        return job.save(done);
    }

    winston.info('processing video content', path.resolve(content));
    winston.info('output directory is', out);

    let command = new Ffmpeg();
    if (intro && allow_intro) {
        winston.info('adding intro to the video', path.resolve(intro));
        command.input(intro);
    }
    if (partner) {
        winston.info('adding partner to the video', path.resolve(partner));
        command.input(partner);
    }
    command.input(content);
    if (outro && allow_outro) {
        winston.info('adding outro to the video', path.resolve(outro));
        command.input(outro);
    }

    command.on('start', function (commandLine) {
        winston.info('Spawned ffmpeg with command', commandLine);
        job.state = 'VIDEO_PROCESSING';
        job.process_data = {
            totalSize: fs.statSync(content).size,
            startDate: moment().toDate()
        };
        job.save();
        //job.markOnPlanning();
    });

    command.on('progress', function (progress) {
        job.process_data.progress = progress;
        job.markModified('process_data');
        job.save();
    });

    command.on('error', function (err) {
        winston.error(`FFMPEG err ${err}`);
        done(err);
    });

    command.on('end', function () {
        // TODO do not delete the video for now, more tests are necessary
        //fs.unlinkSync(job.episode.path);
        job.episode.path = out;
        job.episode.save(function (err, episode) {
            job.state = 'VIDEO_DONE';
            job.process_data.endDate = moment().toDate();
            job.markModified('process_data');
            job.save(done);
        });
    });

    command.mergeToFile(out, config.working_directory);

    winston.info('started');
};
<|endoftext|>