<commit_before>/** @jsx React.DOM */
define(['exports', 'react', 'uri', 'globals'],
function (biosample, React, URI, globals) {
    'use strict';

    var Panel = function (props) {
        // XXX not all panels have the same markup
        var context;
        if (props['@id']) {
            context = props;
            props = {context: context, key: context['@id']};
        }
        return globals.panel_views.lookup(props.context)(props);
    };

    var Biosample = biosample.Biosample = React.createClass({
        render: function() {
            var context = this.props.context;
            var itemClass = globals.itemClass(context, 'view-item');
            return (

Biosamples /

{context.biosample_type}{' '}/
{' '}
                                {context.donor ?

{context.donor.organism.name}

                                : null }

{context.accession}{' / '}{context.biosample_type}

Term name

{context.biosample_term_name}

Term ID

{context.biosample_term_id}

Description

{context.description}

Source

{context.source.title}

Product ID

<maybe_link href={context.url}>{context.product_id}</maybe_link>

Lot ID

{context.lot_id}

Project

{context.award.rfa}

Submitted by

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

Note

{context.note}

                        {(context.donor && (context.biosample_type != "immortalized cell line")) ?

Donor Information

                                <Panel context={context.donor} biosample={context} />

                        : null}

                        {context.treatments.length ?

Treatment Details

                                {context.treatments.map(Panel)}

                        : null}

                        {context.constructs.length ?

Construct Details

                                {context.constructs.map(Panel)}

                        : null}

                    {context.protocol_documents.length ?

Protocol documents

                            {context.protocol_documents.map(Panel)}

                    : null}

                    {context.characterizations.length ?

Characterizations

                            {context.characterizations.map(Panel)}

                    : null}

Related Biosamples

                    {context.derived_from.length ?

Derived From Biosample

{context.derived_from.map(function (biosample) {
                                return (

                                        {biosample.accession}

                                );
                            })}

                    : null}

            );
        }
    });

    globals.content_views.register(Biosample, 'biosample');

    var maybe_link = function (props, children) {
        if (props.href == 'N/A') {
            return children;
        } else {
            return (
                {children}
            );
        }
    };

    var HumanDonor = biosample.HumanDonor = React.createClass({
        render: function() {
            var context = this.props.context;
            var biosample = this.props.biosample;
            return (

Accession

{context.accession}

                    {context.organism.name ?
Species
 : null}
                    {context.organism.name ?
{context.organism.name}
 : null}

                    {biosample && biosample.life_stage ?
Life stage
 : null}
                    {biosample && biosample.life_stage ?
{biosample.life_stage}
 : null}

                    {biosample && biosample.age ?
Age
 : null}
                    {biosample && biosample.age ?
{biosample.age}{' '}{biosample.age_units}
 : null}

Sex

{context.sex}

                    {biosample && biosample.health_status ?
Health status
 : null}
                    {biosample && biosample.health_status ?
{biosample.health_status}
 : null}

Ethnicity

{context.ethnicity}

            );
        }
    });

    globals.panel_views.register(HumanDonor, 'human_donor');

    var MouseDonor = biosample.MouseDonor = React.createClass({
        render: function() {
            var context = this.props.context;
            var biosample = this.props.biosample;
            return (

Accession

{context.accession}

                    {context.organism.name ?
Species
 : null}
                    {context.organism.name ?
{context.organism.name}
 : null}

                    {biosample && biosample.life_stage ?
Life stage
 : null}
                    {biosample && biosample.life_stage ?
{biosample.life_stage}
 : null}

                    {biosample && biosample.age ?
Age
 : null}
                    {biosample && biosample.age ?
{biosample.age}{' '}{biosample.age_units}
 : null}

Sex

{context.sex}

                    {biosample && biosample.health_status ?
Health status
 : null}
                    {biosample && biosample.health_status ?
{biosample.health_status}
 : null}

Strain background

{context.strain_background}

                    {context.strain_name ?
Strain name
 : null}
                    {context.strain_name ?
{context.strain_name}
 : null}

            );
        }
    });

    globals.panel_views.register(MouseDonor, 'mouse_donor');

    var Treatment = biosample.Treatment = React.createClass({
        render: function() {
            var context = this.props.context;
            var title = '';
            if (context.concentration) {
                title += context.concentration + ' ' + context.concentration_units + ' ';
            }
            title += context.treatment_term_name + ' (' + context.treatment_term_id + ') ';
            if (context.duration) {
                title += 'for ' + context.duration + ' ' + context.duration_units;
            }
            return (

Treatment

{title}

Type

{context.treatment_type}

            );
        }
    });

    globals.panel_views.register(Treatment, 'treatment');

    var Construct = biosample.Construct = React.createClass({
        render: function() {
            var context = this.props.context;
            return (

                	{context.target ?
Target
 : null}
                    {context.target ?
{context.target.name}
 : null}

                    {context.vector_backbone_name ?
Vector
 : null}
                    {context.vector_backbone_name ?
{context.vector_backbone_name}
 : null}

                    {context.construct_type ?
Construct Type
 : null}
                    {context.construct_type ?
{context.construct_type}
 : null}

                   	{context.description ?
Description
 : null}
                    {context.description ?
{context.description}
 : null}

                    {context.source.title ?
Source
 : null}
                    {context.source.title ?
{context.source.title}
 : null}

                    {context.product_id ?
Product ID
 : null}
                    {context.product_id ?
<maybe_link href={context.url}>{context.product_id}</maybe_link>
 : null}

Construct documents

							{context.documents.map(function (document) {
								return (

									 		{document.attachment.download}

								);
							})}

            );
        }
    });

    globals.panel_views.register(Construct, 'construct');

    var Document = biosample.Document = React.createClass({
        render: function() {
            var context = this.props.context;
            var attachmentHref, attachmentUri;
            var figure, download, src, imgClass, alt;
            var imgClass = "characterization-img characterization-file";
            var height = "100";
            var width = "100";
            if (context.attachment) {
                attachmentUri = URI(context.attachment.href, URI(context['@id']).href);
                attachmentHref = attachmentUri.pathname + attachmentUri.search;
                if (context.attachment.type.split('/', 1)[0] == 'image') {
                    imgClass = 'characterization-img';
                    src = attachmentHref;
                    height = context.attachment.height;
                    width = context.attachment.width;
                    alt = "Characterization Image"
                } else if (context.attachment.type == "application/pdf"){
                    src = "/static/img/file-pdf.svg";
                    alt = "Characterization PDF Icon";
                } else {
                    src = "/static/img/file.svg";
                    alt = "Characterization Icon";
                }
                figure = (

                );
                download = (

                        {context.attachment.download}

                );
            } else {
                src = "/static/img/file-broken.png";
                alt = "Characterization File Broken Icon";
                figure = (

                );
                download = (
                    Document not available
                );
            }

            return (

                                    {figure}

{context.document_type}

{context.description}

                                	{context.caption ?
Caption
 : null}
                                    {context.caption ?
{context.caption}
 : null}

Submitted By

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

 Download

{download}

            );
        }
    });

    globals.panel_views.register(Document, 'document');
    globals.panel_views.register(Document, 'biosample_characterization');

    return biosample;
});
<commit_msg>Conditional field syntax cleanup. Corrected conditional on Construct docs value field.<commit_after>/** @jsx React.DOM */
define(['exports', 'react', 'uri', 'globals'],
function (biosample, React, URI, globals) {
    'use strict';

    var Panel = function (props) {
        // XXX not all panels have the same markup
        var context;
        if (props['@id']) {
            context = props;
            props = {context: context, key: context['@id']};
        }
        return globals.panel_views.lookup(props.context)(props);
    };

    var Biosample = biosample.Biosample = React.createClass({
        render: function() {
            var context = this.props.context;
            var itemClass = globals.itemClass(context, 'view-item');
            return (

Biosamples /

{context.biosample_type}{' '}/
{' '}
                                {context.donor ?

{context.donor.organism.name}

                                : null }

{context.accession}{' / '}{context.biosample_type}

Term name

{context.biosample_term_name}

Term ID

{context.biosample_term_id}

Description

{context.description}

Source

{context.source.title}

Product ID

<maybe_link href={context.url}>{context.product_id}</maybe_link>

Lot ID

{context.lot_id}

Project

{context.award.rfa}

Submitted by

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

Note

{context.note}

                        {(context.donor && (context.biosample_type != "immortalized cell line")) ?

Donor Information

                                <Panel context={context.donor} biosample={context} />

                        : null}

                        {context.treatments.length ?

Treatment Details

                                {context.treatments.map(Panel)}

                        : null}

                        {context.constructs.length ?

Construct Details

                                {context.constructs.map(Panel)}

                        : null}

                    {context.protocol_documents.length ?

Protocol documents

                            {context.protocol_documents.map(Panel)}

                    : null}

                    {context.characterizations.length ?

Characterizations

                            {context.characterizations.map(Panel)}

                    : null}

Related Biosamples

                    {context.derived_from.length ?

Derived From Biosample

{context.derived_from.map(function (biosample) {
                                return (

                                        {biosample.accession}

                                );
                            })}

                    : null}

            );
        }
    });

    globals.content_views.register(Biosample, 'biosample');

    var maybe_link = function (props, children) {
        if (props.href == 'N/A') {
            return children;
        } else {
            return (
                {children}
            );
        }
    };

    var HumanDonor = biosample.HumanDonor = React.createClass({
        render: function() {
            var context = this.props.context;
            var biosample = this.props.biosample;
            return (

Accession

{context.accession}

Species

{context.organism.name}

Life stage

{biosample.life_stage}

Age

{biosample.age}{' '}{biosample.age_units}

Sex

{context.sex}

Health status

{biosample.health_status}

Ethnicity

{context.ethnicity}

            );
        }
    });

    globals.panel_views.register(HumanDonor, 'human_donor');

    var MouseDonor = biosample.MouseDonor = React.createClass({
        render: function() {
            var context = this.props.context;
            var biosample = this.props.biosample;
            return (

Accession

{context.accession}

Species

{context.organism.name}

Life stage

{biosample.life_stage}

Age

{biosample.age}{' '}{biosample.age_units}

Sex

{context.sex}

Health status

{biosample.health_status}

Strain background

{context.strain_background}

Strain name

{context.strain_name}

            );
        }
    });

    globals.panel_views.register(MouseDonor, 'mouse_donor');

    var Treatment = biosample.Treatment = React.createClass({
        render: function() {
            var context = this.props.context;
            var title = '';
            if (context.concentration) {
                title += context.concentration + ' ' + context.concentration_units + ' ';
            }
            title += context.treatment_term_name + ' (' + context.treatment_term_id + ') ';
            if (context.duration) {
                title += 'for ' + context.duration + ' ' + context.duration_units;
            }
            return (

Treatment

{title}

Type

{context.treatment_type}

            );
        }
    });

    globals.panel_views.register(Treatment, 'treatment');

    var Construct = biosample.Construct = React.createClass({
        render: function() {
            var context = this.props.context;
            return (

Target

{context.target.name}

Vector

{context.vector_backbone_name}

Construct Type

{context.construct_type}

Description

{context.description}

Source

{context.source.title}

Product ID

<maybe_link href={context.url}>{context.product_id}</maybe_link>

Construct documents

							{context.documents.map(function (document) {
								return (

									 		{document.attachment.download}

								);
							})}

            );
        }
    });

    globals.panel_views.register(Construct, 'construct');

    var Document = biosample.Document = React.createClass({
        render: function() {
            var context = this.props.context;
            var attachmentHref, attachmentUri;
            var figure, download, src, imgClass, alt;
            var imgClass = "characterization-img characterization-file";
            var height = "100";
            var width = "100";
            if (context.attachment) {
                attachmentUri = URI(context.attachment.href, URI(context['@id']).href);
                attachmentHref = attachmentUri.pathname + attachmentUri.search;
                if (context.attachment.type.split('/', 1)[0] == 'image') {
                    imgClass = 'characterization-img';
                    src = attachmentHref;
                    height = context.attachment.height;
                    width = context.attachment.width;
                    alt = "Characterization Image"
                } else if (context.attachment.type == "application/pdf"){
                    src = "/static/img/file-pdf.svg";
                    alt = "Characterization PDF Icon";
                } else {
                    src = "/static/img/file.svg";
                    alt = "Characterization Icon";
                }
                figure = (

                );
                download = (

                        {context.attachment.download}

                );
            } else {
                src = "/static/img/file-broken.png";
                alt = "Characterization File Broken Icon";
                figure = (

                );
                download = (
                    Document not available
                );
            }

            return (

                                    {figure}

{context.document_type}

{context.description}

Caption

{context.caption}

Submitted By

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

 Download

{download}

            );
        }
    });

    globals.panel_views.register(Document, 'document');
    globals.panel_views.register(Document, 'biosample_characterization');

    return biosample;
});
<|endoftext|>


<commit_before>var namuapi = {};

// /check 페이지 대응
namuapi.theseedRequest = function (options) {
    var _newoptions = {};
    for (var i in options) {
        if (i !== "onload")
            _newoptions[i] = options[i];
        else
            _newoptions.onload = function (res) {
                console.log('[NamuFix] 위키 측으로부터 응답 받음.');
                var aTagForParsingUrl = document.createElement(res.finalUrl);
                if (aTagForParsingUrl.pathname.indexOf("/check") === 0) {
                    console.log('[NamuFix] /check 페이지 감지됨.');
                    namuapi.resolveRecaptcha(function (capKeyRes) {
                        if (capKeyRes == null) {
                            namuapi.theseedRequest(options);
                        } else {
                            var formData = new FormData();
                            formData.append("g-recaptcha-response", capKeyRes);
                            GM_xmlhttpRequest({
                                url: aTagForParsingUrl.href,
                                method: 'POST',
                                data: formData,
                                headers: {
                                    'Content-Type': 'application/x-www-form-urlencoded'
                                },
                                onload: function (checkRes) {
                                    console.log('[NamuFix] /check페이지에 g-recaptcha-response 전송함. 요청 재진행중...');
                                    namuapi.theseedRequest(options);
                                }
                            })
                        }
                    })
                } else {
                    options.onload(res);
                }
            };
    }
    GM_xmlhttpRequest(_newoptions);
}

namuapi.resolveRecaptcha = function (callback) {
    GM_xmlhttpRequest({
        method: 'GET',
        url: 'https://' + location.host + '/check',
        onload: function (res) {
            var siteKey = /["']sitekey["']: ["']([^"']+)["']/.exec(res.responseText)[1];
            var captchaWin = TooSimplePopup();
            captchaWin.title('reCAPTCHA 해결');
            captchaWin.content(function (winContainer) {
                var id = "nf-recaptcha-" + Date.now();
                var btnId = 'nf-communicate-' + Date.now();
                var cbName = "nfreCAPTCHACallback" + Date.now();
                winContainer.innerHTML = '
reCAPTCHA를 해결해주세요.

<button style="display: none;" type="button" id="' + btnId + '"></button>';
                var injectedButton = winContainer.querySelector('#' + btnId);
                winContainer.querySelector('#' + id).dataset.callback = cbName;
                winContainer.querySelector('#' + id).dataset.sitekey = siteKey;
                injectedButton.addEventListener('click', function (evt) {
                    evt.preventDefault();
                    callback(injectedButton.dataset.recaptchaResponse);
                    captchaWin.close();
                })
                var scriptTag = document.createElement("script");
                scriptTag.innerHTML = 'function ' + cbName + '(recaptcha_response){var btn = document.getElementById("' + btnId + '"); btn.dataset.recaptchaResponse = recaptcha_response; btn.click();}function renderNFReCAPTCHA(){if(!window.grecaptcha) return setTimeout(renderNFReCAPTCHA, 200); window.grecaptcha.render(document.getElementById("' + id + '"));} setTimeout(renderNFReCAPTCHA, 200);';
                winContainer.appendChild(scriptTag);
            });
            captchaWin.button('닫기', function () {
                callback(null);
                captchaWin.close();
            })
        }
    });
}

// getRAW
namuapi.raw = function (title, onfound, onnotfound) {
    namuapi.theseedRequest({
        method: 'GET',
        url: 'https://' + location.host + '/raw/' + title,
        onload: function (res) {
            if (res.status == 404) {
                onnotfound(title);
                return;
            }
            onfound(res.responseText, title);
        }
    })
}

namuapi.searchBlockHistory = function (query, isAuthor, callback) {
    namuapi.theseedRequest({
        method: 'GET',
        url: 'https://' + location.host + '/BlockHistory?target=' + (isAuthor ? "author" : "text") + '&query=' + encodeURIComponent(query),
        onload: function (res) {
            var parser = new DOMParser();
            var doc = parser.parseFromString(res.responseText, "text/html");
            if (doc.querySelector('article ul.wiki-list > li') == null)
                return callback([]);
            var logs = doc.querySelectorAll('article ul.wiki-list > li');
            var result = [];
            // get first entry only
            for (var i = 0; i < logs.length; i++) {
                var curLog = logs[i];
                var durationMatch = /\((.+?)\)/.exec(curLog.querySelector('i').nextSibling.textContent.trim());
                var entry = {
                    blocker: curLog.querySelector('strong > a').textContent.trim(),
                    blocked: /^사용자가\s+(.+)/.exec(curLog.querySelector('strong').nextSibling.textContent.trim())[1],
                    duration: durationMatch == null ? null : durationMatch[1],
                    reason: curLog.querySelector('span[style]') ? curLog.querySelector('span[style]').textContent : "",
                    type: /\((.+?)\)/.exec(curLog.querySelector('i').textContent)[1],
                    at: new Date(curLog.querySelector('time').getAttribute('datetime'))
                };
                if (entry.type == "IP 주소 차단") entry.type = "blockIP";
                else if (entry.type == "IP 주소 차단 해제") entry.type = "unblockIP"
                else if (entry.type == "사용자 차단") entry.type = "blockUser";
                else if (entry.type == "사용자 차단 해제") entry.type = "unblockUser";
                result.push(entry);
            }
            callback(result);
        }
    })
}

// sendUploadReq
namuapi.uploadImage = function (data, callback) {
    var query = new FormData();
    query.append('file', data.file);
    query.append('document', data.fn);
    query.append('text', data.docuText);
    query.append('log', data.log);
    query.append('baserev', 0);
    query.append('identifier', data.identifier); // (ENV.IsLoggedIn ? "m" : "i") + ":" + ENV.UserName
    if (data.recaptchaKey !== null)
        query.append('g-recaptcha-response', data.recaptchaKey);
    namuapi.theseedRequest({
        method: 'POST',
        url: 'https://' + location.host + '/Upload',
        headers: {
            "Referer": 'https://' + location.host + '/Upload'
        },
        data: query,
        onload: function (res) {
            var parser = new DOMParser();
            if (parser.parseFromString(res.responseText, "text/html").querySelector("p.wiki-edit-date") != null) {
                callback(null, fn);
            } else if (res.responseText.indexOf('CAPTCHA를 체크하지 않은 경우입니다.') != -1) {
                callback("recaptcha_required");
            } else {
                callback("html_error", res.responseText);
            }
        }
    });
}<commit_msg>Add brackets<commit_after>var namuapi = {};

// /check 페이지 대응
namuapi.theseedRequest = function (options) {
    var _newoptions = {};
    for (var i in options) {
        if (i !== "onload") {
            _newoptions[i] = options[i];
        } else {
            _newoptions.onload = function (res) {
                console.log('[NamuFix] 위키 측으로부터 응답 받음.');
                var aTagForParsingUrl = document.createElement(res.finalUrl);
                if (aTagForParsingUrl.pathname.indexOf("/check") === 0) {
                    console.log('[NamuFix] /check 페이지 감지됨.');
                    namuapi.resolveRecaptcha(function (capKeyRes) {
                        if (capKeyRes == null) {
                            namuapi.theseedRequest(options);
                        } else {
                            var formData = new FormData();
                            formData.append("g-recaptcha-response", capKeyRes);
                            GM_xmlhttpRequest({
                                url: aTagForParsingUrl.href,
                                method: 'POST',
                                data: formData,
                                headers: {
                                    'Content-Type': 'application/x-www-form-urlencoded'
                                },
                                onload: function (checkRes) {
                                    console.log('[NamuFix] /check페이지에 g-recaptcha-response 전송함. 요청 재진행중...');
                                    namuapi.theseedRequest(options);
                                }
                            })
                        }
                    })
                } else {
                    options.onload(res);
                }
            };
        }
    }
    GM_xmlhttpRequest(_newoptions);
}

namuapi.resolveRecaptcha = function (callback) {
    GM_xmlhttpRequest({
        method: 'GET',
        url: 'https://' + location.host + '/check',
        onload: function (res) {
            var siteKey = /["']sitekey["']: ["']([^"']+)["']/.exec(res.responseText)[1];
            var captchaWin = TooSimplePopup();
            captchaWin.title('reCAPTCHA 해결');
            captchaWin.content(function (winContainer) {
                var id = "nf-recaptcha-" + Date.now();
                var btnId = 'nf-communicate-' + Date.now();
                var cbName = "nfreCAPTCHACallback" + Date.now();
                winContainer.innerHTML = '
reCAPTCHA를 해결해주세요.

<button style="display: none;" type="button" id="' + btnId + '"></button>';
                var injectedButton = winContainer.querySelector('#' + btnId);
                winContainer.querySelector('#' + id).dataset.callback = cbName;
                winContainer.querySelector('#' + id).dataset.sitekey = siteKey;
                injectedButton.addEventListener('click', function (evt) {
                    evt.preventDefault();
                    callback(injectedButton.dataset.recaptchaResponse);
                    captchaWin.close();
                })
                var scriptTag = document.createElement("script");
                scriptTag.innerHTML = 'function ' + cbName + '(recaptcha_response){var btn = document.getElementById("' + btnId + '"); btn.dataset.recaptchaResponse = recaptcha_response; btn.click();}function renderNFReCAPTCHA(){if(!window.grecaptcha) return setTimeout(renderNFReCAPTCHA, 200); window.grecaptcha.render(document.getElementById("' + id + '"));} setTimeout(renderNFReCAPTCHA, 200);';
                winContainer.appendChild(scriptTag);
            });
            captchaWin.button('닫기', function () {
                callback(null);
                captchaWin.close();
            })
        }
    });
}

// getRAW
namuapi.raw = function (title, onfound, onnotfound) {
    namuapi.theseedRequest({
        method: 'GET',
        url: 'https://' + location.host + '/raw/' + title,
        onload: function (res) {
            if (res.status == 404) {
                onnotfound(title);
                return;
            }
            onfound(res.responseText, title);
        }
    })
}

namuapi.searchBlockHistory = function (query, isAuthor, callback) {
    namuapi.theseedRequest({
        method: 'GET',
        url: 'https://' + location.host + '/BlockHistory?target=' + (isAuthor ? "author" : "text") + '&query=' + encodeURIComponent(query),
        onload: function (res) {
            var parser = new DOMParser();
            var doc = parser.parseFromString(res.responseText, "text/html");
            if (doc.querySelector('article ul.wiki-list > li') == null)
                return callback([]);
            var logs = doc.querySelectorAll('article ul.wiki-list > li');
            var result = [];
            // get first entry only
            for (var i = 0; i < logs.length; i++) {
                var curLog = logs[i];
                var durationMatch = /\((.+?)\)/.exec(curLog.querySelector('i').nextSibling.textContent.trim());
                var entry = {
                    blocker: curLog.querySelector('strong > a').textContent.trim(),
                    blocked: /^사용자가\s+(.+)/.exec(curLog.querySelector('strong').nextSibling.textContent.trim())[1],
                    duration: durationMatch == null ? null : durationMatch[1],
                    reason: curLog.querySelector('span[style]') ? curLog.querySelector('span[style]').textContent : "",
                    type: /\((.+?)\)/.exec(curLog.querySelector('i').textContent)[1],
                    at: new Date(curLog.querySelector('time').getAttribute('datetime'))
                };
                if (entry.type == "IP 주소 차단") entry.type = "blockIP";
                else if (entry.type == "IP 주소 차단 해제") entry.type = "unblockIP"
                else if (entry.type == "사용자 차단") entry.type = "blockUser";
                else if (entry.type == "사용자 차단 해제") entry.type = "unblockUser";
                result.push(entry);
            }
            callback(result);
        }
    })
}

// sendUploadReq
namuapi.uploadImage = function (data, callback) {
    var query = new FormData();
    query.append('file', data.file);
    query.append('document', data.fn);
    query.append('text', data.docuText);
    query.append('log', data.log);
    query.append('baserev', 0);
    query.append('identifier', data.identifier); // (ENV.IsLoggedIn ? "m" : "i") + ":" + ENV.UserName
    if (data.recaptchaKey !== null)
        query.append('g-recaptcha-response', data.recaptchaKey);
    namuapi.theseedRequest({
        method: 'POST',
        url: 'https://' + location.host + '/Upload',
        headers: {
            "Referer": 'https://' + location.host + '/Upload'
        },
        data: query,
        onload: function (res) {
            var parser = new DOMParser();
            if (parser.parseFromString(res.responseText, "text/html").querySelector("p.wiki-edit-date") != null) {
                callback(null, fn);
            } else if (res.responseText.indexOf('CAPTCHA를 체크하지 않은 경우입니다.') != -1) {
                callback("recaptcha_required");
            } else {
                callback("html_error", res.responseText);
            }
        }
    });
}<|endoftext|>


<commit_before>$(document).ready(function() {
    search("");

    $(".annuaire").on("click", ".result h2",function(){
        $(this).next("div").toggle();
    })

    $('#search').keyup(function(){
        search($("#search").val());
    });

    $(window).load(function() {
        Pizza.init();
        $(document).foundation();
    });

    function search(motclef){
        $("#results").empty();
        if(motclef!==""){
            var search = "/web/annuaire.json?search="+motclef;
        }
        else{
            var search = "/web/annuaire.json";
        }

        $.get(search, function(data){
            var results=$("<div>");
            $.each( data, function( key, val ) {
                var title=$("<h2>");
                title.html(val.title);
                var id=val.id;
                var description=$("<p>").html(val.description);
                var linkDetail=$("<a>").attr("href",val.link).html(val.link);
                var link=$("<p>").append("Site: ").append(linkDetail);
                var phone=$("<p>").html("Tel: "+val.phone);
                var adress=$("<p>").html(val.address);
                var place=val.place;
                var grade=val.grade;
                var detail=$("<div>").addClass("detail").attr("style","display:none;");

                if(description.text().length>10) detail.append(description);
                if(link.text().length>10) detail.append(link);
                if(adress.text().length>10)detail.append(adress);
                if(phone.text().length>15) detail.append(phone);

                var result=$("<div>").addClass("result").attr("data-id",id).append(title).append(detail);
                results.append(result);
            });
            $("#results").empty();
            $("#results").append(results);
        })
    }

});<commit_msg>affichage petits nums de tel widget<commit_after>$(document).ready(function() {
    search("");

    $(".annuaire").on("click", ".result h2",function(){
        $(this).next("div").toggle();
    })

    $('#search').keyup(function(){
        search($("#search").val());
    });

    $(window).load(function() {
        Pizza.init();
        $(document).foundation();
    });

    function search(motclef){
        $("#results").empty();
        if(motclef!==""){
            var search = "/web/annuaire.json?search="+motclef;
        }
        else{
            var search = "/web/annuaire.json";
        }

        $.get(search, function(data){
            var results=$("<div>");
            $.each( data, function( key, val ) {
                var title=$("<h2>");
                title.html(val.title);
                var id=val.id;
                var description=$("<p>").html(val.description);
                var linkDetail=$("<a>").attr("href",val.link).html(val.link);
                var link=$("<p>").append("Site: ").append(linkDetail);
                var phone=$("<p>").html("Tel: "+val.phone);
                var adress=$("<p>").html(val.address);
                var place=val.place;
                var grade=val.grade;
                var detail=$("<div>").addClass("detail").attr("style","display:none;");

                if(description.text().length>10) detail.append(description);
                if(link.text().length>10) detail.append(link);
                if(adress.text().length>10)detail.append(adress);
                if(phone.text().length>17) detail.append(phone);

                var result=$("<div>").addClass("result").attr("data-id",id).append(title).append(detail);
                results.append(result);
            });
            $("#results").empty();
            $("#results").append(results);
        })
    }

});<|endoftext|>


<commit_before>var env = {
    envType: "prod",
    envVersion:"2007-09-08 14:46",
    appType: (window.location.protocol == "file:")?"cordova":"webapp",

    cswService:"https://oim.dpaw.wa.gov.au/catalogue/api/records/",
    catalogueAdminService:"https://oim.dpaw.wa.gov.au",

    wmtsService:"https://kmi.dpaw.wa.gov.au/geoserver/gwc/service/wmts",
    wmsService:"https://kmi.dpaw.wa.gov.au/geoserver/wms",
    wfsService:"https://kmi.dpaw.wa.gov.au/geoserver/wfs",
    legendSrc:"https://kmi.dpaw.wa.gov.au/geoserver/gwc/service/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&FORMAT=image/png&legend_options=fontName:Times%20New%20Roman;fontAntiAliasing:true;fontSize:14;bgColor:0xFFFFEE;dpi:120;labelMargin:10&LAYER=",

    gokartService:"https://sss.dpaw.wa.gov.au",
    resourceTrackingService:"https://resourcetracking.dpaw.wa.gov.au",
    bfrsService:"https://bfrs.dpaw.wa.gov.au",
    staticService:"https://static.dpaw.wa.gov.au",

    s3Service:"http://gokart.dpaw.io/",

    bushfireListLayer:"dpaw:bushfirelist_latest",

    bushfireLayer:"dpaw:bushfire_latest",
    finalFireboundaryLayer:"dpaw:bushfire_final_fireboundary_latest",
    fireboundaryLayer:"dpaw:bushfire_fireboundary_latest",

    allBushfireLayer:"dpaw:bushfire",
    allFireboundaryLayer:"dpaw:bushfire_fireboundary"
};
<commit_msg>Update production env file<commit_after>var env = {
    envType: "prod",
    envVersion:"2008-02-21 21:48",
    appType: (window.location.protocol == "file:")?"cordova":"webapp",

    cswService:"https://oim.dpaw.wa.gov.au/catalogue/api/records/",
    catalogueAdminService:"https://oim.dpaw.wa.gov.au",

    wmtsService:"https://kmi.dpaw.wa.gov.au/geoserver/gwc/service/wmts",
    wmsService:"https://kmi.dpaw.wa.gov.au/geoserver/wms",
    wfsService:"https://kmi.dpaw.wa.gov.au/geoserver/wfs",
    legendSrc:"https://kmi.dpaw.wa.gov.au/geoserver/gwc/service/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&FORMAT=image/png&legend_options=fontName:Times%20New%20Roman;fontAntiAliasing:true;fontSize:14;bgColor:0xFFFFEE;dpi:120;labelMargin:10&LAYER=",

    gokartService:"https://sss.dpaw.wa.gov.au",
    resourceTrackingService:"https://resourcetracking.dpaw.wa.gov.au",
    bfrsService:"https://bfrs.dpaw.wa.gov.au",
    staticService:"https://static.dpaw.wa.gov.au",

    s3Service:"http://gokart.dpaw.io/",

    appMapping:{
    },
    layerMapping:{
    },
};
<|endoftext|>


<commit_before>/*
 *  asf -- Ada Server Faces
 *  Copyright (C) 2009, 2010, 2011 Stephane Carrez
 *  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
var ASF = {};

(function () {
    /**
     * Execute the AJAX response action represented by the JSON object action.
     *
     * @param node the current node
     * @param action the JSON action object
     */
    ASF.ExecuteOne = function(node, action) {
        if (action.action === "update") {
	        $(action.id).html(action.data);

        } else if (action.action === "show") {
            $(action.id).show('slow');

        } else if (action.action === "hide") {
            $(action.id).hide('slow');

        } else if (action.action === "delete") {
	        $(action.id).remove();

        } else if (action.action === "removeClass") {
	        $(action.id).removeClass(action.data);

        } else if (action.action === "addClass") {
	        $(action.id).addClass(action.data);

        } else if (action.action === "fadeIn") {
            $(action.id).fadeIn('slow');

        } else if (action.action === "fadeOut") {
            $(action.id).fadeOut('slow');

        } else if (action.action === "slideUp") {
            $(action.id).slideUp('slow');

        } else if (action.action === "slideDown") {
            $(action.id).slideDown('slow');

        } else if (action.action === "closeDialog") {
            $(action.id).dialog('close');

        } else if (action.action === "redirect") {
            document.location = action.url;
	    }
    };

    ASF.Execute = function(node, data) {
        if (data != null) {
            for (var i = 0; i < data.length; i++) {
                ASF.ExecuteOne(node, data[i]);
            }
        }
    };

    /**
     * Update the target container with the content of the AJAX GET request
     * on the given URL.  The target parameter is optional.
     *
     * @param node the current element
     * @param url the URL to fetch using an HTTP GET
     * @param target the optional target element
     */
    ASF.Update = function(node, url, target) {
        /* Find the container to update */
        var d;
        if (target != null) {
            d = $(target);
        } else {
            d = $(node);
            if (!d.is('.asf-container')) {
                d = d.parent('.asf-container');
            }
        }
        if (d.length > 0) {
            /* Perform the HTTP GET */
            jQuery.ajax({
                url: url,
                context: document.body,
                success: function(data, status, jqXHDR) {
                    var contentType = jqXHDR.getResponseHeader('Content-type');
                    if (contentType == null) {
                        contentType = "text/html";
                    }
                    if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                        d.html(jqXHDR.responseText);

                    } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                        ASF.Execute(node, data);
                    }
               }
            });
        }
    };

    /**
     * Submit the current form.  The node element refers to the element being clicked.
     * From that element, we can identify the form to submit.  The element to refresh upon
     * the form submit is an outer element that should have the asf-container class.
     * If not such element as parent node, the parent node of the form is used.
     *
     * After the form is submitted, the response is executed if it is a JSON response.
     * If the response is an HTML content, the container element is refreshed with it.
     *
     * @param node the current element
     * @param url the URL to fetch using an HTTP GET
     * @param target the optional target element
     */
    ASF.Submit = function(node) {
        /* Find the form and container to update */
        var f = $(node).closest("form");
        var d = $(f);
        if (!d.is('.asf-container,ui-dialog-content')) {
            d = d.closest('.asf-container,.ui-dialog-content');
        }
        if (d.length == 0) {
            d = $(f).parent();
        }
        if (d.length > 0) {
            var params;
            var params = $(f).serialize();
            var url = $(f).attr('action');

            if (node.tagName == 'a' || node.tagName == 'A') {
                params = node.id + "=1&" + $(f).serialize();
            } else {
                params = node.name + "=1&" + $(f).serialize();
            }
            /* Perform the HTTP POST */
            jQuery.ajax({
                type: "POST",
                url: url,
                data: params,
                context: document.body,
                success: function(data, status, jqXHDR) {
                    var contentType = jqXHDR.getResponseHeader('Content-type');
                    if (contentType == null) {
                        contentType = "text/html";
                    }
                    if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                        d.html(jqXHDR.responseText);

                    } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                        ASF.Execute(node, data);
                    }
               }
            });
        }
        return false;
    };

    /**
     * Open a dialog box and fetch the dialog content from the given URI.
     *
     * @param node the current element
     * @param id the dialog id
     * @param url the URL to fetch using an HTTP GET
     * @param params the optional dialog options
     */
    ASF.OpenDialog = function(node, id, url, params) {
        var div = $(id);
        if (div.length > 0) {
            return false;
        }

        div = document.createElement("div");
        div.id = id;
        div = $(div);

        var d = $(document);
        if (d.length == 0) {
            return false;
        }

        $(d).append($(div));

        /* Perform the HTTP GET */
        jQuery.ajax({
            url: url,
            context: document.body,
            success: function(data, status, jqXHDR) {
                var contentType = jqXHDR.getResponseHeader('Content-type');
                if (contentType == null) {
                    contentType = "text/html";
                }
                if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                    $(div).dialog({
                        autoOpen: false,
                        show: "blind",
                        hide: "explode",
                        minWidth: 500,
                        close: function() {
                            $(div).dialog('destroy');
                            $(div).remove();
                        }
                     });

                     $(div).html(jqXHDR.responseText);
                     var dTitle = $(div).children('div').attr('title');
                     if (dTitle != null) {
                        $(div).dialog("option", "title", dTitle );
                        /* $(div).attr('title', title); */
                     }
                     $(div).dialog('open');

                } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                    ASF.Execute(node, data);
                }
            }
        });
        return false;
    };

})();

<commit_msg>Add JSON action to append and prepend some HTML to after/before an existing element<commit_after>/*
 *  asf -- Ada Server Faces
 *  Copyright (C) 2009, 2010, 2011 Stephane Carrez
 *  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
var ASF = {};

(function () {
    /**
     * Execute the AJAX response action represented by the JSON object action.
     *
     * @param node the current node
     * @param action the JSON action object
     */
    ASF.ExecuteOne = function(node, action) {
        if (action.action === "update") {
	        $(action.id).html(action.data);

        } else if (action.action === "prepend") {
	        $(action.id).prepend(action.data);

        } else if (action.action === "append") {
	        $(action.id).append(action.data);

        } else if (action.action === "show") {
            $(action.id).show('slow');

        } else if (action.action === "hide") {
            $(action.id).hide('slow');

        } else if (action.action === "delete") {
	        $(action.id).remove();

        } else if (action.action === "removeClass") {
	        $(action.id).removeClass(action.data);

        } else if (action.action === "addClass") {
	        $(action.id).addClass(action.data);

        } else if (action.action === "fadeIn") {
            $(action.id).fadeIn('slow');

        } else if (action.action === "fadeOut") {
            $(action.id).fadeOut('slow');

        } else if (action.action === "slideUp") {
            $(action.id).slideUp('slow');

        } else if (action.action === "slideDown") {
            $(action.id).slideDown('slow');

        } else if (action.action === "closeDialog") {
            $(action.id).dialog('close');

        } else if (action.action === "redirect") {
            document.location = action.url;
	    }
    };

    ASF.Execute = function(node, data) {
        if (data != null) {
            for (var i = 0; i < data.length; i++) {
                ASF.ExecuteOne(node, data[i]);
            }
        }
    };

    /**
     * Update the target container with the content of the AJAX GET request
     * on the given URL.  The target parameter is optional.
     *
     * @param node the current element
     * @param url the URL to fetch using an HTTP GET
     * @param target the optional target element
     */
    ASF.Update = function(node, url, target) {
        /* Find the container to update */
        var d;
        if (target != null) {
            d = $(target);
        } else {
            d = $(node);
            if (!d.is('.asf-container')) {
                d = d.parent('.asf-container');
            }
        }
        if (d.length > 0) {
            /* Perform the HTTP GET */
            jQuery.ajax({
                url: url,
                context: document.body,
                success: function(data, status, jqXHDR) {
                    var contentType = jqXHDR.getResponseHeader('Content-type');
                    if (contentType == null) {
                        contentType = "text/html";
                    }
                    if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                        d.html(jqXHDR.responseText);

                    } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                        ASF.Execute(node, data);
                    }
               }
            });
        }
    };

    /**
     * Submit the current form.  The node element refers to the element being clicked.
     * From that element, we can identify the form to submit.  The element to refresh upon
     * the form submit is an outer element that should have the asf-container class.
     * If not such element as parent node, the parent node of the form is used.
     *
     * After the form is submitted, the response is executed if it is a JSON response.
     * If the response is an HTML content, the container element is refreshed with it.
     *
     * @param node the current element
     * @param url the URL to fetch using an HTTP GET
     * @param target the optional target element
     */
    ASF.Submit = function(node) {
        /* Find the form and container to update */
        var f = $(node).closest("form");
        var d = $(f);
        if (!d.is('.asf-container,ui-dialog-content')) {
            d = d.closest('.asf-container,.ui-dialog-content');
        }
        if (d.length == 0) {
            d = $(f).parent();
        }
        if (d.length > 0) {
            var params;
            var params = $(f).serialize();
            var url = $(f).attr('action');

            if (node.tagName == 'a' || node.tagName == 'A') {
                params = node.id + "=1&" + $(f).serialize();
            } else {
                params = node.name + "=1&" + $(f).serialize();
            }
            /* Perform the HTTP POST */
            jQuery.ajax({
                type: "POST",
                url: url,
                data: params,
                context: document.body,
                success: function(data, status, jqXHDR) {
                    var contentType = jqXHDR.getResponseHeader('Content-type');
                    if (contentType == null) {
                        contentType = "text/html";
                    }
                    if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                        d.html(jqXHDR.responseText);

                    } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                        ASF.Execute(node, data);
                    }
               }
            });
        }
        return false;
    };

    /**
     * Open a dialog box and fetch the dialog content from the given URI.
     *
     * @param node the current element
     * @param id the dialog id
     * @param url the URL to fetch using an HTTP GET
     * @param params the optional dialog options
     */
    ASF.OpenDialog = function(node, id, url, params) {
        var div = $(id);
        if (div.length > 0) {
            return false;
        }

        div = document.createElement("div");
        div.id = id;
        div = $(div);

        var d = $(document);
        if (d.length == 0) {
            return false;
        }

        $(d).append($(div));

        /* Perform the HTTP GET */
        jQuery.ajax({
            url: url,
            context: document.body,
            success: function(data, status, jqXHDR) {
                var contentType = jqXHDR.getResponseHeader('Content-type');
                if (contentType == null) {
                    contentType = "text/html";
                }
                if (contentType.match(/^text\/(html|xml)(;.*)?$/i)) {
                    $(div).dialog({
                        autoOpen: false,
                        show: "blind",
                        hide: "explode",
                        minWidth: 500,
                        close: function() {
                            $(div).dialog('destroy');
                            $(div).remove();
                        }
                     });

                     $(div).html(jqXHDR.responseText);
                     var dTitle = $(div).children('div').attr('title');
                     if (dTitle != null) {
                        $(div).dialog("option", "title", dTitle );
                        /* $(div).attr('title', title); */
                     }
                     $(div).dialog('open');

                } else if (contentType.match(/^application\/json(;.*)?$/i)) {
                    ASF.Execute(node, data);
                }
            }
        });
        return false;
    };

})();

<|endoftext|>


<commit_before>const FBSDK = require('react-native-fbsdk')

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native'
const {
  LoginButton,
  ShareDialog,
  AccessToken,
} = FBSDK

import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

export default class nap extends Component {
  constructor(props) {
    super(props)
    const shareLinkContent = {
      contentType: 'link',
      contentUrl: 'https://www.facebook.com/',
    }

    this.state = {
      shareLinkContent: shareLinkContent,
      isLogin: false,
      name: ''
    }
  }

  shareLinkWithShareDialog() {
    var tmp = this
    ShareDialog.canShow(this.state.shareLinkContent).then(
      function (canShow) {
        if (canShow) {
          return ShareDialog.show(tmp.state.shareLinkContent)
        }
      }
    ).then(
      function (result) {
        if (result.isCancelled) {
          alert('Share cancelled')
        } else {
          alert('Share success with postId: '
            + result.postId)
        }
      },
      function (error) {
        alert('Share fail with error: ' + error)
      }
      )
  }

  onLoginFinished(error, result) {
    if (error) {
      alert("login has error: " + result.error)
    } else if (result.isCancelled) {
      alert("login is cancelled.")
    } else {
      AccessToken.getCurrentAccessToken().then(
        (data) => {
          // TODO : Handle bad token
          const access_token = data.accessToken.toString()
          console.log('access_token :', access_token)

          // TODO : Secure header?
          access_token && fetch(`http://localhost:3000/auth/facebook/token`,
            {
              method: 'post',
              headers: {
                'Authorization': `Bearer ${access_token}`
              }
            }
          ).then((response) => {
            if (response.status >= 400) {
              throw new Error("Bad response from server")
            }
            return response.text()
          }).then((text) => {
            console.log(text)
            this.setState({ isLogin: true })
          })
        }
      )
    }
  }

  render() {

    const query = gql`{
      userOne {
        name
      }
    }`

    const UserProfile = ({ data }) => this.state.isLogin ?
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Name: {data.userOne && data.userOne.name}</Text>
      </View>
      :
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Please log in</Text>
      </View>

    const ViewWithData = graphql(query, {
      options: { variables: { name: this.state.name } }
    })(UserProfile)

    return (
      <View style={styles.container}>
        <LoginButton
          onLoginFinished={this.onLoginFinished.bind(this)}
          onLogoutFinished={() => alert("logout.")} />
        <ViewWithData />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  shareText: {
    fontSize: 20,
    margin: 10,
  },
})<commit_msg>Correct typo<commit_after>const FBSDK = require('react-native-fbsdk')

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native'
const {
  LoginButton,
  ShareDialog,
  AccessToken,
} = FBSDK

import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

export default class nap extends Component {
  constructor(props) {
    super(props)
    const shareLinkContent = {
      contentType: 'link',
      contentUrl: 'https://www.facebook.com/',
    }

    this.state = {
      shareLinkContent: shareLinkContent,
      isLoggedIn: false,
      name: ''
    }
  }

  shareLinkWithShareDialog() {
    var tmp = this
    ShareDialog.canShow(this.state.shareLinkContent).then(
      function (canShow) {
        if (canShow) {
          return ShareDialog.show(tmp.state.shareLinkContent)
        }
      }
    ).then(
      function (result) {
        if (result.isCancelled) {
          alert('Share cancelled')
        } else {
          alert('Share success with postId: '
            + result.postId)
        }
      },
      function (error) {
        alert('Share fail with error: ' + error)
      }
      )
  }

  onLoginFinished(error, result) {
    if (error) {
      alert("login has error: " + result.error)
    } else if (result.isCancelled) {
      alert("login is cancelled.")
    } else {
      AccessToken.getCurrentAccessToken().then(
        (data) => {
          // TODO : Handle bad token
          const access_token = data.accessToken.toString()
          console.log('access_token :', access_token)

          // TODO : Secure header?
          access_token && fetch(`http://localhost:3000/auth/facebook/token`,
            {
              method: 'post',
              headers: {
                'Authorization': `Bearer ${access_token}`
              }
            }
          ).then((response) => {
            if (response.status >= 400) {
              throw new Error("Bad response from server")
            }
            return response.text()
          }).then((text) => {
            console.log(text)
            this.setState({ isLoggedIn: true })
          })
        }
      )
    }
  }

  render() {

    const query = gql`{
      userOne {
        name
      }
    }`

    const UserProfile = ({ data }) => this.state.isLoggedIn ?
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Name: {data.userOne && data.userOne.name}</Text>
      </View>
      :
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Please log in</Text>
      </View>

    const ViewWithData = graphql(query, {
      options: { variables: { name: this.state.name } }
    })(UserProfile)

    return (
      <View style={styles.container}>
        <LoginButton
          onLoginFinished={this.onLoginFinished.bind(this)}
          onLogoutFinished={() => alert("logout.")} />
        <ViewWithData />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  shareText: {
    fontSize: 20,
    margin: 10,
  },
})<|endoftext|>


<commit_before>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
var params = new URLSearchParams(window.location.search);
var position = {
    pageX: 0,
    pageY: 0,
    path: params.get('path')
};
function savePosition () {
    sessionStorage.setItem('position', JSON.stringify(position));
};
function loadPosition (){
    var savedPosition = sessionStorage.getItem('position');
    if (savedPosition && savedPosition != "undefined"){
        position = JSON.parse(savedPosition)
    }
};
window.onscroll = function (event){
    position.pageX = event.pageX;
    position.pageY = event.pageY;
};
window.onload = function (){
    loadPosition();
};
(() => {
    let shelf = {};
    let contents = {};

    function linkCodeBlocks(elem, linkable = true) {
        codeworldKeywords = {};
        registerStandardHints(() => {
            let pres = elem.getElementsByTagName('pre');
            for (let i = 0; i < pres.length; ++i) {
                (() => {
                    let pre = pres[i];

                    // Markdeep buries the class annotations a bit, so we dig.
                    let clickable =
                        pre.classList.contains('clickable') ||
                        (pre.firstChild && pre.firstChild.classList &&
                            pre.firstChild.classList.contains(
                                'clickable')) ||
                        (pre.firstChild && pre.firstChild.firstChild &&
                            pre.firstChild.firstChild.classList &&
                            pre.firstChild.firstChild.classList
                            .contains('clickable'));

                    let text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, {
                        name: 'codeworld',
                        overrideKeywords: codeworldKeywords
                    }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable && clickable) {
                        pre.classList.add('clickable');
                        pre.onclick = () => {
                            if (env && env.loadSample) {
                                env.loadSample(text);
                            }
                        }
                    }
                })();
            }
        });
    }

    function activateCollapsible(root) {
        let elems = root.getElementsByClassName('collapsible');
        for (let i = 0; i < elems.length; ++i) {
            let elem = elems[i];
            elem.onclick = () => {
                if (elem.classList.contains('expanded')) {
                    elem.classList.remove('expanded');
                } else {
                    elem.classList.add('expanded');
                }
            }
        }
    }

    function linkFunBlocks(elem) {
        let blocks = elem.getElementsByTagName('xml');
        let i = 0;

        while (blocks != null && blocks.length > 0) {
            let block = blocks[0];
            let text = block.outerHTML;

            let iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", () => {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow,
                    text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            let parent = block.parentNode;
            parent.insertBefore(iframe, block);
            parent.removeChild(block);

            blocks = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        let contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        let elems = body.getElementsByTagName('*');

        let currentLevel = 0;
        let currentElem = contents;
        let n = 0;
        for (let i = 0; i < elems.length; ++i) {
            let header = elems[i];
            let match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            let level = parseInt(match[1]);

            while (currentLevel < level) {
                let sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            let anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            let li = document.createElement('li');
            let link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        let popdiv = document.createElement('div');
        popdiv.id = 'popout';
        popdiv.style = 'text-align: right';
        let popout = document.createElement('a');
        popout.innerHTML =
            ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = e => {
            let tab = open(this.href);
            tab.addEventListener("load", () => {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
                if (parent.sweetAlert2) {
                    parent.sweetAlert2.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        let elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                let url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function removeCallStacks(node) {
        if (node.nodeType == Node.TEXT_NODE) {
            node.nodeValue = node.nodeValue.replace(/HasCallStack => /, '');
        } else {
            for (let child of node.childNodes) removeCallStacks(child);
        }
    }

    function setContent(elem) {
        let help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)
        document.body.scrollTop = 0;
        if (document.firstElementChild) document.firstElementChild.scrollTop =
            0;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];
        position.path = path;
        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            let request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = () => {
                if (request.readyState != 4) {
                    return;
                }

                let source = new URL(path, location.href);
                let content = document.createElement('div');
                let raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = window.markdeep.format(raw,
                        false);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                        activateCollapsible(content);
                    } else {
                        linkCodeBlocks(content);
                        activateCollapsible(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                    removeCallStacks(content);
                }

                let spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }

                setContent(content);
                window.scrollTo(position.pageX, position.pageY);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        let path = position.path;
        if (!path) path = shelf.default;

        let activeIndex = false;

        let acc = document.createElement('div')
        acc.id = 'helpacc';

        let paneNum = 0;
        for (let doc in shelf.named) {
            let hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            let entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: (event, ui) => {
                let name = ui.newHeader.text();
                let path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    let markdeepStyle = document.createElement('style');
    document.head.appendChild(markdeepStyle);
    markdeepStyle.outerHTML = window.markdeep.stylesheet();

    if (params.get('shelf')) {
        let request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = () => {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(position.path);
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<commit_msg>Fix bug with frozen position when user clicks over tutorial.<commit_after>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
var params = new URLSearchParams(window.location.search);
var position = {
    pageX: 0,
    pageY: 0,
    path: params.get('path')
};
function savePosition () {
    sessionStorage.setItem('position', JSON.stringify(position));
};
function loadPosition (){
    var savedPosition = sessionStorage.getItem('position');
    if (savedPosition && savedPosition != "undefined"){
        position = JSON.parse(savedPosition)
    }
};
window.onscroll = function (event){
    position.pageX = event.pageX;
    position.pageY = event.pageY;
};
window.onload = function (){
    loadPosition();
};
(() => {
    let shelf = {};
    let contents = {};

    function linkCodeBlocks(elem, linkable = true) {
        codeworldKeywords = {};
        registerStandardHints(() => {
            let pres = elem.getElementsByTagName('pre');
            for (let i = 0; i < pres.length; ++i) {
                (() => {
                    let pre = pres[i];

                    // Markdeep buries the class annotations a bit, so we dig.
                    let clickable =
                        pre.classList.contains('clickable') ||
                        (pre.firstChild && pre.firstChild.classList &&
                            pre.firstChild.classList.contains(
                                'clickable')) ||
                        (pre.firstChild && pre.firstChild.firstChild &&
                            pre.firstChild.firstChild.classList &&
                            pre.firstChild.firstChild.classList
                            .contains('clickable'));

                    let text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, {
                        name: 'codeworld',
                        overrideKeywords: codeworldKeywords
                    }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable && clickable) {
                        pre.classList.add('clickable');
                        pre.onclick = () => {
                            if (env && env.loadSample) {
                                env.loadSample(text);
                            }
                        }
                    }
                })();
            }
        });
    }

    function activateCollapsible(root) {
        let elems = root.getElementsByClassName('collapsible');
        for (let i = 0; i < elems.length; ++i) {
            let elem = elems[i];
            elem.onclick = () => {
                if (elem.classList.contains('expanded')) {
                    elem.classList.remove('expanded');
                } else {
                    elem.classList.add('expanded');
                }
            }
        }
    }

    function linkFunBlocks(elem) {
        let blocks = elem.getElementsByTagName('xml');
        let i = 0;

        while (blocks != null && blocks.length > 0) {
            let block = blocks[0];
            let text = block.outerHTML;

            let iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", () => {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow,
                    text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            let parent = block.parentNode;
            parent.insertBefore(iframe, block);
            parent.removeChild(block);

            blocks = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        let contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        let elems = body.getElementsByTagName('*');

        let currentLevel = 0;
        let currentElem = contents;
        let n = 0;
        for (let i = 0; i < elems.length; ++i) {
            let header = elems[i];
            let match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            let level = parseInt(match[1]);

            while (currentLevel < level) {
                let sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            let anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            let li = document.createElement('li');
            let link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        let popdiv = document.createElement('div');
        popdiv.id = 'popout';
        popdiv.style = 'text-align: right';
        let popout = document.createElement('a');
        popout.innerHTML =
            ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = e => {
            let tab = open(this.href);
            tab.addEventListener("load", () => {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
                if (parent.sweetAlert2) {
                    parent.sweetAlert2.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        let elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                let url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function removeCallStacks(node) {
        if (node.nodeType == Node.TEXT_NODE) {
            node.nodeValue = node.nodeValue.replace(/HasCallStack => /, '');
        } else {
            for (let child of node.childNodes) removeCallStacks(child);
        }
    }

    function setContent(elem) {
        let help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)

        document.body.scrollTop = position.pageY;
        if (document.firstElementChild) document.firstElementChild.scrollTop =
            position.pageY;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];
        position.path = path;
        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            let request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = () => {
                if (request.readyState != 4) {
                    return;
                }

                let source = new URL(path, location.href);
                let content = document.createElement('div');
                let raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = window.markdeep.format(raw,
                        false);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                        activateCollapsible(content);
                    } else {
                        linkCodeBlocks(content);
                        activateCollapsible(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                    removeCallStacks(content);
                }

                let spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }
                setContent(content);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        let path = position.path;
        if (!path) path = shelf.default;

        let activeIndex = false;

        let acc = document.createElement('div')
        acc.id = 'helpacc';

        let paneNum = 0;
        for (let doc in shelf.named) {
            let hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            let entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: (event, ui) => {
                position.pageX = 0;
                position.pageY = 0;
                let name = ui.newHeader.text();
                let path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    let markdeepStyle = document.createElement('style');
    document.head.appendChild(markdeepStyle);
    markdeepStyle.outerHTML = window.markdeep.stylesheet();

    if (params.get('shelf')) {
        let request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = () => {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(position.path);
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<|endoftext|>


<commit_before>const config = require('./vue/UIconfig');

const koa = require('koa');
const serve = require('koa-static');
const cors = require('koa-cors');
const _ = require('lodash');
const bodyParser = require('koa-bodyparser');

const opn = require('opn');
const server = require('http').createServer();
const router = require('koa-router')();
const ws = require('ws');
const app = koa();

const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ server: server });

const cache = require('./state/cache');
const ListManager = require('./state/listManager');

require('./supportsTalib');

// broadcast function
const broadcast = data => {
  if(_.isEmpty(data))
    return;

  _.each(
    wss.clients,
    client => client.send(JSON.stringify(data))
  );
}
cache.set('broadcast', broadcast);

// initialize lists and dump into cache
cache.set('imports', new ListManager);
cache.set('gekkos', new ListManager);
cache.set('apiKeyManager', require('./apiKeyManager'));

// setup API routes

const WEBROOT = __dirname + '/';
const ROUTE = n => WEBROOT + 'routes/' + n;

// attach routes
const apiKeys = require(ROUTE('apiKeys'));
router.get('/api/strategies', require(ROUTE('strategies')));
router.get('/api/configPart/:part', require(ROUTE('configPart')));
router.get('/api/apiKeys', apiKeys.get);

const listWraper = require(ROUTE('list'));
router.get('/api/imports', listWraper('imports'));
router.get('/api/gekkos', listWraper('gekkos'));
router.get('/api/exchanges', require(ROUTE('exchanges')));

router.post('/api/addApiKey', apiKeys.add);
router.post('/api/removeApiKey', apiKeys.remove);
router.post('/api/scan', require(ROUTE('scanDateRange')));
router.post('/api/scansets', require(ROUTE('scanDatasets')));
router.post('/api/backtest', require(ROUTE('backtest')));
router.post('/api/import', require(ROUTE('import')));
router.post('/api/startGekko', require(ROUTE('startGekko')));
router.post('/api/killGekko', require(ROUTE('killGekko')));
router.post('/api/getCandles', require(ROUTE('getCandles')));

// incoming WS:
// wss.on('connection', ws => {
//   ws.on('message', _.noop);
// });

app
  .use(cors())
  .use(serve(WEBROOT + 'vue'))
  .use(bodyParser())
  .use(require('koa-logger')())
  .use(router.routes())
  .use(router.allowedMethods());

server.timeout = config.api.timeout;
server.on('request', app.callback());
server.listen(config.api.port, config.api.host, '::', () => {
  const host = `${config.ui.host}:${config.ui.port}${config.ui.path}`;

  if(config.ui.ssl) {
    var location = `https://${host}`;
  } else {
    var location = `http://${host}`;
  }

  console.log('Serving Gekko UI on ' + location +  '\n');

  // only open a browser when running `node gekko`
  // this prevents opening the browser during development
  let nodeCommand = _.last(process.argv[1].split('/'));
  if(nodeCommand === 'gekko' && !config.headless) {
    try {
      opn(location);
    } catch(e) {}
  }
});
<commit_msg>add default 2 minutes to prevent breaking legacy configs in case timeout isnt specified<commit_after>const config = require('./vue/UIconfig');

const koa = require('koa');
const serve = require('koa-static');
const cors = require('koa-cors');
const _ = require('lodash');
const bodyParser = require('koa-bodyparser');

const opn = require('opn');
const server = require('http').createServer();
const router = require('koa-router')();
const ws = require('ws');
const app = koa();

const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ server: server });

const cache = require('./state/cache');
const ListManager = require('./state/listManager');

require('./supportsTalib');

// broadcast function
const broadcast = data => {
  if(_.isEmpty(data))
    return;

  _.each(
    wss.clients,
    client => client.send(JSON.stringify(data))
  );
}
cache.set('broadcast', broadcast);

// initialize lists and dump into cache
cache.set('imports', new ListManager);
cache.set('gekkos', new ListManager);
cache.set('apiKeyManager', require('./apiKeyManager'));

// setup API routes

const WEBROOT = __dirname + '/';
const ROUTE = n => WEBROOT + 'routes/' + n;

// attach routes
const apiKeys = require(ROUTE('apiKeys'));
router.get('/api/strategies', require(ROUTE('strategies')));
router.get('/api/configPart/:part', require(ROUTE('configPart')));
router.get('/api/apiKeys', apiKeys.get);

const listWraper = require(ROUTE('list'));
router.get('/api/imports', listWraper('imports'));
router.get('/api/gekkos', listWraper('gekkos'));
router.get('/api/exchanges', require(ROUTE('exchanges')));

router.post('/api/addApiKey', apiKeys.add);
router.post('/api/removeApiKey', apiKeys.remove);
router.post('/api/scan', require(ROUTE('scanDateRange')));
router.post('/api/scansets', require(ROUTE('scanDatasets')));
router.post('/api/backtest', require(ROUTE('backtest')));
router.post('/api/import', require(ROUTE('import')));
router.post('/api/startGekko', require(ROUTE('startGekko')));
router.post('/api/killGekko', require(ROUTE('killGekko')));
router.post('/api/getCandles', require(ROUTE('getCandles')));

// incoming WS:
// wss.on('connection', ws => {
//   ws.on('message', _.noop);
// });

app
  .use(cors())
  .use(serve(WEBROOT + 'vue'))
  .use(bodyParser())
  .use(require('koa-logger')())
  .use(router.routes())
  .use(router.allowedMethods());

server.timeout = config.api.timeout||120000;
server.on('request', app.callback());
server.listen(config.api.port, config.api.host, '::', () => {
  const host = `${config.ui.host}:${config.ui.port}${config.ui.path}`;

  if(config.ui.ssl) {
    var location = `https://${host}`;
  } else {
    var location = `http://${host}`;
  }

  console.log('Serving Gekko UI on ' + location +  '\n');

  // only open a browser when running `node gekko`
  // this prevents opening the browser during development
  let nodeCommand = _.last(process.argv[1].split('/'));
  if(nodeCommand === 'gekko' && !config.headless) {
    try {
      opn(location);
    } catch(e) {}
  }
});
<|endoftext|>