<commit_before>CoreGlobalBreadcrumbRibbon = {
    GetInit: function () {
        PnPGlobal.GetUrlChange();
        PnPGlobal.CreateBreadcrumb();
        PnPGlobal.CreateStyle();
        PnPGlobal.LoadSiteBreadcrumb();
        window.addEventListener("DOMContentLoaded", RibbonValidation, false);
    },
    GetUrlChange: function () {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            var element = document.createElement('script');
            var UrlChange = "window.onhashchange = locationHashChanged;function locationHashChanged(){GetUrlDocMDS();}";
            element.innerHTML = UrlChange;
            document.getElementsByTagName('body')[0].appendChild(element);
        }, "sp.js");
    },

    CreateStyle: function () {
        var headID = document.getElementsByTagName("head")[0];
        var cssNode = document.createElement('style');
        cssNode.innerHTML = "#CustomRibbon div{padding-top: 5px; padding-left: 10px; float: left;}.breadcrumb li {display: inline;}.breadcrumb li+li:before {content:\">> \";}";
        headID.appendChild(cssNode);
    },
    CreateBreadcrumb: function () {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            var element = document.createElement('div');
            var context = new SP.ClientContext.get_current();
            var site = context.get_site();
            var web = site.get_rootWeb().get_allProperties();
            context.load(web)
            context.executeQueryAsync(function () {
                var results = JSON.parse(web.get_item('vti_GlobalBreadcrumbRibbon'));
                var breadcrumb = '
';

                for (var i = 0; i < results.Breadcrumb.length; i++) {
                    breadcrumb = breadcrumb + '
' + results.Breadcrumb[i].title + '
';
                }
                breadcrumb = breadcrumb + '
';
                element.innerHTML = breadcrumb;
                var Custombreadcrumb = document.getElementById("s4-bodyContainer");
                Custombreadcrumb.insertBefore(element, Custombreadcrumb.childNodes[0]);

            }, function () { });

        }, "sp.js");
    },
    LoadSiteBreadcrumb: function () {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            var clientcontext = SP.ClientContext.get_current();
            var site = clientcontext.get_site();
            var currentWeb = clientcontext.get_web();
            clientcontext.load(currentWeb, 'ServerRelativeUrl', 'Title', 'ParentWeb', 'Url');
            clientcontext.load(site, 'ServerRelativeUrl');
            clientcontext.executeQueryAsync(
            function () {
                var element = document.createElement('div');
                var breadcrumb = '
';
                breadcrumb = breadcrumb + '
';
                element.innerHTML = breadcrumb;
                var Custombreadcrumb = document.getElementById("s4-bodyContainer");
                Custombreadcrumb.insertBefore(element, Custombreadcrumb.childNodes[0]);
                var li = document.createElement('li');
                li.innerHTML = '' + currentWeb.get_title() + '';
                var Custombreadcrumb = document.getElementById("breadcrumbSite");
                Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
                if (site.get_serverRelativeUrl() !== currentWeb.get_serverRelativeUrl()) {
                    PnPGlobal.RecursiveWeb(currentWeb.get_parentWeb().get_serverRelativeUrl())
                }
            }, fail);
        }, "sp.js");
    },
    RecursiveWeb: function (siteUrl) {
        var clientcontext = new SP.ClientContext(siteUrl);
        var site = clientcontext.get_site();
        var currentWeb = clientcontext.get_web();
        clientcontext.load(currentWeb, 'ServerRelativeUrl', 'Title', 'ParentWeb', 'Url');
        clientcontext.load(site, 'ServerRelativeUrl');
        clientcontext.executeQueryAsync(
    function () {
        if (site.get_serverRelativeUrl() !== currentWeb.get_serverRelativeUrl()) {
            var li = document.createElement('li');
            li.innerHTML = '' + currentWeb.get_title() + '';
            var Custombreadcrumb = document.getElementById("breadcrumbSite");
            Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
            PnPGlobal.RecursiveWeb(currentWeb.get_parentWeb().get_serverRelativeUrl())
        } else {
            var li = document.createElement('li');
            li.innerHTML = '' + currentWeb.get_title() + '';
            var Custombreadcrumb = document.getElementById("breadcrumbSite");
            Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
        }

    }, fail);
    }
}
window.PnPGlobal = window.CoreGlobalBreadcrumbRibbon;

PnPGlobal.GetInit();
(function (open) {

    XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {

        this.addEventListener("readystatechange", function () {
            window.addEventListener("DOMContentLoaded", RibbonValidation, false);
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);
function RibbonValidation() {
    SP.SOD.executeOrDelayUntilScriptLoaded(function () {
        try {
            var pm = SP.Ribbon.PageManager.get_instance();
            pm.add_ribbonInited(function () {
                CreateRibbon();
            });
            var ribbon = null;
            try {
                ribbon = pm.get_ribbon();
            }
            catch (e) { }
            if (!ribbon) {
                if (typeof (_ribbonStartInit) == "function")
                    _ribbonStartInit(_ribbon.initialTabId, false, null);
            }
            else {
                CreateRibbon();
            }
        } catch (e)
        { }
    }, "sp.ribbon.js");
}
function CreateRibbon() {
    GetUrlDoc();
    var Ribbonhtml = document.createElement('div');
    Ribbonhtml.setAttribute("id", "CustomRibbon");
    Ribbonhtml.innerHTML = "

Ribbon Example

SP Add-in\'s
";
    var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
    if (ribbon) {
        var tab = new CUI.Tab(ribbon, 'GlobalRibbon.Tab', 'Option', 'Option', 'GlobalRibbon.Tab.Command', false, '', null);
        ribbon.addChildAtIndex(tab, 1);
        var group = new CUI.Group(ribbon, 'GlobalRibbon.Tab.Group', 'Custom Ribbon', 'Global Ribbon Example', 'GlobalRibbon.Group.Command', null);
        tab.addChild(group);
    }
    SelectRibbonTab('GlobalRibbon.Tab', false);
    document.getElementById("GlobalRibbon.Tab.Group").childNodes[0].childNodes[0].appendChild(Ribbonhtml);
    SelectRibbonTab('Ribbon.Read', true);
    window.removeEventListener("DOMContentLoaded", RibbonValidation, false);
}
function LoadApps() {
    clientcontext = SP.ClientContext.get_current()
    currentWeb = clientcontext.get_web();
    appinstancesList = SP.AppCatalog.getAppInstances(clientcontext, currentWeb);
    clientcontext.load(appinstancesList);
    clientcontext.executeQueryAsync(Success, fail);
}
function DialogApps(stringHtml) {
    var element = document.createElement('div');
    element.innerHTML = stringHtml;
    SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', {
        html: element,
        title: "SharePoint Add-in",
        allowMaximize: false,
        showClose: true,
        autoSize: true
    });
}
function Success() {
    var stringHtml = '';
    var list = appinstancesList.getEnumerator();
    while (list.moveNext()) {
        var current = list.get_current();

        stringHtml += '
' + current.get_title() + '
Link
';
    }
    DialogApps(stringHtml);
}
function fail(sender, args) {
    alert(args.get_message());
}
function getQueryStringParameter(param, serverRelativeUrl) {
    if (document.URL.split("?").length > 1) {
        var params = document.URL.split("?")[1].split("&");
        for (var i = 0; i < params.length; i = i + 1) {
            var singleParam = params[i].split("=");
            if (singleParam[0] == param)
                return decodeURIComponent(singleParam[1]).replace(serverRelativeUrl, "");
        }
        if (_spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] === "Lists") {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] + "/" + _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[1];
        } else {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0];
        }
    } else {
        if (_spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] === "Lists") {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] + "/" + _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[1];
        } else {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0];
        }
    }
}
function getQueryStringParameterMDS(param) {
    if (document.URL.split("#").length > 1) {
        if (document.URL.split("?").length > 1) {
            var params = document.URL.split("?")[1].split("&");
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == param) {
                    return decodeURIComponent(singleParam[1]);
                } else if (i < params.length && singleParam[0] !== param) {
                    if (decodeURIComponent(document.URL.split("#")[1].split("/")[1]) === "Lists") {
                        return decodeURIComponent(document.URL.split("#")[1].split("/")[1]) + "/" + decodeURIComponent(document.URL.split("#")[1].split("/")[2]);
                    } else {
                        return decodeURIComponent(document.URL.split("#")[1].split("/")[1]);
                    }
                }
            }
        } else {
            if (decodeURIComponent(document.URL.split("#")[1].split("/")[1]) === "Lists") {
                return decodeURIComponent(document.URL.split("#")[1].split("/")[1]) + "/" + decodeURIComponent(document.URL.split("#")[1].split("/")[2]);
            } else {
                return decodeURIComponent(document.URL.split("#")[1].split("/")[1]);
            }
        }
    } else {
        return "";
    }

}
function GetUrlDoc() {
    var elements = document.getElementsByClassName("ListBreadcumb");
    while (elements.length > 0) {
        elements[0].parentNode.removeChild(elements[0]);
    }
    clientcontext = SP.ClientContext.get_current()
    var currentWeb = clientcontext.get_web();
    clientcontext.load(currentWeb, 'ServerRelativeUrl');
    clientcontext.executeQueryAsync(function () {
        var fullurl = currentWeb.get_serverRelativeUrl() + ((currentWeb.get_serverRelativeUrl().indexOf('/', currentWeb.get_serverRelativeUrl().length - 1) !== -1) ? '' : '/');
        var path = getQueryStringParameter("RootFolder", fullurl);
        var CustomUrl;
        if (path.split("/").length > 1) {
            var params = path.split("/");
            for (var i = 0; i < params.length; i = i + 1) {
                if (params[i].trim() !== "") {
                    fullurl = fullurl + params[i] + '/';
                    if (i === 0 && params[i].trim() === "Lists") {
                    }
                    else {
                        CustomUrl = document.createElement('li');
                        CustomUrl.className = "ListBreadcumb";
                        CustomUrl.innerHTML = '' + params[i] + '';
                        document.getElementById("breadcrumbSite").appendChild(CustomUrl);
                    }
                }
            }
        } else {
            fullurl = fullurl + path + '/';
            CustomUrl = document.createElement('li');
            CustomUrl.className = "ListBreadcumb";
            CustomUrl.innerHTML = '' + path + '';
            document.getElementById("breadcrumbSite").appendChild(CustomUrl);
        }
    }, fail);
}
function GetUrlDocMDS() {
    var elements = document.getElementsByClassName("ListBreadcumb");
    while (elements.length > 0) {
        elements[0].parentNode.removeChild(elements[0]);
    }
    clientcontext = SP.ClientContext.get_current()
    var currentWeb = clientcontext.get_web();
    clientcontext.load(currentWeb, 'ServerRelativeUrl');
    clientcontext.executeQueryAsync(function () {
        var path = getQueryStringParameterMDS("RootFolder");
        path = path.replace(currentWeb.get_serverRelativeUrl(), '');
        var CustomUrl;
        var fullurl = currentWeb.get_serverRelativeUrl() + ((currentWeb.get_serverRelativeUrl().indexOf('/', currentWeb.get_serverRelativeUrl().length - 1) !== -1) ? '' : '/');
        if (path.split("/").length > 1) {
            var params = path.split("/");
            for (var i = 0; i < params.length; i = i + 1) {
                if (params[i].trim() !== "") {
                    fullurl = fullurl + params[i] + '/';
                    if (i === 0 && params[i].trim() === "Lists") {

                    }
                    else {
                        CustomUrl = document.createElement('li');
                        CustomUrl.className = "ListBreadcumb";
                        CustomUrl.innerHTML = '' + params[i] + '';
                        document.getElementById("breadcrumbSite").appendChild(CustomUrl);
                    }
                }
            }
        } else {
            fullurl = fullurl + path + '/';
            CustomUrl = document.createElement('li');
            CustomUrl.className = "ListBreadcumb";
            CustomUrl.innerHTML = '' + path + '';
            document.getElementById("breadcrumbSite").appendChild(CustomUrl);
        }
    }, fail);
}<commit_msg>update pnpglobal /Lists/<commit_after>CoreGlobalBreadcrumbRibbon = {
    GetInit: function () {

        PnPGlobal.CreateBreadcrumb();
        PnPGlobal.CreateStyle();
        PnPGlobal.LoadSiteBreadcrumb();
        window.addEventListener("DOMContentLoaded", RibbonValidation, false);
    },
    CreateStyle: function () {
        var headID = document.getElementsByTagName("head")[0];
        var cssNode = document.createElement('style');
        cssNode.innerHTML = "#CustomRibbon div{padding-top: 5px; padding-left: 10px; float: left;}.breadcrumb li {display: inline;}.breadcrumb li+li:before {content:\">> \";}";
        headID.appendChild(cssNode);
    },
    CreateBreadcrumb: function () {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            var element = document.createElement('div');
            var context = new SP.ClientContext.get_current();
            var site = context.get_site();
            var web = site.get_rootWeb().get_allProperties();
            context.load(web)
            context.executeQueryAsync(function () {
                var results = JSON.parse(web.get_item('vti_GlobalBreadcrumbRibbon'));
                var breadcrumb = '
';

                for (var i = 0; i < results.Breadcrumb.length; i++) {
                    breadcrumb = breadcrumb + '
' + results.Breadcrumb[i].title + '
';
                }
                breadcrumb = breadcrumb + '
';
                element.innerHTML = breadcrumb;
                var Custombreadcrumb = document.getElementById("s4-bodyContainer");
                Custombreadcrumb.insertBefore(element, Custombreadcrumb.childNodes[0]);

            }, function () { });

        }, "sp.js");
    },
    LoadSiteBreadcrumb: function () {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            var clientcontext = SP.ClientContext.get_current();
            var site = clientcontext.get_site();
            var currentWeb = clientcontext.get_web();
            clientcontext.load(currentWeb, 'ServerRelativeUrl', 'Title', 'ParentWeb', 'Url');
            clientcontext.load(site, 'ServerRelativeUrl');
            clientcontext.executeQueryAsync(
            function () {
                var element = document.createElement('div');
                var breadcrumb = '
';
                breadcrumb = breadcrumb + '
';
                element.innerHTML = breadcrumb;
                var Custombreadcrumb = document.getElementById("s4-bodyContainer");
                Custombreadcrumb.insertBefore(element, Custombreadcrumb.childNodes[0]);
                var li = document.createElement('li');
                li.innerHTML = '' + currentWeb.get_title() + '';
                var Custombreadcrumb = document.getElementById("breadcrumbSite");
                Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
                if (site.get_serverRelativeUrl() !== currentWeb.get_serverRelativeUrl()) {
                    PnPGlobal.RecursiveWeb(currentWeb.get_parentWeb().get_serverRelativeUrl())
                }
            }, fail);
        }, "sp.js");
    },
    RecursiveWeb: function (siteUrl) {
        var clientcontext = new SP.ClientContext(siteUrl);
        var site = clientcontext.get_site();
        var currentWeb = clientcontext.get_web();
        clientcontext.load(currentWeb, 'ServerRelativeUrl', 'Title', 'ParentWeb', 'Url');
        clientcontext.load(site, 'ServerRelativeUrl');
        clientcontext.executeQueryAsync(
    function () {
        if (site.get_serverRelativeUrl() !== currentWeb.get_serverRelativeUrl()) {
            var li = document.createElement('li');
            li.innerHTML = '' + currentWeb.get_title() + '';
            var Custombreadcrumb = document.getElementById("breadcrumbSite");
            Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
            PnPGlobal.RecursiveWeb(currentWeb.get_parentWeb().get_serverRelativeUrl())
        } else {
            var li = document.createElement('li');
            li.innerHTML = '' + currentWeb.get_title() + '';
            var Custombreadcrumb = document.getElementById("breadcrumbSite");
            Custombreadcrumb.insertBefore(li, Custombreadcrumb.childNodes[0]);
        }

    }, fail);
    }
}
window.PnPGlobal = window.CoreGlobalBreadcrumbRibbon;

PnPGlobal.GetInit();
(function (open) {

    XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {

        this.addEventListener("readystatechange", function () {
            window.addEventListener("DOMContentLoaded", RibbonValidation, false);
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);
function RibbonValidation() {
    SP.SOD.executeOrDelayUntilScriptLoaded(function () {
        try {
            var pm = SP.Ribbon.PageManager.get_instance();
            pm.add_ribbonInited(function () {
                CreateRibbon();
            });
            var ribbon = null;
            try {
                ribbon = pm.get_ribbon();
            }
            catch (e) { }
            if (!ribbon) {
                if (typeof (_ribbonStartInit) == "function")
                    _ribbonStartInit(_ribbon.initialTabId, false, null);
            }
            else {
                CreateRibbon();
            }
        } catch (e)
        { }
    }, "sp.ribbon.js");
}
function CreateRibbon() {
    GetUrlDoc();
    var Ribbonhtml = document.createElement('div');
    Ribbonhtml.setAttribute("id", "CustomRibbon");
    Ribbonhtml.innerHTML = "

Ribbon Example

SP Add-in\'s
";
    var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
    if (ribbon) {
        var tab = new CUI.Tab(ribbon, 'GlobalRibbon.Tab', 'Option', 'Option', 'GlobalRibbon.Tab.Command', false, '', null);
        ribbon.addChildAtIndex(tab, 1);
        var group = new CUI.Group(ribbon, 'GlobalRibbon.Tab.Group', 'Custom Ribbon', 'Global Ribbon Example', 'GlobalRibbon.Group.Command', null);
        tab.addChild(group);
    }
    SelectRibbonTab('GlobalRibbon.Tab', false);
    document.getElementById("GlobalRibbon.Tab.Group").childNodes[0].childNodes[0].appendChild(Ribbonhtml);
    SelectRibbonTab('Ribbon.Read', true);
    window.removeEventListener("DOMContentLoaded", RibbonValidation, false);
}
function LoadApps() {
    clientcontext = SP.ClientContext.get_current()
    currentWeb = clientcontext.get_web();
    appinstancesList = SP.AppCatalog.getAppInstances(clientcontext, currentWeb);
    clientcontext.load(appinstancesList);
    clientcontext.executeQueryAsync(Success, fail);
}
function DialogApps(stringHtml) {
    var element = document.createElement('div');
    element.innerHTML = stringHtml;
    SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', {
        html: element,
        title: "SharePoint Add-in",
        allowMaximize: false,
        showClose: true,
        autoSize: true
    });
}
function Success() {
    var stringHtml = '';
    var list = appinstancesList.getEnumerator();
    while (list.moveNext()) {
        var current = list.get_current();

        stringHtml += '
' + current.get_title() + '
Link
';
    }
    DialogApps(stringHtml);
}
function fail(sender, args) {
    alert(args.get_message());
}
function getQueryStringParameter(param, serverRelativeUrl) {
    if (document.URL.indexOf("_layouts/15/start.aspx#") > -1) { return getQueryStringParameterMDS(param) }
    else if (document.URL.split("?").length > 1) {
        var params = document.URL.split("?")[1].split("&");
        for (var i = 0; i < params.length; i = i + 1) {
            var singleParam = params[i].split("=");
            if (singleParam[0] == param)
                return decodeURIComponent(singleParam[1]).replace(serverRelativeUrl, "");
        }
        if (_spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] === "Lists") {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] + "/" + _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[1];
        } else {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0];
        }
    } else {
        if (_spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] === "Lists") {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0] + "/" + _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[1];
        } else {
            return _spPageContextInfo.serverRequestPath.replace(serverRelativeUrl, "").split("/")[0];
        }
    }
}
function getQueryStringParameterMDS(param) {
    if (document.URL.split("#").length > 1) {
        if (document.URL.split("?").length > 1) {
            var params = document.URL.split("?")[1].split("&");
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == param) {
                    return decodeURIComponent(singleParam[1]);
                } else if (i < params.length && singleParam[0] !== param) {
                    return decodeURIComponent(document.URL.split("#")[1]);
                }
            }
        } else {
            return decodeURIComponent(document.URL.split("#")[1]);
        }
    } else {
        return "";
    }

}
function GetUrlDoc() {
    var elements = document.getElementsByClassName("ListBreadcumb");
    while (elements.length > 0) {
        elements[0].parentNode.removeChild(elements[0]);
    }
    clientcontext = SP.ClientContext.get_current()
    var currentWeb = clientcontext.get_web();
    clientcontext.load(currentWeb, 'ServerRelativeUrl');
    clientcontext.executeQueryAsync(function () {
        var fullurl = currentWeb.get_serverRelativeUrl() + ((currentWeb.get_serverRelativeUrl().indexOf('/', currentWeb.get_serverRelativeUrl().length - 1) !== -1) ? '' : '/');
        var path = getQueryStringParameter("RootFolder", fullurl);
        var CustomUrl;
        if (path.split("/").length > 1) {
            var params = path.split("/");
            for (var i = 0; i < params.length; i = i + 1) {
                if (params[i].trim() !== "") {
                    fullurl = fullurl + params[i] + '/';
                    if ((i === 1 || i === 0) && params[i].trim() === "Lists") {
                    }
                    else {
                        CustomUrl = document.createElement('li');
                        CustomUrl.className = "ListBreadcumb";
                        CustomUrl.innerHTML = '' + params[i] + '';
                        document.getElementById("breadcrumbSite").appendChild(CustomUrl);
                    }
                }
            }
        } else {
            fullurl = fullurl + path + '/';
            CustomUrl = document.createElement('li');
            CustomUrl.className = "ListBreadcumb";
            CustomUrl.innerHTML = '' + path + '';
            document.getElementById("breadcrumbSite").appendChild(CustomUrl);
        }
    }, fail);
}<|endoftext|>


<commit_before>var publishNumberStyle = {
  width: '50px',
}, publishFieldLabelStyle = {
  display: 'inline-block',
  width: '118px',
  textAlign: 'right',
  verticalAlign: 'top',
}, publishFieldStyle = {
  width: '330px',
};

var PublishPage = React.createClass({
  _requiredFields: ['name', 'bid', 'meta_title', 'meta_author', 'meta_license', 'meta_description'],

  handleSubmit: function() {
    this.setState({
      submitting: true,
    });

    var checkFields = this._requiredFields.slice();
    if (!this.state.nameIsMine) {
      checkFields.push('file');
    }

    var missingFieldFound = false;
    for (let fieldName of checkFields) {
      var field = this.refs[fieldName];
      if (field.getValue() === '') {
        field.warnRequired();
        if (!missingFieldFound) {
          field.focus();
          missingFieldFound = true;
        }
      }
    }

    if (missingFieldFound) {
      this.setState({
        submitting: false,
      });
      return;
    }

    if (this.state.nameIsMine) {
      // Pre-populate with existing metadata
      var metadata = Object.assign({}, this.state.claimMetadata);
      if (this.refs.file.getValue() !== '') {
        delete metadata.sources;
      }
    } else {
      var metadata = {};
    }

    for (let metaField of ['title', 'author', 'description', 'thumbnail', 'license', 'license_url', 'language', 'nsfw']) {
      var value = this.refs['meta_' + metaField].getValue();
      if (value !== '') {
        metadata[metaField] = value;
      }
    }

    /*
    metadata.license = {};
    metadata.license.name = this.refs.meta_license.getValue();

    var licenseUrl = this.refs.meta_license_url.getValue();
    if (licenseUrl != '') {
      metadata.license.url = licenseUrl;
    }
    */

    var licenseUrl = this.refs.meta_license_url.getValue();
    if (licenseUrl) {
      metadata.license_url = licenseUrl;
    }

    var doPublish = () => {
      var publishArgs = {
        name: this.state.name,
        bid: parseFloat(this.state.bid),
        metadata: metadata,
      };

      if (this.refs.file.getValue() !== '') {
        publishArgs.file_path = this._tempFilePath;
      }

      console.log(publishArgs);
      lbry.publish(publishArgs, (message) => {
        this.handlePublishSuccess();
        this.setState({
          submitting: false,
        });
      }, (error) => {
        this.handlePublishError(error);
        this.setState({
          submitting: false,
        });
      });
    };

    if (this.state.isFee) {
      lbry.getNewAddress((address) => {
        metadata.fee = {};
        metadata.fee[this.state.feeCurrency] = {
          amount: parseFloat(this.state.feeAmount),
          address: address,
        };

        doPublish();
      });
    } else {
      doPublish();
    }
  },
  getInitialState: function() {
    this._tempFilePath = null;

    return {
      name: '',
      bid: '',
      feeAmount: '',
      feeCurrency: 'USD',
      nameResolved: false,
      nameIsMine: false,
      claimValue: 0.0,
      claimMetadata: null,
      fileInfo: null,
      uploadProgress: 0.0,
      uploaded: false,
      tempFileReady: false,
      submitting: false,
    };
  },
  handlePublishSuccess: function() {
    alert(`Your file ${this.refs.meta_title.getValue()} has been published to LBRY at the address lbry://${this.state.name}!\n\n` +
          `You will now be taken to your My Files page, where your newly published file will be listed. Your file will take a few minutes to appear for other LBRY users; until then it will be listed as "pending."`);
    window.location = "?files";
  },
  handlePublishError: function(error) {
    alert(`The following error occurred when attempting to publish your file:\n\n` +
          error.message);
  },
  handleNameChange: function(event) {
    var name = event.target.value;

    if (!name) {
      this.setState({
        name: '',
        nameResolved: false,
      });

      return;
    }

    lbry.resolveName(name, (info) => {
      if (name != this.refs.name.getValue()) {
        return;
      }

      if (!info) {
        this.setState({
          name: name,
          nameResolved: false,
        });
      } else {
        lbry.getClaimInfo(name, (claimInfo) => {
          if (name != this.refs.name.getValue()) {
            return;
          }

          var newState = {
            name: name,
            nameResolved: true,
            nameIsMine: claimInfo.is_mine,
            claimValue: parseFloat(claimInfo.amount),
            claimMetadata: claimInfo.value,
          };

          if (claimInfo.is_mine) {
            newState.bid = claimInfo.amount;
          } else if (this.state.nameIsMine && !claimInfo.name_is_mine) {
            // Just changed away from a name we control, so clear pre-fill
            newState.bid = '';
          }

          this.setState(newState);
        });
      }
    });
  },
  handleBidChange: function(event) {
    this.setState({
      bid: event.target.value,
    });
  },
  handleFeeAmountChange: function(event) {
    this.setState({
      feeAmount: event.target.value,
    });
  },
  handleFeeCurrencyChange: function(event) {
    this.setState({
      feeCurrency: event.target.value,
    });
  },
  handleFileChange: function(event) {
    event.preventDefault();

    var fileInput = event.target;

    this._tempFilePath = null;
    if (fileInput.files.length == 0) {
      // File was removed
      this.setState({
        fileInfo: null,
        uploadProgress: 0.0,
        uploaded: false,
        tempFileReady: false,
      });
    } else {
      var file = fileInput.files[0];
      this.setState({
        fileInfo: {
          name: file.name,
          size: file.size,
        },
        uploadProgress: 0.0,
        uploaded: false,
        tempFileReady: false,
      });

      var xhr = new XMLHttpRequest();
      xhr.upload.addEventListener('progress', (event) => {
        this.setState({
          uploadProgress: (event.loaded / event.total),
        });
      });
      xhr.upload.addEventListener('load', (event) => {
        this.setState({
          uploaded: true,
        });
      });
      xhr.addEventListener('load', (event) => {
        this._tempFilePath = JSON.parse(xhr.responseText);
        this.setState({
          tempFileReady: true,
        });
      })

      xhr.open('POST', '/upload', true);
      xhr.send(new FormData(fileInput.form));
    }
  },
  handleFeePrefChange: function(feeEnabled) {
    this.setState({
      isFee: feeEnabled
    });
  },
  componentDidMount: function() {
    document.title = "Publish";
  },
  componentDidUpdate: function() {
    if (this.state.fileInfo && !this.state.tempFileReady) {
      // A file was chosen but the daemon hasn't finished processing it yet, i.e. it's loading, so
      // we're displaying a progress bar and need a value for it.

      // React can't unset the "value" prop (to show an "indeterminate" bar) after it's already
      // been set, so we have to manage it manually.

      if (!this.state.uploaded) {
        // Still uploading
        this.refs.progress.setAttribute('value', this.state.uploadProgress);
      } else {
        // Fully uploaded and waiting for server to finish processing, so set progress bar to "indeterminite"
        this.refs.progress.removeAttribute('value');
      }
    }
  },
  render: function() {
    return (

LBRY Name

            lbry://<FormField type="text" ref="name" onChange={this.handleNameChange} />
            {
              (!this.state.name ? '' :
                (! this.state.nameResolved ?  This name is available: {this.state.name}
                                           : (this.state.nameIsMine ?  You already control this name. You can use this page to update your claim.
                                                                    :  This name is currently claimed for {lbry.formatCredits(this.state.claimValue)} credits.)))
            }

What LBRY name would you like to claim for this file?

Choose File

          <form>
            <FormField name="file" ref="file" type="file" onChange={this.handleFileChange} />
            { !this.state.fileInfo ? '' :
                (!this.state.tempFileReady ?

                                               <progress ref='progress'></progress>
                                               {!this.state.uploaded ?  Importing file into LBRY... :  Processing file...}

                                           :
File ready for publishing!
) }
          </form>
          { this.state.nameIsMine ?
If you don't choose a file, the file from your existing claim will be used.
 : null }

Bid Amount

            Credits <FormField ref="bid" style={publishNumberStyle} type="text" onChange={this.handleBidChange} value={this.state.bid} placeholder={this.state.nameResolved ? lbry.formatCredits(this.state.claimValue + 10) : 100} />

How much would you like to bid for this name?
            { !this.state.nameResolved ?  Since this name is not currently resolved, you may bid as low as you want, but higher bids help prevent others from claiming your name.
                                       : (this.state.nameIsMine ?  Your current bid is {lbry.formatCredits(this.state.claimValue)} credits.
                                                                :  You must bid over {lbry.formatCredits(this.state.claimValue)} credits to claim this name.) }

Fee

             <FormField type="radio" onChange={ () => { this.handleFeePrefChange(false) } } checked={!this.state.isFee} /> No fee

             <FormField type="radio" onChange={ () => { this.handleFeePrefChange(true) } } checked={this.state.isFee} /> { !this.state.isFee ? 'Choose fee...' : 'Fee ' }

               <FormField type="text" onChange={this.handleFeeAmountChange} style={publishNumberStyle} /> <FormField type="select" onChange={this.handleFeeCurrencyChange}>
                 <option value="USD">US Dollars</option>
                 <option value="LBC">LBRY credits</option>
               </FormField>

How much would you like to charge for this file?

              If you choose to price this content in dollars, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.

Your Content

            Title<FormField type="text" ref="meta_title" name="title" placeholder="My Show, Episode 1" style={publishFieldStyle} />

            Author<FormField type="text" ref="meta_author" name="author" placeholder="My Company, Inc." style={publishFieldStyle} />

          License info<FormField type="text" ref="meta_license" name="license" defaultValue="Creative Commons Attribution 3.0 United States" style={publishFieldStyle} />

          Language <FormField type="select" defaultValue="en" ref="meta_language" name="language">
               <option value="en">English</option>
               <option value="zh">Chinese</option>
               <option value="fr">French</option>
               <option value="de">German</option>
               <option value="jp">Japanese</option>
               <option value="ru">Russian</option>
               <option value="es">Spanish</option>
            </FormField>

            Description <FormField type="textarea" ref="meta_description" name="description" placeholder="Description of your content" style={publishFieldStyle} />

            <FormField type="checkbox" ref="meta_nsfw" name="nsfw" placeholder="Description of your content" /> Not Safe For Work

Additional Content Information (Optional)

            Thumbnail URL <FormField type="text" ref="meta_thumbnail" name="thumbnail" placeholder="http://mycompany.com/images/ep_1.jpg" style={publishFieldStyle} />

            License URL <FormField type="text" ref="meta_license_url" name="license_url" defaultValue="https://creativecommons.org/licenses/by/3.0/us/legalcode" style={publishFieldStyle} />

          <Link button="primary" label={!this.state.submitting ? 'Publish' : 'Publishing...'} onClick={this.handleSubmit} disabled={this.state.submitting} />
          <Link button="cancel" href="/" label="Cancel"/>

    );
  }
});
<commit_msg>Lowercase and remove special chars from names on Publish page<commit_after>var publishNumberStyle = {
  width: '50px',
}, publishFieldLabelStyle = {
  display: 'inline-block',
  width: '118px',
  textAlign: 'right',
  verticalAlign: 'top',
}, publishFieldStyle = {
  width: '330px',
};

var PublishPage = React.createClass({
  _requiredFields: ['name', 'bid', 'meta_title', 'meta_author', 'meta_license', 'meta_description'],

  handleSubmit: function() {
    this.setState({
      submitting: true,
    });

    var checkFields = this._requiredFields.slice();
    if (!this.state.nameIsMine) {
      checkFields.push('file');
    }

    var missingFieldFound = false;
    for (let fieldName of checkFields) {
      var field = this.refs[fieldName];
      if (field.getValue() === '') {
        field.warnRequired();
        if (!missingFieldFound) {
          field.focus();
          missingFieldFound = true;
        }
      }
    }

    if (missingFieldFound) {
      this.setState({
        submitting: false,
      });
      return;
    }

    if (this.state.nameIsMine) {
      // Pre-populate with existing metadata
      var metadata = Object.assign({}, this.state.claimMetadata);
      if (this.refs.file.getValue() !== '') {
        delete metadata.sources;
      }
    } else {
      var metadata = {};
    }

    for (let metaField of ['title', 'author', 'description', 'thumbnail', 'license', 'license_url', 'language', 'nsfw']) {
      var value = this.refs['meta_' + metaField].getValue();
      if (value !== '') {
        metadata[metaField] = value;
      }
    }

    /*
    metadata.license = {};
    metadata.license.name = this.refs.meta_license.getValue();

    var licenseUrl = this.refs.meta_license_url.getValue();
    if (licenseUrl != '') {
      metadata.license.url = licenseUrl;
    }
    */

    var licenseUrl = this.refs.meta_license_url.getValue();
    if (licenseUrl) {
      metadata.license_url = licenseUrl;
    }

    var doPublish = () => {
      var publishArgs = {
        name: this.state.name,
        bid: parseFloat(this.state.bid),
        metadata: metadata,
      };

      if (this.refs.file.getValue() !== '') {
        publishArgs.file_path = this._tempFilePath;
      }

      console.log(publishArgs);
      lbry.publish(publishArgs, (message) => {
        this.handlePublishSuccess();
        this.setState({
          submitting: false,
        });
      }, (error) => {
        this.handlePublishError(error);
        this.setState({
          submitting: false,
        });
      });
    };

    if (this.state.isFee) {
      lbry.getNewAddress((address) => {
        metadata.fee = {};
        metadata.fee[this.state.feeCurrency] = {
          amount: parseFloat(this.state.feeAmount),
          address: address,
        };

        doPublish();
      });
    } else {
      doPublish();
    }
  },
  getInitialState: function() {
    this._tempFilePath = null;

    return {
      name: '',
      bid: '',
      feeAmount: '',
      feeCurrency: 'USD',
      nameResolved: false,
      nameIsMine: false,
      claimValue: 0.0,
      claimMetadata: null,
      fileInfo: null,
      uploadProgress: 0.0,
      uploaded: false,
      tempFileReady: false,
      submitting: false,
    };
  },
  handlePublishSuccess: function() {
    alert(`Your file ${this.refs.meta_title.getValue()} has been published to LBRY at the address lbry://${this.state.name}!\n\n` +
          `You will now be taken to your My Files page, where your newly published file will be listed. Your file will take a few minutes to appear for other LBRY users; until then it will be listed as "pending."`);
    window.location = "?files";
  },
  handlePublishError: function(error) {
    alert(`The following error occurred when attempting to publish your file:\n\n` +
          error.message);
  },
  handleNameChange: function(event) {
    var rawName = event.target.value;

    if (!rawName) {
      this.setState({
        name: '',
        nameResolved: false,
      });

      return;
    }

    var name = lbry.formatName(rawName);

    lbry.resolveName(name, (info) => {
      if (name != lbry.formatName(this.refs.name.getValue())) {
        // A new name has been typed already, so bail
        return;
      }

      if (!info) {
        this.setState({
          name: name,
          nameResolved: false,
        });
      } else {
        lbry.getClaimInfo(name, (claimInfo) => {
          if (name != this.refs.name.getValue()) {
            return;
          }

          var newState = {
            name: name,
            nameResolved: true,
            nameIsMine: claimInfo.is_mine,
            claimValue: parseFloat(claimInfo.amount),
            claimMetadata: claimInfo.value,
          };

          if (claimInfo.is_mine) {
            newState.bid = claimInfo.amount;
          } else if (this.state.nameIsMine && !claimInfo.name_is_mine) {
            // Just changed away from a name we control, so clear pre-fill
            newState.bid = '';
          }

          this.setState(newState);
        });
      }
    });
  },
  handleBidChange: function(event) {
    this.setState({
      bid: event.target.value,
    });
  },
  handleFeeAmountChange: function(event) {
    this.setState({
      feeAmount: event.target.value,
    });
  },
  handleFeeCurrencyChange: function(event) {
    this.setState({
      feeCurrency: event.target.value,
    });
  },
  handleFileChange: function(event) {
    event.preventDefault();

    var fileInput = event.target;

    this._tempFilePath = null;
    if (fileInput.files.length == 0) {
      // File was removed
      this.setState({
        fileInfo: null,
        uploadProgress: 0.0,
        uploaded: false,
        tempFileReady: false,
      });
    } else {
      var file = fileInput.files[0];
      this.setState({
        fileInfo: {
          name: file.name,
          size: file.size,
        },
        uploadProgress: 0.0,
        uploaded: false,
        tempFileReady: false,
      });

      var xhr = new XMLHttpRequest();
      xhr.upload.addEventListener('progress', (event) => {
        this.setState({
          uploadProgress: (event.loaded / event.total),
        });
      });
      xhr.upload.addEventListener('load', (event) => {
        this.setState({
          uploaded: true,
        });
      });
      xhr.addEventListener('load', (event) => {
        this._tempFilePath = JSON.parse(xhr.responseText);
        this.setState({
          tempFileReady: true,
        });
      })

      xhr.open('POST', '/upload', true);
      xhr.send(new FormData(fileInput.form));
    }
  },
  handleFeePrefChange: function(feeEnabled) {
    this.setState({
      isFee: feeEnabled
    });
  },
  componentDidMount: function() {
    document.title = "Publish";
  },
  componentDidUpdate: function() {
    if (this.state.fileInfo && !this.state.tempFileReady) {
      // A file was chosen but the daemon hasn't finished processing it yet, i.e. it's loading, so
      // we're displaying a progress bar and need a value for it.

      // React can't unset the "value" prop (to show an "indeterminate" bar) after it's already
      // been set, so we have to manage it manually.

      if (!this.state.uploaded) {
        // Still uploading
        this.refs.progress.setAttribute('value', this.state.uploadProgress);
      } else {
        // Fully uploaded and waiting for server to finish processing, so set progress bar to "indeterminite"
        this.refs.progress.removeAttribute('value');
      }
    }
  },
  render: function() {
    return (

LBRY Name

            lbry://<FormField type="text" ref="name" onChange={this.handleNameChange} />
            {
              (!this.state.name ? '' :
                (! this.state.nameResolved ?  The name {this.state.name} is available.
                                           : (this.state.nameIsMine ?  You already control the name {this.state.name}. You can use this page to update your claim.
                                                                    :  The name {this.state.name} is currently claimed for {lbry.formatCredits(this.state.claimValue)} credits.)))
            }

What LBRY name would you like to claim for this file?

Choose File

          <form>
            <FormField name="file" ref="file" type="file" onChange={this.handleFileChange} />
            { !this.state.fileInfo ? '' :
                (!this.state.tempFileReady ?

                                               <progress ref='progress'></progress>
                                               {!this.state.uploaded ?  Importing file into LBRY... :  Processing file...}

                                           :
File ready for publishing!
) }
          </form>
          { this.state.nameIsMine ?
If you don't choose a file, the file from your existing claim will be used.
 : null }

Bid Amount

            Credits <FormField ref="bid" style={publishNumberStyle} type="text" onChange={this.handleBidChange} value={this.state.bid} placeholder={this.state.nameResolved ? lbry.formatCredits(this.state.claimValue + 10) : 100} />

How much would you like to bid for this name?
            { !this.state.nameResolved ?  Since this name is not currently resolved, you may bid as low as you want, but higher bids help prevent others from claiming your name.
                                       : (this.state.nameIsMine ?  Your current bid is {lbry.formatCredits(this.state.claimValue)} credits.
                                                                :  You must bid over {lbry.formatCredits(this.state.claimValue)} credits to claim this name.) }

Fee

             <FormField type="radio" onChange={ () => { this.handleFeePrefChange(false) } } checked={!this.state.isFee} /> No fee

             <FormField type="radio" onChange={ () => { this.handleFeePrefChange(true) } } checked={this.state.isFee} /> { !this.state.isFee ? 'Choose fee...' : 'Fee ' }

               <FormField type="text" onChange={this.handleFeeAmountChange} style={publishNumberStyle} /> <FormField type="select" onChange={this.handleFeeCurrencyChange}>
                 <option value="USD">US Dollars</option>
                 <option value="LBC">LBRY credits</option>
               </FormField>

How much would you like to charge for this file?

              If you choose to price this content in dollars, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.

Your Content

            Title<FormField type="text" ref="meta_title" name="title" placeholder="My Show, Episode 1" style={publishFieldStyle} />

            Author<FormField type="text" ref="meta_author" name="author" placeholder="My Company, Inc." style={publishFieldStyle} />

          License info<FormField type="text" ref="meta_license" name="license" defaultValue="Creative Commons Attribution 3.0 United States" style={publishFieldStyle} />

          Language <FormField type="select" defaultValue="en" ref="meta_language" name="language">
               <option value="en">English</option>
               <option value="zh">Chinese</option>
               <option value="fr">French</option>
               <option value="de">German</option>
               <option value="jp">Japanese</option>
               <option value="ru">Russian</option>
               <option value="es">Spanish</option>
            </FormField>

            Description <FormField type="textarea" ref="meta_description" name="description" placeholder="Description of your content" style={publishFieldStyle} />

            <FormField type="checkbox" ref="meta_nsfw" name="nsfw" placeholder="Description of your content" /> Not Safe For Work

Additional Content Information (Optional)

            Thumbnail URL <FormField type="text" ref="meta_thumbnail" name="thumbnail" placeholder="http://mycompany.com/images/ep_1.jpg" style={publishFieldStyle} />

            License URL <FormField type="text" ref="meta_license_url" name="license_url" defaultValue="https://creativecommons.org/licenses/by/3.0/us/legalcode" style={publishFieldStyle} />

          <Link button="primary" label={!this.state.submitting ? 'Publish' : 'Publishing...'} onClick={this.handleSubmit} disabled={this.state.submitting} />
          <Link button="cancel" href="/" label="Cancel"/>

    );
  }
});
<|endoftext|>


<commit_before>import makeDir from 'make-dir'
import fs from 'fs'
import gutil from 'gulp-util'
import modulesList from './modulesList'
import outputFileSync from 'output-file-sync'
import gulp from 'gulp'
import args from './args'
import config from '../../config'
import path from 'path'
import requireDirectory from 'require-directory'
import _ from 'lodash'

/**
 * 工具类
 */
class Util {
  /**
   * 初始化主题目录
   */
  static initDir () {
    let themeDir = this.themeDir()
    if (!this.isDir(themeDir)) {
      this.initConfigFile(themeDir, this.currentThemeName())
      let totalModules = [...modulesList, ...this.extraModulesList()]
      for (let key in totalModules) {
        let moduleDir = `${themeDir}/Magento_${totalModules[key]}`
        this.initModule(moduleDir)
      }
    } else {
      gutil.log(gutil.colors.red(`主题目录已存在：${themeDir}`))
    }
  }

  /**
   * 检查目录是否存在
   * @param dir
   * @returns true|false
   */
  static isDir (dir) {
    return fs.existsSync(dir)
  }

  /**
   * 创建目录
   * @param dir
   */
  static createDir (dir) {
    makeDir(dir).then(path => {
      gutil.log(gutil.colors.green(`目录创建成功：${dir}`))
    })
  }

  /**
   * 初始化模块目录
   * @param dir
   */
  static initModule (dir) {
    Promise.all([
      makeDir(`${dir}/layout`),
      makeDir(`${dir}/templates`),
      makeDir(`${dir}/web/components`),
      makeDir(`${dir}/web/modules`),
      makeDir(`${dir}/web/lib`)
    ]).then((path) => {
      gutil.log(gutil.colors.green(`模块创建成功：${dir}`))
    })

    gulp.src('./build/static/require-config.js').pipe(gulp.dest(`${dir}`))
  }

  /**
   * 初始化主题配置文件及所需资源
   * @param dir
   * @param themeName
   */
  static initConfigFile (dir, themeName) {
    let registration = fs.readFileSync('./build/static/registration.php', 'utf8')
    let registrationR = registration.replace(/ThemePath/, dir)
    outputFileSync(`${dir}/registration.php`, registrationR)

    let theme = fs.readFileSync('./build/static/theme.xml', 'utf8')
    let themeR = theme.replace(/ThemeName/, themeName)
    outputFileSync(`${dir}/theme.xml`, themeR)

    gulp.src('./build/static/etc/view.xml').pipe(gulp.dest(`${dir}/etc`))
    gulp.src('./build/static/media/preview.jpg').pipe(gulp.dest(`${dir}/media`))

    gulp.src('./build/static/web/**').pipe(gulp.dest(`${dir}/web`))
    gulp.src('./build/static/Magento_Theme/**').pipe(gulp.dest(`${dir}/Magento_Theme`))
  }

  /**
   * 获取当前主题路径
   * @returns {string}
   */
  static themeDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `./frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 主题输出目录
   * @returns {*}
   */
  static outputDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `${path.join(__dirname, '../../../')}app/design/frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 设置需要排除的依赖文件，浅移除加载
   * @returns {Util.excludeShallow|*|Array}
   */
  static excludeShallow () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].excludeShallow ? config.themes[currentTheme].excludeShallow : []
  }

  /**
   * 指定主题标识
   */
  static currentTheme () {
    return args.theme
  }

  /**
   * 当前主题名
   */
  static currentThemeName () {
    return config.themes[this.currentTheme()].name
  }

  /**
   * 当前模式
   */
  static mode () {
    return args.mode
  }

  /**
   * 合并所有require-config.js配置文件
   */
  static mergeConfig () {
    let themeDir = path.join(__dirname, `../../${this.themeDir()}`)
    if (this.isDir(themeDir)) {
      let whitelist = /Magento_[\w]+\/require-config.js/
      let requireDir = requireDirectory(module, themeDir, {include: whitelist})
      let requireConfigObj = {}
      for (let item of Object.keys(requireDir)) {
        requireConfigObj = _.merge(requireConfigObj, requireDir[item]['require-config'].default)
      }
      let config = String('require.config(' + JSON.stringify(requireConfigObj) + ')')
      outputFileSync(`${themeDir}web/require-config.js`, config, 'utf-8')
    } else {
      gutil.log(gutil.colors.red(`目录不存在：${themeDir}`))
    }
  }

  /**
   * 是否开启模块压缩
   * @returns {string}
   */
  static isUglify () {
    return args.mode ? 'uglify' : 'none'
  }

  /**
   * 监听的端口
   */
  static port () {
    return args.prot
  }

  /**
   * 代理URL
   * @returns {*}
   */
  static proxy () {
    if (config.siteConfig.proxy) {
      return config.siteConfig.proxy
    } else {
      gutil.log(gutil.colors.red('请先在配置文件中设置proxy'))
      return false
    }
  }

  /**
   * 获取扩展的模块列表
   * @returns {*}
   */
  static extraModulesList () {
    return config.themes[this.currentTheme()].extraModulesList ? config.themes[this.currentTheme()].extraModulesList : []
  }

  /**
   * 判断主题是否存在
   * @returns {boolean}
   */
  static isThemeDir () {
    if (this.isDir(this.themeDir())) {
      return true
    } else {
      gutil.log(gutil.colors.red(`主题目录不存在：${this.themeDir()}`))
      return false
    }
  }
}

export default Util
<commit_msg>修复同步到magento主题目录不能工作<commit_after>import makeDir from 'make-dir'
import fs from 'fs'
import gutil from 'gulp-util'
import modulesList from './modulesList'
import outputFileSync from 'output-file-sync'
import gulp from 'gulp'
import args from './args'
import config from '../../config'
import path from 'path'
import requireDirectory from 'require-directory'
import _ from 'lodash'

/**
 * 工具类
 */
class Util {
  /**
   * 初始化主题目录
   */
  static initDir () {
    let themeDir = this.themeDir()
    if (!this.isDir(themeDir)) {
      this.initConfigFile(themeDir, this.currentThemeName())
      let totalModules = [...modulesList, ...this.extraModulesList()]
      for (let key in totalModules) {
        let moduleDir = `${themeDir}/Magento_${totalModules[key]}`
        this.initModule(moduleDir)
      }
    } else {
      gutil.log(gutil.colors.red(`主题目录已存在：${themeDir}`))
    }
  }

  /**
   * 检查目录是否存在
   * @param dir
   * @returns true|false
   */
  static isDir (dir) {
    return fs.existsSync(dir)
  }

  /**
   * 创建目录
   * @param dir
   */
  static createDir (dir) {
    makeDir(dir).then(path => {
      gutil.log(gutil.colors.green(`目录创建成功：${dir}`))
    })
  }

  /**
   * 初始化模块目录
   * @param dir
   */
  static initModule (dir) {
    Promise.all([
      makeDir(`${dir}/layout`),
      makeDir(`${dir}/templates`),
      makeDir(`${dir}/web/components`),
      makeDir(`${dir}/web/modules`),
      makeDir(`${dir}/web/lib`)
    ]).then((path) => {
      gutil.log(gutil.colors.green(`模块创建成功：${dir}`))
    })

    gulp.src('./build/static/require-config.js').pipe(gulp.dest(`${dir}`))
  }

  /**
   * 初始化主题配置文件及所需资源
   * @param dir
   * @param themeName
   */
  static initConfigFile (dir, themeName) {
    let registration = fs.readFileSync('./build/static/registration.php', 'utf8')
    let registrationR = registration.replace(/ThemePath/, dir.slice(2, dir.length-1))
    outputFileSync(`${dir}/registration.php`, registrationR)

    let theme = fs.readFileSync('./build/static/theme.xml', 'utf8')
    let themeR = theme.replace(/ThemeName/, themeName)
    outputFileSync(`${dir}/theme.xml`, themeR)

    gulp.src('./build/static/etc/view.xml').pipe(gulp.dest(`${dir}/etc`))
    gulp.src('./build/static/media/preview.jpg').pipe(gulp.dest(`${dir}/media`))

    gulp.src('./build/static/web/**').pipe(gulp.dest(`${dir}/web`))
    gulp.src('./build/static/Magento_Theme/**').pipe(gulp.dest(`${dir}/Magento_Theme`))
  }

  /**
   * 获取当前主题路径
   * @returns {string}
   */
  static themeDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `./frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 主题输出目录
   * @returns {*}
   */
  static outputDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `${path.join(__dirname, '../../../')}app/design/frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 设置需要排除的依赖文件，浅移除加载
   * @returns {Util.excludeShallow|*|Array}
   */
  static excludeShallow () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].excludeShallow ? config.themes[currentTheme].excludeShallow : []
  }

  /**
   * 指定主题标识
   */
  static currentTheme () {
    return args.theme
  }

  /**
   * 当前主题名
   */
  static currentThemeName () {
    return config.themes[this.currentTheme()].name
  }

  /**
   * 当前模式
   */
  static mode () {
    return args.mode
  }

  /**
   * 合并所有require-config.js配置文件
   */
  static mergeConfig () {
    let themeDir = path.join(__dirname, `../../${this.themeDir()}`)
    if (this.isDir(themeDir)) {
      let whitelist = /Magento_[\w]+\/require-config.js/
      let requireDir = requireDirectory(module, themeDir, {include: whitelist})
      let requireConfigObj = {}
      for (let item of Object.keys(requireDir)) {
        requireConfigObj = _.merge(requireConfigObj, requireDir[item]['require-config'].default)
      }
      let config = String('require.config(' + JSON.stringify(requireConfigObj) + ')')
      outputFileSync(`${themeDir}web/require-config.js`, config, 'utf-8')
    } else {
      gutil.log(gutil.colors.red(`目录不存在：${themeDir}`))
    }
  }

  /**
   * 是否开启模块压缩
   * @returns {string}
   */
  static isUglify () {
    return args.mode ? 'uglify' : 'none'
  }

  /**
   * 监听的端口
   */
  static port () {
    return args.prot
  }

  /**
   * 代理URL
   * @returns {*}
   */
  static proxy () {
    if (config.siteConfig.proxy) {
      return config.siteConfig.proxy
    } else {
      gutil.log(gutil.colors.red('请先在配置文件中设置proxy'))
      return false
    }
  }

  /**
   * 获取扩展的模块列表
   * @returns {*}
   */
  static extraModulesList () {
    return config.themes[this.currentTheme()].extraModulesList ? config.themes[this.currentTheme()].extraModulesList : []
  }

  /**
   * 判断主题是否存在
   * @returns {boolean}
   */
  static isThemeDir () {
    if (this.isDir(this.themeDir())) {
      return true
    } else {
      gutil.log(gutil.colors.red(`主题目录不存在：${this.themeDir()}`))
      return false
    }
  }
}

export default Util
<|endoftext|>


<commit_before>import React from 'react';
import { AST_True } from 'terser';

describe('<RelationBox />', () => {
  it('should not crash', () => {
    expect(true).toBe(true);
  });
});
AST_True;
<commit_msg>Relation box UT<commit_after>import React from 'react';
import { shallow } from 'enzyme';

import RelationBox from '../index';
import { InputTextWithErrors as InputText } from 'strapi-helper-plugin';

describe('<RelationBox />', () => {
  const props = {
    onChange: jest.fn(),
    value: '',
  };

  it('should not crash', () => {
    shallow(<RelationBox {...props} />);
  });

  it('should use the defaultProps', () => {
    const {
      defaultProps: { onClick },
    } = RelationBox;

    expect(onClick).toBeDefined();
    expect(onClick()).toBe(undefined);
  });

  it('should display source if it exists', () => {
    props.main = true;
    props.source = 'users-permissions';

    const wrapper = shallow(<RelationBox {...props} />);

    const span = wrapper
      .find('p')
      .at(0)
      .find('span');

    expect(span.text()).toContain('users-permissions');
  });

  it('target value should not be value if nature is oneWay or manyWays', () => {
    props.nature = 'oneWay';
    const wrapper = shallow(<RelationBox {...props} />);
    const { value } = wrapper.find(InputText).props();

    expect(value).toBe('-');

    props.nature = 'manyWays';
    expect(value).toBe('-');
  });
});
<|endoftext|>


<commit_before>$(document).ready(function() {
    // Pull in data via AJAX

    updateSummaryData();

    updateQueriesOverTime();

    updateQueryTypes();

    updateTopClientsChart();

    updateForwardDestinations();

    updateTopLists();

    var isMobile = {
        Windows: function() {
            return /IEMobile/i.test(navigator.userAgent);
        },
        Android: function() {
            return /Android/i.test(navigator.userAgent);
        },
        BlackBerry: function() {
            return /BlackBerry/i.test(navigator.userAgent);
        },
        iOS: function() {
            return /iPhone|iPad|iPod/i.test(navigator.userAgent);
        },
        any: function() {
            return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
        }
    };
    var animate = false;
    var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
    timeLineChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [
                {
                    label: "All Queries",
                    fill: true,
                    backgroundColor: "rgba(220,220,220,0.5)",
                    borderColor: "rgba(0, 166, 90,.8)",
                    pointBorderColor: "rgba(0, 166, 90,.8)",
                    pointRadius: 0,
                    data: [],
                    pointHitRadius: 20
                },
                {
                    label: "Ad Queries",
                    fill: true,
                    backgroundColor: "rgba(0,192,239,0.5)",
                    borderColor: "rgba(0,192,239,1)",
                    pointBorderColor: "rgba(0,192,239,1)",
                    pointRadius: 0,
                    data: [],
                    pointHitRadius: 20
                }
            ]
        },
        options: {
            tooltips: {
                enabled: true,
                mode: 'x-axis'
            },
            legend: {
                display: false
            },
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            },
            maintainAspectRatio: false
        }
    });

    ctx = document.getElementById("queryTypeChart").getContext("2d");
    queryTypeChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: [],
            datasets: [{ data: [] }]
        },
        options: {
            legend: {
                display: false
            },
            cutoutPercentage: 0
        }
    });

    ctx = document.getElementById("forwardDestinationChart").getContext("2d");
    forwardDestinationChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: [],
            datasets: [{ data: [] }]
        },
        options: {
            legend: {
                display: false
            },
            cutoutPercentage: 0
        }
    });
});

// Functions to update data in page

function updateSummaryData(runOnce) {
    $.getJSON("api.php?summary", function LoadSummaryData(data) {
        //$("h3.statistic").addClass("glow");
        if ($("h3#ads_blocked_today").text() != data.ads_blocked_today) {
            $("h3#ads_blocked_today").addClass("glow");
        }
        if ($("h3#dns_queries_today").text() != data.dns_queries_today) {
            $("h3#dns_queries_today").addClass("glow");
        }
        if ($("h3#ads_percentage_today").text() != data.ads_percentage_today) {
            $("h3#ads_percentage_today").addClass("glow");
        }

        window.setTimeout(function(){
            $("h3#ads_blocked_today").text(data.ads_blocked_today);
            $("h3#dns_queries_today").text(data.dns_queries_today);
            $("h3#domains_being_blocked").text(data.domains_being_blocked);
            $("h3#ads_percentage_today").text(data.ads_percentage_today + "%");
            $("h3.statistic.glow").removeClass("glow")
        }, 500);
    }).done(function() {
        if (runOnce !== true) {
            setTimeout(updateSummaryData, 10000);
        }
    }).fail(function() {
        if (runOnce !== true) {
            setTimeout(updateSummaryData, (1000 * 60 * 5));
        }
    });;
}

function updateQueriesOverTime() {
    $.getJSON("api.php?overTimeData", function(data) {
        // Add data for each hour that is available
        for (hour in data.ads_over_time) {
            // Add x-axis label
            timeLineChart.data.labels.push(hour + ":00");
            timeLineChart.data.datasets.forEach(function(dataset, index) {
                // Add data to line with index 0 or 1
                if(index == 0) dataset.data.push(data.domains_over_time[hour]);
                if(index == 1) dataset.data.push(data.ads_over_time[hour]);
            });
        }
        $('#queries-over-time .overlay').remove();
        timeLineChart.update();
    });
}

function updateQueryTypes() {
    $.getJSON("api.php?getQueryTypes", function(data) {
        var colors = [];
        // Get colors from AdminLTE
        $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); });
        var v = [], c = [];
        // Collect values and colors, immediately push individual labels
        $.each(data, function(key , value) {
            v.push(value);
            c.push(colors.shift());
            queryTypeChart.data.labels.push(key.substr(6,key.length - 7));
        });
        // Build a single dataset with the data to be pushed
        var dd = {data: v, backgroundColor: c};
        // and push it at once
        queryTypeChart.data.datasets.push(dd);
        $('#query-types .overlay').remove();
        queryTypeChart.update();
        queryTypeChart.chart.config.options.animation.duration=2000;
        queryTypeChart.chart.config.options.cutoutPercentage=30;
        queryTypeChart.update();
    });
}

function updateTopClientsChart() {
    $.getJSON("api.php?summaryRaw&getQuerySources", function(data) {
        var clienttable =  $('#client-frequency').find('tbody:last');
        for (domain in data.top_sources) {
            clienttable.append('
 ' + domain +
                '	 ' + data.top_sources[domain] + '

 ');
        }

        $('#client-frequency .overlay').remove();
    });
}

function updateForwardDestinations() {
    $.getJSON("api.php?getForwardDestinations", function(data) {
        var colors = [];
        // Get colors from AdminLTE
        $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); });
        var v = [], c = [];
        // Collect values and colors, immediately push individual labels
        $.each(data, function(key , value) {
            v.push(value);
            c.push(colors.shift());
            forwardDestinationChart.data.labels.push(key);
        });
        // Build a single dataset with the data to be pushed
        var dd = {data: v, backgroundColor: c};
        // and push it at once
        forwardDestinationChart.data.datasets.push(dd);
        $('#forward-destinations .overlay').remove();
        forwardDestinationChart.update();
        forwardDestinationChart.chart.config.options.animation.duration=2000;
        forwardDestinationChart.chart.config.options.cutoutPercentage=30;
        forwardDestinationChart.update();
    });
}

function updateTopLists() {
    $.getJSON("api.php?summaryRaw&topItems", function(data) {
        var domaintable = $('#domain-frequency').find('tbody:last');
        var adtable = $('#ad-frequency').find('tbody:last');

        for (domain in data.top_queries) {
            domaintable.append('
 ' + domain +
                '	 ' + data.top_queries[domain] + '

 ');
        }
        for (domain in data.top_ads) {
            adtable.append('
 ' + domain +
                '	 ' + data.top_ads[domain] + '

 ');
        }

        $('#domain-frequency .overlay').remove();
        $('#ad-frequency .overlay').remove();
    });
}
<commit_msg>Algorithm used to interpolate a smooth curve from the discrete data points changed to 'monotone'. With the default value, over- and undershoots are easily generated. In contrast, the 'monotone' setting keeps (piecewise) monotonicity and ensures that local extrema stay at data points.<commit_after>$(document).ready(function() {
    // Pull in data via AJAX

    updateSummaryData();

    updateQueriesOverTime();

    updateQueryTypes();

    updateTopClientsChart();

    updateForwardDestinations();

    updateTopLists();

    var isMobile = {
        Windows: function() {
            return /IEMobile/i.test(navigator.userAgent);
        },
        Android: function() {
            return /Android/i.test(navigator.userAgent);
        },
        BlackBerry: function() {
            return /BlackBerry/i.test(navigator.userAgent);
        },
        iOS: function() {
            return /iPhone|iPad|iPod/i.test(navigator.userAgent);
        },
        any: function() {
            return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
        }
    };
    var animate = false;
    var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
    timeLineChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [
                {
                    label: "All Queries",
                    fill: true,
                    backgroundColor: "rgba(220,220,220,0.5)",
                    borderColor: "rgba(0, 166, 90,.8)",
                    pointBorderColor: "rgba(0, 166, 90,.8)",
                    pointRadius: 0,
                    data: [],
                    pointHitRadius: 20,
                    cubicInterpolationMode: 'monotone'
                },
                {
                    label: "Ad Queries",
                    fill: true,
                    backgroundColor: "rgba(0,192,239,0.5)",
                    borderColor: "rgba(0,192,239,1)",
                    pointBorderColor: "rgba(0,192,239,1)",
                    pointRadius: 0,
                    data: [],
                    pointHitRadius: 20,
                    cubicInterpolationMode: 'monotone'
                }
            ]
        },
        options: {
            tooltips: {
                enabled: true,
                mode: 'x-axis'
            },
            legend: {
                display: false
            },
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            },
            maintainAspectRatio: false
        }
    });

    ctx = document.getElementById("queryTypeChart").getContext("2d");
    queryTypeChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: [],
            datasets: [{ data: [] }]
        },
        options: {
            legend: {
                display: false
            },
            cutoutPercentage: 0
        }
    });

    ctx = document.getElementById("forwardDestinationChart").getContext("2d");
    forwardDestinationChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: [],
            datasets: [{ data: [] }]
        },
        options: {
            legend: {
                display: false
            },
            cutoutPercentage: 0
        }
    });
});

// Functions to update data in page

function updateSummaryData(runOnce) {
    $.getJSON("api.php?summary", function LoadSummaryData(data) {
        //$("h3.statistic").addClass("glow");
        if ($("h3#ads_blocked_today").text() != data.ads_blocked_today) {
            $("h3#ads_blocked_today").addClass("glow");
        }
        if ($("h3#dns_queries_today").text() != data.dns_queries_today) {
            $("h3#dns_queries_today").addClass("glow");
        }
        if ($("h3#ads_percentage_today").text() != data.ads_percentage_today) {
            $("h3#ads_percentage_today").addClass("glow");
        }

        window.setTimeout(function(){
            $("h3#ads_blocked_today").text(data.ads_blocked_today);
            $("h3#dns_queries_today").text(data.dns_queries_today);
            $("h3#domains_being_blocked").text(data.domains_being_blocked);
            $("h3#ads_percentage_today").text(data.ads_percentage_today + "%");
            $("h3.statistic.glow").removeClass("glow")
        }, 500);
    }).done(function() {
        if (runOnce !== true) {
            setTimeout(updateSummaryData, 10000);
        }
    }).fail(function() {
        if (runOnce !== true) {
            setTimeout(updateSummaryData, (1000 * 60 * 5));
        }
    });;
}

function updateQueriesOverTime() {
    $.getJSON("api.php?overTimeData", function(data) {
        // Add data for each hour that is available
        for (hour in data.ads_over_time) {
            // Add x-axis label
            timeLineChart.data.labels.push(hour + ":00");
            timeLineChart.data.datasets.forEach(function(dataset, index) {
                // Add data to line with index 0 or 1
                if(index == 0) dataset.data.push(data.domains_over_time[hour]);
                if(index == 1) dataset.data.push(data.ads_over_time[hour]);
            });
        }
        $('#queries-over-time .overlay').remove();
        timeLineChart.update();
    });
}

function updateQueryTypes() {
    $.getJSON("api.php?getQueryTypes", function(data) {
        var colors = [];
        // Get colors from AdminLTE
        $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); });
        var v = [], c = [];
        // Collect values and colors, immediately push individual labels
        $.each(data, function(key , value) {
            v.push(value);
            c.push(colors.shift());
            queryTypeChart.data.labels.push(key.substr(6,key.length - 7));
        });
        // Build a single dataset with the data to be pushed
        var dd = {data: v, backgroundColor: c};
        // and push it at once
        queryTypeChart.data.datasets.push(dd);
        $('#query-types .overlay').remove();
        queryTypeChart.update();
        queryTypeChart.chart.config.options.animation.duration=2000;
        queryTypeChart.chart.config.options.cutoutPercentage=30;
        queryTypeChart.update();
    });
}

function updateTopClientsChart() {
    $.getJSON("api.php?summaryRaw&getQuerySources", function(data) {
        var clienttable =  $('#client-frequency').find('tbody:last');
        for (domain in data.top_sources) {
            clienttable.append('
 ' + domain +
                '	 ' + data.top_sources[domain] + '

 ');
        }

        $('#client-frequency .overlay').remove();
    });
}

function updateForwardDestinations() {
    $.getJSON("api.php?getForwardDestinations", function(data) {
        var colors = [];
        // Get colors from AdminLTE
        $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); });
        var v = [], c = [];
        // Collect values and colors, immediately push individual labels
        $.each(data, function(key , value) {
            v.push(value);
            c.push(colors.shift());
            forwardDestinationChart.data.labels.push(key);
        });
        // Build a single dataset with the data to be pushed
        var dd = {data: v, backgroundColor: c};
        // and push it at once
        forwardDestinationChart.data.datasets.push(dd);
        $('#forward-destinations .overlay').remove();
        forwardDestinationChart.update();
        forwardDestinationChart.chart.config.options.animation.duration=2000;
        forwardDestinationChart.chart.config.options.cutoutPercentage=30;
        forwardDestinationChart.update();
    });
}

function updateTopLists() {
    $.getJSON("api.php?summaryRaw&topItems", function(data) {
        var domaintable = $('#domain-frequency').find('tbody:last');
        var adtable = $('#ad-frequency').find('tbody:last');

        for (domain in data.top_queries) {
            domaintable.append('
 ' + domain +
                '	 ' + data.top_queries[domain] + '

 ');
        }
        for (domain in data.top_ads) {
            adtable.append('
 ' + domain +
                '	 ' + data.top_ads[domain] + '

 ');
        }

        $('#domain-frequency .overlay').remove();
        $('#ad-frequency .overlay').remove();
    });
}
<|endoftext|>


<commit_before>var sinon = require('sinon'),
    ajax =      require('basic-ajax'),
    endpoints = require('../../src/js/api-endpoints'),
    adminurls = require('../../src/js/admin-urls'),
    browser =   require('../../src/js/browser'),
    cookies =   require('../../src/js/cookies'),
    getUrlParameter = require('../../src/js/get-url-parameter')

describe('Editing Service Provider Need', function () {
  var Model = require('../../src/js/models/service-provider-needs/EditServiceProviderNeed')
  var model
  var browserStub
  var ajaxGetStub

  beforeEach(function () {
    browserStub = sinon.stub(browser, 'dataLoaded')

    function fakeGetResolution (value) {
      return {
        then: function (success, error) {
          success({
            'status': 200,
            'json': needData()
          })
        }
      }
    }
    ajaxGetStub = sinon.stub(ajax, 'get').withArgs(
      endpoints.getServiceProviders + '/albert-kennedy-trust/needs/56d8784092855610f88d492a',
      {
        'content-type': 'application/json',
        'session-token': 'saved-session-token'
      },
      JSON.stringify({})
    ).returns(fakeGetResolution())
    var urlParamsStub = sinon.stub(getUrlParameter, 'parameter')
    urlParamsStub.withArgs('providerId').returns('albert-kennedy-trust')
    urlParamsStub.withArgs('needId').returns('56d8784092855610f88d492a')
    sinon.stub(cookies, 'get').returns('saved-session-token')
    model = new Model()
  })

  afterEach(function () {
    ajax.get.restore()
    browser.dataLoaded.restore()
    getUrlParameter.parameter.restore()
    cookies.get.restore()
  })

  it('should get need from api', function () {
    expect(ajaxGetStub.calledOnce).toBeTruthy()
  })

  it('should set editNeedUrl', function () {
    expect(model.need().editNeedUrl).toEqual(adminurls.serviceProviderNeedsEdit + '?providerId=albert-kennedy-trust&needId=56d8784092855610f88d492a')
  })

  it('should set need id', function () {
    expect(model.need().id()).toEqual('56d8784092855610f88d492a')
  })

  it('should set need service provider id', function () {
    expect(model.need().serviceProviderId).toEqual('albert-kennedy-trust')
  })

  it('should set need description', function () {
    expect(model.need().description()).toEqual('test')
  })

  it('should set need type', function () {
    expect(model.need().type()).toEqual('Money')
  })

  it('should set need reason', function () {
    expect(model.need().reason()).toEqual('reas')
  })

  it('should set need moreInfoUrl', function () {
    expect(model.need().moreInfoUrl()).toEqual('http://www.wang.com')
  })

  it('should set need postcode', function () {
    expect(model.need().postcode()).toEqual('m1 3ly')
  })

  it('should set need instructions', function () {
    expect(model.need().instructions()).toEqual('instructions')
  })

  it('should set need email', function () {
    expect(model.need().email()).toEqual('email')
  })

  it('should set need donationAmountInPounds', function () {
    expect(model.need().donationAmountInPounds()).toEqual(1)
  })

  it('should set need donationUrl', function () {
    expect(model.need().donationUrl()).toEqual('http://www.donationUrl.com')
  })

  it('should tell browser dataLoaded', function () {
    expect(browserStub.calledOnce).toBeTruthy()
  })

  describe('save', function () {
    var ajaxPutStub

    beforeEach(function () {
      function fakePutResolution (value) {
        return {
          then: function (success, error) {
            success({
              'status': 200
            })
          }
        }
      }
      ajaxPutStub = sinon.stub(ajax, 'put').withArgs(
        endpoints.getServiceProviders + '/albert-kennedy-trust/needs/56d8784092855610f88d492a',
        {
          'content-type': 'application/json',
          'session-token': 'saved-session-token'
        },
        JSON.stringify({
          'Description': 'test',
          'Type': 'Money',
          'Reason': 'reas',
          'MoreInfoUrl': 'http://www.wang.com',
          'Postcode': 'm1 3ly',
          'Instructions': 'instructions',
          'Email': 'email',
          'DonationAmountInPounds': 1,
          'DonationUrl': 'http://www.donationUrl.com'
        })
      ).returns(fakePutResolution())

      model.need().save()
    })

    afterEach(function () {
      ajax.put.restore()
    })

    it('should put to api', function () {
      expect(ajaxPutStub.calledOnce).toBeTruthy()
    })
  })
})

function needData() {
  return {
    'id': '56d8784092855610f88d492a',
    'description': 'test',
    'serviceProviderId': 'albert-kennedy-trust',
    'type': 'Money',
    'reason': 'reas',
    'moreInfoUrl': 'http://www.wang.com',
    'postcode': 'm1 3ly',
    'instructions': 'instructions',
    'email': 'email',
    'donationAmountInPounds': 1,
    'donationUrl': 'http://www.donationUrl.com'
  }
}
<commit_msg>put new details<commit_after>var sinon = require('sinon'),
    ajax =      require('basic-ajax'),
    endpoints = require('../../src/js/api-endpoints'),
    adminurls = require('../../src/js/admin-urls'),
    browser =   require('../../src/js/browser'),
    cookies =   require('../../src/js/cookies'),
    getUrlParameter = require('../../src/js/get-url-parameter')

describe('Editing Service Provider Need', function () {
  var Model = require('../../src/js/models/service-provider-needs/EditServiceProviderNeed')
  var model
  var browserStub
  var ajaxGetStub

  beforeEach(function () {
    browserStub = sinon.stub(browser, 'dataLoaded')

    function fakeGetResolution (value) {
      return {
        then: function (success, error) {
          success({
            'status': 200,
            'json': needData()
          })
        }
      }
    }
    ajaxGetStub = sinon.stub(ajax, 'get').withArgs(
      endpoints.getServiceProviders + '/albert-kennedy-trust/needs/56d8784092855610f88d492a',
      {
        'content-type': 'application/json',
        'session-token': 'saved-session-token'
      },
      JSON.stringify({})
    ).returns(fakeGetResolution())
    var urlParamsStub = sinon.stub(getUrlParameter, 'parameter')
    urlParamsStub.withArgs('providerId').returns('albert-kennedy-trust')
    urlParamsStub.withArgs('needId').returns('56d8784092855610f88d492a')
    sinon.stub(cookies, 'get').returns('saved-session-token')
    model = new Model()
  })

  afterEach(function () {
    ajax.get.restore()
    browser.dataLoaded.restore()
    getUrlParameter.parameter.restore()
    cookies.get.restore()
  })

  it('should get need from api', function () {
    expect(ajaxGetStub.calledOnce).toBeTruthy()
  })

  it('should set editNeedUrl', function () {
    expect(model.need().editNeedUrl).toEqual(adminurls.serviceProviderNeedsEdit + '?providerId=albert-kennedy-trust&needId=56d8784092855610f88d492a')
  })

  it('should set need id', function () {
    expect(model.need().id()).toEqual('56d8784092855610f88d492a')
  })

  it('should set need service provider id', function () {
    expect(model.need().serviceProviderId).toEqual('albert-kennedy-trust')
  })

  it('should set need description', function () {
    expect(model.need().description()).toEqual('test')
  })

  it('should set need type', function () {
    expect(model.need().type()).toEqual('Money')
  })

  it('should set need reason', function () {
    expect(model.need().reason()).toEqual('reas')
  })

  it('should set need moreInfoUrl', function () {
    expect(model.need().moreInfoUrl()).toEqual('http://www.wang.com')
  })

  it('should set need postcode', function () {
    expect(model.need().postcode()).toEqual('m1 3ly')
  })

  it('should set need instructions', function () {
    expect(model.need().instructions()).toEqual('instructions')
  })

  it('should set need email', function () {
    expect(model.need().email()).toEqual('email')
  })

  it('should set need donationAmountInPounds', function () {
    expect(model.need().donationAmountInPounds()).toEqual(1)
  })

  it('should set need donationUrl', function () {
    expect(model.need().donationUrl()).toEqual('http://www.donationUrl.com')
  })

  it('should tell browser dataLoaded', function () {
    expect(browserStub.calledOnce).toBeTruthy()
  })

  describe('save', function () {
    var ajaxPutStub
    var browserRedirectStub

    beforeEach(function () {
      function fakePutResolution (value) {
        return {
          then: function (success, error) {
            success({
              'status': 200
            })
          }
        }
      }
      ajaxPutStub = sinon.stub(ajax, 'put').withArgs(
        endpoints.getServiceProviders + '/albert-kennedy-trust/needs/56d8784092855610f88d492a',
        {
          'content-type': 'application/json',
          'session-token': 'saved-session-token'
        },
        JSON.stringify({
          'Description': 'test',
          'Type': 'Money',
          'Reason': 'reas',
          'MoreInfoUrl': 'http://www.wang.com',
          'Postcode': 'm1 3ly',
          'Instructions': 'instructions',
          'Email': 'email',
          'DonationAmountInPounds': 1,
          'DonationUrl': 'http://www.donationUrl.com'
        })
      ).returns(fakePutResolution())
      browserRedirectStub  = sinon.stub(browser, 'redirect')

      model.need().save()
    })

    afterEach(function () {
      ajax.put.restore()
    })

    it('should put to api', function () {
      expect(ajaxPutStub.calledOnce).toBeTruthy()
    })

    it('should redirect back to service provider', function () {
      var redirect = adminurls.serviceProviders + '?key=coffee4craig'
      expect(browserRedirectStub.withArgs(redirect).calledOnce).toBeTruthy()
    })
  })
})

function needData() {
  return {
    'id': '56d8784092855610f88d492a',
    'description': 'test',
    'serviceProviderId': 'albert-kennedy-trust',
    'type': 'Money',
    'reason': 'reas',
    'moreInfoUrl': 'http://www.wang.com',
    'postcode': 'm1 3ly',
    'instructions': 'instructions',
    'email': 'email',
    'donationAmountInPounds': 1,
    'donationUrl': 'http://www.donationUrl.com'
  }
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

var Game   = require('../models/game');
var config = require('../config');
var Logger = require('../utility/logger');
var data   = require('../utility/data');

//You should not be able to access /game/ directly
router.get('/', function(req, res, next) {
    return res.redirect("/");
});

router.get('/:game', function(req, res, next) {
    var query = decodeURI(req.params.game);

    if (query.length < 1){
        return;
    }

    query = getCleanedName(query);

    console.log(query);

    var gameQuery = {
        "name": {
            $regex : query + ".*"
        }
    };

    Game.findOne(gameQuery, function(err, game) {

        if (err){
            Logger.log("Searching for game " + query + " failed.", err);
        }

        if (!game){
            gameNotFound(res, req.user, query);
            return;
        }

        var release;

        if (game.release_date) {
            var date = game.release_date;
            var locale = "en-us";
            var month = date.toLocaleString(locale, {month: "long"});

            release = month + " " + date.getDay() + ", " + date.getFullYear();
        }

        var banner;

        if (game.screenshots){
            banner = game.screenshots[Math.floor(Math.random()*game.screenshots.length)];
        }

        return res.render('game', {
            title: game.display_name,
            layout: 'primary',
            file: 'game',
            user : req.user,
            game: game,
            release: release,
            banner: banner
        });
    });
});

function getCleanedName(name){
    var ret = name
        .toLowerCase()
        .replace('é', 'e');
    return ret;
}

function gameNotFound(res, user, game){
    res.status(404);
    res.render('404', {
        title: 'Game not found!',
        layout: 'primary',
        file: '404',
        user: user,
        message: game + " not found!"
    });
}

module.exports = router;
<commit_msg>Fixed game release dates<commit_after>var express = require('express');
var router = express.Router();

var Game   = require('../models/game');
var config = require('../config');
var Logger = require('../utility/logger');
var data   = require('../utility/data');

//You should not be able to access /game/ directly
router.get('/', function(req, res, next) {
    return res.redirect("/");
});

router.get('/:game', function(req, res, next) {
    var query = decodeURI(req.params.game);

    if (query.length < 1){
        return;
    }

    query = getCleanedName(query);

    console.log(query);

    var gameQuery = {
        "name": {
            $regex : query + ".*"
        }
    };

    Game.findOne(gameQuery, function(err, game) {

        if (err){
            Logger.log("Searching for game " + query + " failed.", err);
        }

        if (!game){
            gameNotFound(res, req.user, query);
            return;
        }

        var release;

        if (game.release_date) {
            var date = game.release_date;
            var locale = "en-us";
            var month = date.toLocaleString(locale, {month: "long"});

            release = month + " " + date.getDate() + ", " + date.getFullYear();
        }

        var banner;

        if (game.screenshots){
            banner = game.screenshots[Math.floor(Math.random()*game.screenshots.length)];
        }

        return res.render('game', {
            title: game.display_name,
            layout: 'primary',
            file: 'game',
            user : req.user,
            game: game,
            release: release,
            banner: banner
        });
    });
});

function getCleanedName(name){
    var ret = name
        .toLowerCase()
        .replace('é', 'e');
    return ret;
}

function gameNotFound(res, user, game){
    res.status(404);
    res.render('404', {
        title: 'Game not found!',
        layout: 'primary',
        file: '404',
        user: user,
        message: game + " not found!"
    });
}

module.exports = router;
<|endoftext|>


<commit_before>export default (assignment, course) => {
  if (course.stay_in_sandbox) {
    return [
      completeBibliography(assignment),
      createInSandbox(assignment),
      expandYourDraft(assignment),
      prepareForMainspace(assignment)
    ];
  }
  return [
    completeBibliography(assignment),
    createInSandbox(assignment),
    expandYourDraft(assignment),
    moveYourWork(assignment)
  ];
};

const completeBibliography = (assignment) => {
  return {
    title: 'Complete your bibliography',
    content: 'Compile a list of reliable and verifiable secondary sources for the subject you\'ll be contributing to.',
    status: 'not_yet_started',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#complete-your-bibliography'
      },
      {
        title: 'Bibliography',
        path: `${assignment.sandboxUrl}/Bibliography?veaction=edit&preload=Template:Dashboard.wikiedu.org_bibliography`,
        external: true
      }
    ]
  };
};

const createInSandbox = (assignment) => {
  return {
    title: 'Create in the sandbox',
    content: 'In your designated sandbox, begin to sketch out your contribution.',
    status: 'in_progress',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#create-in-the-sandbox'
      },
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      }
    ]
  };
};

const expandYourDraft = (assignment) => {
  return {
    title: 'Expand your draft',
    content: 'Continue to build your contribution and prepare it for the article main space.',
    status: 'ready_for_review',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#expand-your-draft'
      },
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      }
    ]
  };
};

const moveYourWork = (assignment) => {
  return {
    title: 'Move your work',
    content: 'It\'s time to move your contribution into the article main space and make your work live!',
    status: 'ready_for_mainspace',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#move-your-work'
      },
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      },
      {
        title: 'Article',
        path: assignment.article_url,
        external: true
      }
    ]
  };
};

const prepareForMainspace = (assignment) => {
  return {
    title: 'Final checks',
    content: 'Use the quality checklist to make sure your work meets all the requirements to become a live Wikipedia article. If it does, it will be moved live after the end of the course.',
    status: 'ready_for_mainspace',
    trainings: [
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      },
      {
        title: 'Article',
        path: assignment.article_url,
        external: true
      }
    ]
  };
};
<commit_msg>Add preload template to 'create in sandbox' link in MyArticles<commit_after>export default (assignment, course) => {
  if (course.stay_in_sandbox) {
    return [
      completeBibliography(assignment),
      createInSandbox(assignment),
      expandYourDraft(assignment),
      prepareForMainspace(assignment)
    ];
  }
  return [
    completeBibliography(assignment),
    createInSandbox(assignment),
    expandYourDraft(assignment),
    moveYourWork(assignment)
  ];
};

const completeBibliography = (assignment) => {
  return {
    title: 'Complete your bibliography',
    content: 'Compile a list of reliable and verifiable secondary sources for the subject you\'ll be contributing to.',
    status: 'not_yet_started',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#complete-your-bibliography'
      },
      {
        title: 'Bibliography',
        path: `${assignment.sandboxUrl}/Bibliography?veaction=edit&preload=Template:Dashboard.wikiedu.org_bibliography`,
        external: true
      }
    ]
  };
};

const createInSandbox = (assignment) => {
  let url = assignment.sandboxUrl;
  if (Features.wikiEd) {
    url += '?veaction=edit&preload=Template:Dashboard.wikiedu.org_draft_template';
  }

  return {
    title: 'Create in the sandbox',
    content: 'In your designated sandbox, begin to sketch out your contribution.',
    status: 'in_progress',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#create-in-the-sandbox'
      },
      {
        title: 'Sandbox',
        path: url,
        external: true
      }
    ]
  };
};

const expandYourDraft = (assignment) => {
  return {
    title: 'Expand your draft',
    content: 'Continue to build your contribution and prepare it for the article main space.',
    status: 'ready_for_review',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#expand-your-draft'
      },
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      }
    ]
  };
};

const moveYourWork = (assignment) => {
  return {
    title: 'Move your work',
    content: 'It\'s time to move your contribution into the article main space and make your work live!',
    status: 'ready_for_mainspace',
    trainings: [
      {
        title: 'Related Training Modules',
        path: 'resources#move-your-work'
      },
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      },
      {
        title: 'Article',
        path: assignment.article_url,
        external: true
      }
    ]
  };
};

const prepareForMainspace = (assignment) => {
  return {
    title: 'Final checks',
    content: 'Use the quality checklist to make sure your work meets all the requirements to become a live Wikipedia article. If it does, it will be moved live after the end of the course.',
    status: 'ready_for_mainspace',
    trainings: [
      {
        title: 'Sandbox',
        path: assignment.sandboxUrl,
        external: true
      },
      {
        title: 'Article',
        path: assignment.article_url,
        external: true
      }
    ]
  };
};
<|endoftext|>


<commit_before>exports.init = function () {
    debugger
};
<commit_msg>Create the link from the client<commit_after>var $ = function (s) {
    return document.querySelector(s);
};

exports.init = function () {
    var content = $("#content");
    this
      .link("clientConnected")
      .send()
      .data(function (err, data) {
         content.value += data + "\n";
       })
      ;
};

<|endoftext|>