<commit_before>var heads               = require('robohydra').heads,
    RoboHydraHead       = require("robohydra").heads.RoboHydraHead,
    RoboHydraHeadStatic = heads.RoboHydraHeadStatic,
    token               = require('./tokens.js').token,
    apiPrefix           = "/path/to/api";

exports.getBodyParts = function(config, modules) {
    var mockupload = {
        id: 1,
        resource_uri: '/path/to/upload/1',
        token_access_key: '123123',
        token_secret_key: '123123',
        token_session: '123123',
        token_uid: '123123',
        bucket: 'foobucket',
        prefix: 'foobar',
        status: 'pending',
    }
    function meta(n){
        return {
            limit: 20,
            next: null,
            offset: 0,
            previous: null,
            total_count: n
        }
    }
    return {
        heads: [
            new RoboHydraHeadStatic({
                path: apiPrefix + '/',
                content: {
                    capsule: {
                        list_endpoint: apiPrefix + "/capsule/",
                        schema: apiPrefix + "/capsule/schema/"
                    },
                    upload: {
                        list_endpoint: apiPrefix + "/upload/",
                        schema: apiPrefix + "/upload/schema/"
                    },
                    user: {
                        list_endpoint: apiPrefix + "/user/",
                        schema: apiPrefix + "/user/schema/"
                    }
                }
            }),
            new RoboHydraHeadStatic({
                path: apiPrefix + '/capsule/',
                content: {
                    meta: meta(0),
                    objects: []
                }
            }),
            new RoboHydraHead({
                path: apiPrefix + '/upload/',
                handler: function(req, res, next) {
                    modules.assert.equal(req.method, "POST", "Upload resource supports only POST")
                    modules.assert.ok("content-type" in req.headers, "client didn't send content-type")
                    modules.assert.equal(req.headers['content-type'], 'application/json')
                    content = JSON.parse(req.rawBody)
                    modules.assert.ok("title" in content)
                    modules.assert.ok("description" in content)
                    modules.assert.ok("capsule" in content)
                    modules.assert.ok("size" in content)
                    res.statusCode='200';
                    ret = mockupload;
                    date = new Date();
                    date.setTime(date.getTime()+(60*60*1000));
                    ret['token_expiration'] = date.toISOString();
                    if (res.hasOwnProperty('token')) {
                        for (var attr in res.token) {
                            ret[attr] = res.token[attr];

                        }
                    }
                    res.write(JSON.stringify(ret));
                    res.end();
                }
            }),
            new RoboHydraHead({
                path: apiPrefix + '/upload/1',
                handler: function(req, res, next) {
                    if (req.method == "PATCH") {
                        content = JSON.parse(req.rawBody)
                        modules.assert.ok("status" in content)
                    }
                    res.statusCode='200';
                    ret = mockupload;
                    date = new Date();
                    date.setTime(date.getTime()+(60*60*1000));
                    ret['token_expiration'] = date.toISOString();
                    if (res.hasOwnProperty('token')) {
                        for (var attr in res.token) {
                            ret[attr] = res.token[attr];

                        }
                    }
                    if (res.hasOwnProperty('upload_status'))
                        ret['status'] = res.upload_status;
                    res.write(JSON.stringify(ret));
                    res.end();
                }
            })
        ],
        scenarios: {
            uploadError: {
                instructions: "Init an upload and then check it's status. it will be 'error'",
                heads: [
                    new RoboHydraHead({
                        path: apiPrefix + '/upload/1',
                        handler: function(req, res, next) {
                            res.upload_status = 'error';
                            next(req, res);
                        }
                    })
                ]
            },
            uploadComplete: {
                instructions: "Init an upload and then check it's status. it will be 'complete'",
                heads: [
                    new RoboHydraHead({
                        path: apiPrefix + '/upload/1',
                        handler: function(req, res, next) {
                            res.upload_status = 'complete';
                            next(req, res);
                        }
                    })
                ]
            },
            serverProblems: {
                instructions: "Try to upload a file. The client should show some error messaging stating the server couldn't fulfill the request or the API wasn't available",
                heads: [
                    new RoboHydraHead({
                        path: '/.*',
                        handler: function(req, res) {
                            res.statusCode = 500;
                            res.send("500 - (Synthetic) Internal Server Error");
                        }
                    })
                ]
            },
            realToken: {
                instructions: "return real AWS token.",
                heads: [
                    new RoboHydraHead({
                        path: '/.*',
                        handler: function(req, res, next) {
                            res.token = token;
                            next(req, res);
                        }
                    })
                ]
            },
            oneCapsule: {
                instructions: "activate 1 capsule.",
                heads: [
                    new RoboHydraHeadStatic({
                        path: apiPrefix + '/capsule/',
                        content: {
                            meta: meta(1),
                            objects: [
                                {
                                    created: "2013-06-07T10:45:01",
                                    id: 3,
                                    resource_uri: "/api/v1/capsule/3/",
                                    title: "Photos",
                                    user: "/api/v1/user/3/",
                                    remaining: 482,
                                    size: 1024
                                },
                                {
                                    created: "2013-06-07T10:44:38",
                                    id: 2,
                                    resource_uri: "/api/v1/capsule/2/",
                                    title: "Stuff",
                                    user: "/api/v1/user/2/",
                                    remaining: 482,
                                    size: 1024
                                }
                            ]
                        }
                    })
                ]
            },
        }
    };
};
<commit_msg>don't persist upload status in mock api<commit_after>var heads               = require('robohydra').heads,
    RoboHydraHead       = require("robohydra").heads.RoboHydraHead,
    RoboHydraHeadStatic = heads.RoboHydraHeadStatic,
    token               = require('./tokens.js').token,
    apiPrefix           = "/path/to/api";

exports.getBodyParts = function(config, modules) {
    function mockupload() {
        return { id: 1,
            resource_uri: '/path/to/upload/1',
            token_access_key: '123123',
            token_secret_key: '123123',
            token_session: '123123',
            token_uid: '123123',
            bucket: 'foobucket',
            prefix: 'foobar',
            status: 'pending',
        }
    }
    function meta(n){
        return {
            limit: 20,
            next: null,
            offset: 0,
            previous: null,
            total_count: n
        }
    }
    return {
        heads: [
            new RoboHydraHeadStatic({
                path: apiPrefix + '/',
                content: {
                    capsule: {
                        list_endpoint: apiPrefix + "/capsule/",
                        schema: apiPrefix + "/capsule/schema/"
                    },
                    upload: {
                        list_endpoint: apiPrefix + "/upload/",
                        schema: apiPrefix + "/upload/schema/"
                    },
                    user: {
                        list_endpoint: apiPrefix + "/user/",
                        schema: apiPrefix + "/user/schema/"
                    }
                }
            }),
            new RoboHydraHeadStatic({
                path: apiPrefix + '/capsule/',
                content: {
                    meta: meta(0),
                    objects: []
                }
            }),
            new RoboHydraHead({
                path: apiPrefix + '/upload/',
                handler: function(req, res, next) {
                    modules.assert.equal(req.method, "POST", "Upload resource supports only POST")
                    modules.assert.ok("content-type" in req.headers, "client didn't send content-type")
                    modules.assert.equal(req.headers['content-type'], 'application/json')
                    content = JSON.parse(req.rawBody)
                    modules.assert.ok("title" in content)
                    modules.assert.ok("description" in content)
                    modules.assert.ok("capsule" in content)
                    modules.assert.ok("size" in content)
                    res.statusCode='200';
                    var ret = mockupload();
                    date = new Date();
                    date.setTime(date.getTime()+(60*60*1000));
                    ret['token_expiration'] = date.toISOString();
                    if (res.hasOwnProperty('token')) {
                        for (var attr in res.token) {
                            ret[attr] = res.token[attr];

                        }
                    }
                    res.write(JSON.stringify(ret));
                    res.end();
                }
            }),
            new RoboHydraHead({
                path: apiPrefix + '/upload/1',
                handler: function(req, res, next) {
                    if (req.method == "PATCH") {
                        content = JSON.parse(req.rawBody)
                        modules.assert.ok("status" in content)
                    }
                    res.statusCode='200';
                    var ret = mockupload();
                    date = new Date();
                    date.setTime(date.getTime()+(60*60*1000));
                    ret['token_expiration'] = date.toISOString();
                    if (res.hasOwnProperty('token')) {
                        for (var attr in res.token) {
                            ret[attr] = res.token[attr];

                        }
                    }
                    if (res.hasOwnProperty('upload_status'))
                        ret['status'] = res.upload_status;
                    res.write(JSON.stringify(ret));
                    res.end();
                }
            })
        ],
        scenarios: {
            uploadError: {
                instructions: "Init an upload and then check it's status. it will be 'error'",
                heads: [
                    new RoboHydraHead({
                        path: apiPrefix + '/upload/1',
                        handler: function(req, res, next) {
                            res.upload_status = 'error';
                            next(req, res);
                        }
                    })
                ]
            },
            uploadComplete: {
                instructions: "Init an upload and then check it's status. it will be 'complete'",
                heads: [
                    new RoboHydraHead({
                        path: apiPrefix + '/upload/1',
                        handler: function(req, res, next) {
                            res.upload_status = 'complete';
                            next(req, res);
                        }
                    })
                ]
            },
            serverProblems: {
                instructions: "Try to upload a file. The client should show some error messaging stating the server couldn't fulfill the request or the API wasn't available",
                heads: [
                    new RoboHydraHead({
                        path: '/.*',
                        handler: function(req, res) {
                            res.statusCode = 500;
                            res.send("500 - (Synthetic) Internal Server Error");
                        }
                    })
                ]
            },
            realToken: {
                instructions: "return real AWS token.",
                heads: [
                    new RoboHydraHead({
                        path: '/.*',
                        handler: function(req, res, next) {
                            res.token = token;
                            next(req, res);
                        }
                    })
                ]
            },
            oneCapsule: {
                instructions: "activate 1 capsule.",
                heads: [
                    new RoboHydraHeadStatic({
                        path: apiPrefix + '/capsule/',
                        content: {
                            meta: meta(1),
                            objects: [
                                {
                                    created: "2013-06-07T10:45:01",
                                    id: 3,
                                    resource_uri: "/api/v1/capsule/3/",
                                    title: "Photos",
                                    user: "/api/v1/user/3/",
                                    remaining: 482,
                                    size: 1024
                                },
                                {
                                    created: "2013-06-07T10:44:38",
                                    id: 2,
                                    resource_uri: "/api/v1/capsule/2/",
                                    title: "Stuff",
                                    user: "/api/v1/user/2/",
                                    remaining: 482,
                                    size: 1024
                                }
                            ]
                        }
                    })
                ]
            },
        }
    };
};
<|endoftext|>


<commit_before><commit_msg>fix(panorama_shop): item recipe icons are not shown<commit_after><|endoftext|>


<commit_before>(function ($, window, document, undefined) {
    var editor;

    window.HLInbox = {
        config: {
            accountDeactivatedMessage: 'Your account doesn\'t seem to be active. Please activate your account to view your email.',
            inboxCcInput: '.inbox-compose .mail-to .inbox-cc',
            inboxBccInput: '.inbox-compose .mail-to .inbox-bcc',
            singleMessageSelector: '.inbox-content .view-message',
            templateField: '#id_template',
            mailGroupCheckbox: '.mail-group-checkbox',
            singleInboxCheckbox: '.mail-checkbox:not(.mail-group-checkbox)',
            searchFormSubmit: '.search-form [type="submit"]',
            inboxComposeSubmit: '.inbox-compose [type="submit"]',
            replyButton: '.reply-btn',
            inboxFrame: null,
            tagsAjaxSelector: '.tags-ajax',
            emailAccountInput: '#id_send_from'
        },

        init: function (config) {
            var self = this;

            // Setup config
            if (typeof (config === 'object')) {
                $.extend(this.config, config);
            }

            self.initListeners();
            App.fixContentHeight();
            App.initUniform();
        },

        initListeners: function() {
            var self = this,
                cf = self.config;

            $('body')
                .on('click', cf.inboxCcInput, function() {
                    // Handle compose/reply cc input toggle
                    self.handleAdditionalRecipientsInput('cc');
                })
                .on('click', cf.inboxBccInput, function() {
                    // Handle compose/reply bcc input toggle
                    self.handleAdditionalRecipientsInput('bcc');
                })
                .on('change', cf.templateField, function () {
                    self.changeTemplateField.call(self, this);
                })
                .on('click', cf.singleMessageSelector, function () {
                    self.openMessage.call(self, this);
                })
                .on('change', cf.mailGroupCheckbox, function () {
                    self.toggleGroupCheckbox.call(self, this);
                })
                .on('change', cf.singleInboxCheckbox, function () {
                    // Handle single checkbox toggle
                    $(this).parents('tr').toggleClass('active');

                    self.toggleActionsButton();
                    self.updateBulkIds();
                })
                .on('click', cf.replyButton, function () {
                    // Open links when clicking the reply button
                    $('.inbox-view').hide();
                    $('.inbox-loading').show();
                    HLApp.redirectTo($(this).data('href'));
                })
                .on('click', cf.searchFormSubmit, function () {
                    App.blockUI($('.inbox-content'), false, '');
                    $(this).button('loading');
                })
                .on('click', cf.inboxComposeSubmit, function (event) {
                    self.handleInboxComposeSubmit(this, event);
                })
                .on('change', cf.tags, function () {
                    self.handleTagsAjaxChange(this);
                });

            // Set heading properly after change
            var toolbar = $('#wysihtml5-toolbar');
            $(toolbar).find('a[data-wysihtml5-command="formatBlock"]').click(function(e) {
                var target = e.target || e.srcElement;
                var el = $(target);
                $(toolbar).find('.current-font').text(el.html());
            });

            // autogrow on frame load
            $(cf.inboxFrame).load(self.emailFrameAutogrow());

            // initialize uniform checkboxes
            App.initUniform('.mail-group-checkbox');

            // on load
            self.toggleActionsButton();
            self.updateBulkIds();
        },

        // enable/disable actions button when (no) items are selected
        toggleActionsButton: function () {
            var selected = $('' + $('.mail-group-checkbox').attr('data-set') + ':checked');
            if (selected.length) {
                $('.mail-actions').removeClass('disabled');
                $('.email-list-extra-btn').removeClass('disabled');
            } else {
                $('.mail-actions').addClass('disabled');
                $('.email-list-extra-btn').addClass('disabled');
            }
        },

        // update forms that have actions for selected messages
        updateBulkIds: function () {
            var selected = $('' + $('.mail-group-checkbox').attr('data-set') + ':not(.mail-group-checkbox):checked');
            var selectedIds = [];
            for (var i = 0; i < selected.length; i++) {
                selectedIds.push($(selected[i]).val());
            }

            $('.bulk-ids').val(selectedIds.join(','));
        },

        emailFrameAutogrow: function () {
            var cf = this.config;

            setTimeout(function () {
                $('.inbox-loading').hide();
                $('.inbox-view').show();
                App.fixContentHeight();

                // highlight selected messages
                $('.mail-checkbox:not(.mail-group-checkbox)').change(function () {
                    $(this).parents('tr').toggleClass('active');
                });

                // do this after .inbox-view is visible
                var ifDoc, ifRef = cf.inboxFrame;

                // set ifDoc to 'document' from frame
                try {
                    ifDoc = ifRef.contentWindow.document.documentElement;
                } catch (e1) {
                    try {
                        ifDoc = ifRef.contentDocument.documentElement;
                    } catch (e2) {
                    }
                }

                // calculate and set max height for frame
                if (ifDoc) {
                    var subtractHeights = [
                        $(cf.inboxFrame).offset().top,
                        $('.footer').outerHeight()
                    ];

                    var maxHeight = $('body').outerHeight();
                    for (var height in subtractHeights) {
                        maxHeight = maxHeight - height;
                    }

                    if (ifDoc.scrollHeight > maxHeight) {
                        ifRef.height = maxHeight;
                    } else {
                        ifRef.height = ifDoc.scrollHeight;
                    }
                }
            }, 300);
        },

        customParser: function () {
            function parse(elementOrHtml, rules, context, cleanUp) {
                return elementOrHtml;
            }

            return parse;
        },

        initEmailCompose: function (emailComposeConfig) {
            var self = this;

            if (typeof (emailComposeConfig === 'object')) {
                $.extend(this.config, emailComposeConfig);
            }

            self.initWysihtml5();
            self.loadDefaultEmailTemplate();
        },

        initWysihtml5: function () {
            var self = this;

            editor = new wysihtml5.Editor('id_body_html', {
                toolbar: 'wysihtml5-toolbar',
                parser: self.customParser(),
                handleTables: false
            });

            editor.observe('load', function() {
                editor.composer.element.addEventListener('keyup', function() {
                    self.resizeEditor();
                });
            });

            // Set heading properly after change
            var toolbar = $('#wysihtml5-toolbar');
            $(toolbar).find('a[data-wysihtml5-command="formatBlock"]').click(function(e) {
                var target = e.target || e.srcElement;
                var el = $(target);
                $(toolbar).find('.current-font').text(el.html());
            });

            // Not putting this in the initListeners since it's only used in the email compose
            $(window).on('resize', function() {
                self.resizeEditor();
            });
        },

        resizeEditor: function () {
            $('.wysihtml5-sandbox')[0].style.height = editor.composer.element.scrollHeight + 'px';
        },

        handleAdditionalRecipientsInput: function (inputType) {
            var $ccLink = $('.inbox-compose .mail-to .inbox-' + inputType);
            var $inputField = $('.inbox-compose .input-' + inputType);
            $ccLink.hide();
            $inputField.show();
            $('.close', $inputField).click(function () {
                $inputField.hide();
                $ccLink.show();
                $inputField.find('.tags').select2('val', '');
            });
        },

        changeTemplateField: function (templateField) {
            var self = this;
            if (templateList) {
                var value = parseInt($(templateField).val());
                var subjectField = $('#id_subject');
                if (value) {
                    var messageType = self.config.messageType;

                    if (messageType === 'new' && templateList[value].subject != '') {
                        subjectField.val(templateList[value].subject);
                    }
                    self.getEditor().setValue(templateList[value].html_part + '<br>' + self.getEditor().getValue());
                    self.resizeEditor();
                } else {
                    subjectField.val('');
                    self.getEditor().setValue('');
                    self.resizeEditor();
                }
            }
        },

        openMessage: function (singleMessageSelector) {
            // Open single email message
            if ($(singleMessageSelector).closest('[data-readable]').data('readable') == 'false') {
                alert(this.config.accountDeactivatedMessage);
            } else {
                $('.inbox-content').hide();
                $('.inbox-loading').show();
                HLApp.redirectTo($(singleMessageSelector).closest('[data-href]').data('href'));
            }
        },

        toggleGroupCheckbox: function (mailGroupCheckbox) {
            var $checkbox = $(mailGroupCheckbox);
            // Handle group checkbox toggle
            var checkboxes = $checkbox.attr('data-set');
            var checked = $checkbox.is(':checked');
            $(checkboxes).each(function () {
                if (checked) {
                    $(this).attr('checked', true);
                    $(this).parents('tr').addClass('active');
                } else {
                    $(this).attr('checked', false);
                    $(this).parents('tr').removeClass('active');
                }
            });

            $.uniform.update(checkboxes);

            this.toggleActionsButton();
            this.updateBulkIds();
        },

        handleInboxComposeSubmit: function (inboxCompose, event) {
            event.preventDefault();

            var button_name = $(inboxCompose).attr('name');
            var form = $(inboxCompose).closest('form');

            // Add button name which is used for certain checks
            $('<input>').attr('type', 'hidden')
                .attr('name', button_name)
                .attr('value', '')
                .appendTo(form);

            if (button_name == 'submit-send') {
                // Validation of fields.
                if (!$('#id_send_to_normal').val() && !$('#id_send_to_cc').val() && !$('#id_send_to_bcc').val()) {
                    $('#modal_no_email_address').modal();
                    event.preventDefault();
                    return;
                }
            } else if (button_name == 'submit-discard') {
                // Discarding email, remove all attachments to prevent unneeded uploading.
                $('[id|=id_attachments]:file').remove();
            }

            // Make sure both buttons of the same name are set to the loading state
            $('button[name="' + button_name + '"]').button('loading');

            // No validation needed, remove attachments to prevent unneeded uploading.
            $('[id|=id_attachments]:file').filter(function () {
                return $(inboxCompose).data('formset-disabled') == true;
            }).remove();

            App.blockUI($('.inbox-content'), false, '');

            // Unexplained bug caused form to freeze when submitting, so make sure form always gets submitted
            $(form).submit();
        },

        handleTagsAjaxChange: function (tagsAjax) {
            // Select2 doesn't remove certain values (values with quotes), so make sure that the value of the field is correct
            var values = [];
            var data = $(tagsAjax).select2('data');

            for(var i=0; i < data.length; i++) {
                var recipient_data = data[i];
                values.push(recipient_data.id);
            }

            $(tagsAjax).val(values.join());
        },

        getEditor: function() {
            return editor;
        },

        loadDefaultEmailTemplate: function() {
            var self = this;
            var emailAccountId = $(self.config.emailAccountInput).val();
            var url = self.config.defaultEmailTemplateUrl + emailAccountId;

            $.getJSON(url, function(data) {
                $(self.config.templateField).select2('val', data['template_id']).trigger('change');
            });
        }
    }
})(jQuery, window, document);
<commit_msg>LILY-411: Replace existing email template when selecting a new one<commit_after>(function ($, window, document, undefined) {
    var editor;

    window.HLInbox = {
        config: {
            accountDeactivatedMessage: 'Your account doesn\'t seem to be active. Please activate your account to view your email.',
            inboxCcInput: '.inbox-compose .mail-to .inbox-cc',
            inboxBccInput: '.inbox-compose .mail-to .inbox-bcc',
            singleMessageSelector: '.inbox-content .view-message',
            templateField: '#id_template',
            mailGroupCheckbox: '.mail-group-checkbox',
            singleInboxCheckbox: '.mail-checkbox:not(.mail-group-checkbox)',
            searchFormSubmit: '.search-form [type="submit"]',
            inboxComposeSubmit: '.inbox-compose [type="submit"]',
            replyButton: '.reply-btn',
            inboxFrame: null,
            tagsAjaxSelector: '.tags-ajax',
            emailAccountInput: '#id_send_from'
        },

        init: function (config) {
            var self = this;

            // Setup config
            if (typeof (config === 'object')) {
                $.extend(this.config, config);
            }

            self.initListeners();
            App.fixContentHeight();
            App.initUniform();
        },

        initListeners: function() {
            var self = this,
                cf = self.config;

            $('body')
                .on('click', cf.inboxCcInput, function() {
                    // Handle compose/reply cc input toggle
                    self.handleAdditionalRecipientsInput('cc');
                })
                .on('click', cf.inboxBccInput, function() {
                    // Handle compose/reply bcc input toggle
                    self.handleAdditionalRecipientsInput('bcc');
                })
                .on('change', cf.templateField, function () {
                    self.changeTemplateField.call(self, this);
                })
                .on('click', cf.singleMessageSelector, function () {
                    self.openMessage.call(self, this);
                })
                .on('change', cf.mailGroupCheckbox, function () {
                    self.toggleGroupCheckbox.call(self, this);
                })
                .on('change', cf.singleInboxCheckbox, function () {
                    // Handle single checkbox toggle
                    $(this).parents('tr').toggleClass('active');

                    self.toggleActionsButton();
                    self.updateBulkIds();
                })
                .on('click', cf.replyButton, function () {
                    // Open links when clicking the reply button
                    $('.inbox-view').hide();
                    $('.inbox-loading').show();
                    HLApp.redirectTo($(this).data('href'));
                })
                .on('click', cf.searchFormSubmit, function () {
                    App.blockUI($('.inbox-content'), false, '');
                    $(this).button('loading');
                })
                .on('click', cf.inboxComposeSubmit, function (event) {
                    self.handleInboxComposeSubmit(this, event);
                })
                .on('change', cf.tags, function () {
                    self.handleTagsAjaxChange(this);
                });

            // Set heading properly after change
            var toolbar = $('#wysihtml5-toolbar');
            $(toolbar).find('a[data-wysihtml5-command="formatBlock"]').click(function(e) {
                var target = e.target || e.srcElement;
                var el = $(target);
                $(toolbar).find('.current-font').text(el.html());
            });

            // autogrow on frame load
            $(cf.inboxFrame).load(self.emailFrameAutogrow());

            // initialize uniform checkboxes
            App.initUniform('.mail-group-checkbox');

            // on load
            self.toggleActionsButton();
            self.updateBulkIds();
        },

        // enable/disable actions button when (no) items are selected
        toggleActionsButton: function () {
            var selected = $('' + $('.mail-group-checkbox').attr('data-set') + ':checked');
            if (selected.length) {
                $('.mail-actions').removeClass('disabled');
                $('.email-list-extra-btn').removeClass('disabled');
            } else {
                $('.mail-actions').addClass('disabled');
                $('.email-list-extra-btn').addClass('disabled');
            }
        },

        // update forms that have actions for selected messages
        updateBulkIds: function () {
            var selected = $('' + $('.mail-group-checkbox').attr('data-set') + ':not(.mail-group-checkbox):checked');
            var selectedIds = [];
            for (var i = 0; i < selected.length; i++) {
                selectedIds.push($(selected[i]).val());
            }

            $('.bulk-ids').val(selectedIds.join(','));
        },

        emailFrameAutogrow: function () {
            var cf = this.config;

            setTimeout(function () {
                $('.inbox-loading').hide();
                $('.inbox-view').show();
                App.fixContentHeight();

                // highlight selected messages
                $('.mail-checkbox:not(.mail-group-checkbox)').change(function () {
                    $(this).parents('tr').toggleClass('active');
                });

                // do this after .inbox-view is visible
                var ifDoc, ifRef = cf.inboxFrame;

                // set ifDoc to 'document' from frame
                try {
                    ifDoc = ifRef.contentWindow.document.documentElement;
                } catch (e1) {
                    try {
                        ifDoc = ifRef.contentDocument.documentElement;
                    } catch (e2) {
                    }
                }

                // calculate and set max height for frame
                if (ifDoc) {
                    var subtractHeights = [
                        $(cf.inboxFrame).offset().top,
                        $('.footer').outerHeight()
                    ];

                    var maxHeight = $('body').outerHeight();
                    for (var height in subtractHeights) {
                        maxHeight = maxHeight - height;
                    }

                    if (ifDoc.scrollHeight > maxHeight) {
                        ifRef.height = maxHeight;
                    } else {
                        ifRef.height = ifDoc.scrollHeight;
                    }
                }
            }, 300);
        },

        customParser: function () {
            function parse(elementOrHtml, rules, context, cleanUp) {
                return elementOrHtml;
            }

            return parse;
        },

        initEmailCompose: function (emailComposeConfig) {
            var self = this;

            if (typeof (emailComposeConfig === 'object')) {
                $.extend(this.config, emailComposeConfig);
            }

            self.initWysihtml5();
            self.loadDefaultEmailTemplate();
        },

        initWysihtml5: function () {
            var self = this;

            editor = new wysihtml5.Editor('id_body_html', {
                toolbar: 'wysihtml5-toolbar',
                parser: self.customParser(),
                handleTables: false
            });

            editor.observe('load', function() {
                editor.focus();
                editor.composer.element.addEventListener('keyup', function() {
                    self.resizeEditor();
                });
            });

            // Set heading properly after change
            var toolbar = $('#wysihtml5-toolbar');
            $(toolbar).find('a[data-wysihtml5-command="formatBlock"]').click(function(e) {
                var target = e.target || e.srcElement;
                var el = $(target);
                $(toolbar).find('.current-font').text(el.html());
            });

            // Not putting this in the initListeners since it's only used in the email compose
            $(window).on('resize', function() {
                self.resizeEditor();
            });
        },

        resizeEditor: function () {
            $('.wysihtml5-sandbox')[0].style.height = editor.composer.element.scrollHeight + 'px';
        },

        handleAdditionalRecipientsInput: function (inputType) {
            var $ccLink = $('.inbox-compose .mail-to .inbox-' + inputType);
            var $inputField = $('.inbox-compose .input-' + inputType);
            $ccLink.hide();
            $inputField.show();
            $('.close', $inputField).click(function () {
                $inputField.hide();
                $ccLink.show();
                $inputField.find('.tags').select2('val', '');
            });
        },

        changeTemplateField: function (templateField) {
            var self = this;
            if (templateList) {
                var value = parseInt($(templateField).val());
                var subjectField = $('#id_subject');
                var subject = '';
                var htmlPart = '';

                if (value) {
                    subject = templateList[value].subject;
                    htmlPart = templateList[value].html_part;
                }

                var messageType = self.config.messageType;

                if (messageType === 'new' && subject != '') {
                    subjectField.val(subject);
                }

                // getValue returns a string, so convert to elements
                var editorValue = $(editor.getValue());
                var currentTemplate = editorValue.closest('#compose-email-template');
                var newEditorValue = '';

                // Check if an email template has already been loaded
                if (currentTemplate.length) {
                    // Change the html of the existing email template
                    currentTemplate.html(htmlPart);

                    // Since editorValue is actually an array of elements we can't easily convert it back to text
                    var container = $('<div>');
                    // Add the (edited) html to the newly created container
                    container.append(editorValue);
                    // Get the text version of the new html
                    newEditorValue = container[0].innerHTML
                }
                else {
                    // No email template loaded so create our email template container
                    var emailTemplate = '<div id="compose-email-template">' + htmlPart + '</div>';
                    // Append the existing text
                    newEditorValue = emailTemplate + '<br>' + editor.getValue()
                }

                editor.setValue(newEditorValue);
                self.resizeEditor();
            }
        },

        openMessage: function (singleMessageSelector) {
            // Open single email message
            if ($(singleMessageSelector).closest('[data-readable]').data('readable') == 'false') {
                alert(this.config.accountDeactivatedMessage);
            } else {
                $('.inbox-content').hide();
                $('.inbox-loading').show();
                HLApp.redirectTo($(singleMessageSelector).closest('[data-href]').data('href'));
            }
        },

        toggleGroupCheckbox: function (mailGroupCheckbox) {
            var $checkbox = $(mailGroupCheckbox);
            // Handle group checkbox toggle
            var checkboxes = $checkbox.attr('data-set');
            var checked = $checkbox.is(':checked');
            $(checkboxes).each(function () {
                if (checked) {
                    $(this).attr('checked', true);
                    $(this).parents('tr').addClass('active');
                } else {
                    $(this).attr('checked', false);
                    $(this).parents('tr').removeClass('active');
                }
            });

            $.uniform.update(checkboxes);

            this.toggleActionsButton();
            this.updateBulkIds();
        },

        handleInboxComposeSubmit: function (inboxCompose, event) {
            event.preventDefault();

            var button_name = $(inboxCompose).attr('name');
            var form = $(inboxCompose).closest('form');

            // Add button name which is used for certain checks
            $('<input>').attr('type', 'hidden')
                .attr('name', button_name)
                .attr('value', '')
                .appendTo(form);

            if (button_name == 'submit-send') {
                // Validation of fields.
                if (!$('#id_send_to_normal').val() && !$('#id_send_to_cc').val() && !$('#id_send_to_bcc').val()) {
                    $('#modal_no_email_address').modal();
                    event.preventDefault();
                    return;
                }
            } else if (button_name == 'submit-discard') {
                // Discarding email, remove all attachments to prevent unneeded uploading.
                $('[id|=id_attachments]:file').remove();
            }

            // Make sure both buttons of the same name are set to the loading state
            $('button[name="' + button_name + '"]').button('loading');

            // No validation needed, remove attachments to prevent unneeded uploading.
            $('[id|=id_attachments]:file').filter(function () {
                return $(inboxCompose).data('formset-disabled') == true;
            }).remove();

            App.blockUI($('.inbox-content'), false, '');

            // Unexplained bug caused form to freeze when submitting, so make sure form always gets submitted
            $(form).submit();
        },

        handleTagsAjaxChange: function (tagsAjax) {
            // Select2 doesn't remove certain values (values with quotes), so make sure that the value of the field is correct
            var values = [];
            var data = $(tagsAjax).select2('data');

            for(var i=0; i < data.length; i++) {
                var recipient_data = data[i];
                values.push(recipient_data.id);
            }

            $(tagsAjax).val(values.join());
        },

        getEditor: function() {
            return editor;
        },

        loadDefaultEmailTemplate: function() {
            var self = this;
            var emailAccountId = $(self.config.emailAccountInput).val();
            var url = self.config.defaultEmailTemplateUrl + emailAccountId;

            $.getJSON(url, function(data) {
                $(self.config.templateField).select2('val', data['template_id']).trigger('change');
            });
        }
    }
})(jQuery, window, document);
<|endoftext|>


<commit_before>function MenuState() {
};

MenuState.prototype.init = function() {
  this.bg_img = loadImage('res/menu.png');

  this.key_cooldown = 0;

  var that = this;
  this.elements = [
    [function() {
      sm.changeState('game');
      mm.changeState('game');
    }, {x: 13.35, y: 3.9, w: 1.9, h: 1.2, hover: function() {
      that.select(0);
    }}],
    [function() {
      mm.audioButton.toggleActivated();
    }, {x: 15, y: 0, w: 1, h: 1}]
  ];

  this.y_values = [1.8, 3.3, 4.8];
  this.y_time = 1;
  this.y = this.y_values[0];
  this.start_y = this.y_values[0];
  this.end_y = this.y_values[0];
  this.selected = 0;
};

MenuState.prototype.setY = function(y) {
  this.start_y = this.y;
  this.end_y = y;
  this.y_time = 0;
};

MenuState.prototype.select = function(selected) {
  if (this.selected == selected) {
    return;
  }
  this.selected = selected;
  this.setY(this.y_values[this.selected]);
};

MenuState.prototype.pause = function() {
  document.removeEventListener('keypress', this.fullscreenHandler);
  $("#wrapper > .logo").remove();
  $('.player-name-container').hide();
};

MenuState.prototype.resume = function() {
  var that = this;
  this.fullscreenHandler = document.addEventListener('keypress', function(e) {
    if (e.keyCode == 13 && that.selected == 0) {
    }
  });
  var logo = $('.logo.template').clone().removeClass('template');
  $('#wrapper').append(logo);
  $('.player-name-container').show();
  $('#player-name-input').val(localStorage.playerName);
};

MenuState.prototype.render = function(ctx) {
  ctx.save();
  var scaler = 16 * GU / this.bg_img.width;
  ctx.translate(CENTER.x * GU, CENTER.y * GU);
  ctx.scale(scaler, scaler);
  ctx.translate(-this.bg_img.width / 2, -this.bg_img.height / 2);
  ctx.drawImage(this.bg_img, 0, 0);
  ctx.restore();
  $('#player-name-input').css({
    'font-size': 0.5 * GU + 'px',
    'width': 5.1 * GU + 'px',
    'margin-top': -0.25 * GU + 'px',
    'padding-left': 0.2 * GU + 'px'
  });

  mm.audioButton.render(ctx);

};

MenuState.prototype.update = function() {
  this.key_cooldown && this.key_cooldown--;
  this.y_time += 0.12;
  if (this.y_time < 1) {
    this.y = smoothstep(this.start_y, this.end_y, this.y_time);
  } else if (this.y_time > 1) {
    this.y_time = 1;
    this.y = this.end_y;
  }

  if (!this.key_cooldown) {
    if (KEYS[40]) { /* key down */
      this.selected + 1 < this.y_values.length && this.select(this.selected + 1);
      this.key_cooldown = 10;
    }
    if (KEYS[38]) { /* key up */
      this.selected - 1 >= 0 && this.select(this.selected - 1);
      this.key_cooldown = 10;
    }
    if (KEYS[13]) { /* key enter */
      this.key_cooldown = 10;
      sm.changeState('game');
      mm.changeState('game');
    }
  }
};
<commit_msg>Add default names to menu state<commit_after>function MenuState() {
};

MenuState.prototype.init = function() {
  this.bg_img = loadImage('res/menu.png');

  this.key_cooldown = 0;

  var that = this;
  this.elements = [
    [function() {
      sm.changeState('game');
      mm.changeState('game');
    }, {x: 13.35, y: 3.9, w: 1.9, h: 1.2, hover: function() {
      that.select(0);
    }}],
    [function() {
      mm.audioButton.toggleActivated();
    }, {x: 15, y: 0, w: 1, h: 1}]
  ];

  this.y_values = [1.8, 3.3, 4.8];
  this.y_time = 1;
  this.y = this.y_values[0];
  this.start_y = this.y_values[0];
  this.end_y = this.y_values[0];
  this.selected = 0;
};

MenuState.prototype.setY = function(y) {
  this.start_y = this.y;
  this.end_y = y;
  this.y_time = 0;
};

MenuState.prototype.select = function(selected) {
  if (this.selected == selected) {
    return;
  }
  this.selected = selected;
  this.setY(this.y_values[this.selected]);
};

MenuState.prototype.pause = function() {
  document.removeEventListener('keypress', this.fullscreenHandler);
  $("#wrapper > .logo").remove();
  $('.player-name-container').hide();
};

MenuState.prototype.resume = function() {
  var that = this;
  this.fullscreenHandler = document.addEventListener('keypress', function(e) {
    if (e.keyCode == 13 && that.selected == 0) {
    }
  });
  var logo = $('.logo.template').clone().removeClass('template');
  $('#wrapper').append(logo);
  $('.player-name-container').show();
  $('#player-name-input').val(localStorage.playerName || new Player().name);
};

MenuState.prototype.render = function(ctx) {
  ctx.save();
  var scaler = 16 * GU / this.bg_img.width;
  ctx.translate(CENTER.x * GU, CENTER.y * GU);
  ctx.scale(scaler, scaler);
  ctx.translate(-this.bg_img.width / 2, -this.bg_img.height / 2);
  ctx.drawImage(this.bg_img, 0, 0);
  ctx.restore();
  $('#player-name-input').css({
    'font-size': 0.5 * GU + 'px',
    'width': 5.1 * GU + 'px',
    'margin-top': -0.25 * GU + 'px',
    'padding-left': 0.2 * GU + 'px'
  });

  mm.audioButton.render(ctx);

};

MenuState.prototype.update = function() {
  this.key_cooldown && this.key_cooldown--;
  this.y_time += 0.12;
  if (this.y_time < 1) {
    this.y = smoothstep(this.start_y, this.end_y, this.y_time);
  } else if (this.y_time > 1) {
    this.y_time = 1;
    this.y = this.end_y;
  }

  if (!this.key_cooldown) {
    if (KEYS[40]) { /* key down */
      this.selected + 1 < this.y_values.length && this.select(this.selected + 1);
      this.key_cooldown = 10;
    }
    if (KEYS[38]) { /* key up */
      this.selected - 1 >= 0 && this.select(this.selected - 1);
      this.key_cooldown = 10;
    }
    if (KEYS[13]) { /* key enter */
      this.key_cooldown = 10;
      sm.changeState('game');
      mm.changeState('game');
    }
  }
};
<|endoftext|>


<commit_before>define(function () {

    function RunQuery (bezl, queryName) {

        switch (queryName) {
            case "Orders":
                bezl.vars.loading = true;

                // Pull in the accounts list for the logged in user
                bezl.dataService.add('Orders','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "OrderInquiry",
                    "Parameters": [
                        { "Key": "StartDate", "Value": bezl.vars.startDate || "01/01/1900"},
                        { "Key": "EndDate", "Value": bezl.vars.endDate || "01/01/2100"},
                        { "Key": "CustID", "Value": bezl.vars.selectedAccount.ID || ""},
                        { "Key": "Company", "Value": 'All' }
                    ] },0);
                break;
            case 'Accounts':
                bezl.vars.loading = true;
                // Get All Accounts associated with user
                bezl.dataService.add('Accounts','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "GetAccounts",
                    "Parameters": [
                        { "Key": "EmailAddress", "Value": bezl.env.currentUser }
                    ] },0);
                break;
            case 'GetAllOrders':
                bezl.vars.loading = true;
                // Get All Orders associated with user
                bezl.dataService.add('Orders','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "GetAllOrders",
                    "Parameters": [
                      	{ "Key": "EmailAddress", "Value": bezl.env.currentUser },
                        { "Key": "StartDate", "Value": bezl.vars.startDate || "01/01/1900"},
                        { "Key": "EndDate", "Value": bezl.vars.endDate || "01/01/2100"},
                        { "Key": "Company", "Value": 'All' }
                    ] },0);
                break;
            default:
                break;
        }
    }

    function Select(bezl, Order) {
        // Mark the selected customer as selected
        for (var i = 0; i < bezl.vars.Orders.length; i++) {
            if (bezl.vars.Orders[i].OrderNum == Order.OrderNum) {
                bezl.vars.Orders[i].Selected = !bezl.vars.Orders[i].Selected;

                if (bezl.vars.Orders[i].Selected) {
                    localStorage.setItem('selectedOrder', JSON.stringify(bezl.vars.Orders[i]));
                    $('#bezlpanel').trigger('selectedOrder', [bezl.vars.Orders[i]]);
                } else {
                    localStorage.setItem('selectedOrder', '');
                    $('#bezlpanel').trigger('selectedOrder', [{}]);
                }

            } else {
                bezl.vars.Orders[i].Selected = false;
            }
        };
    }

    function Filter(bezl) {
        // Filter, will hide the table rows that do not match filter
        var tr, td;
        tr = document.getElementById("orderList").getElementsByTagName("tr");

        // Loop through all rows
        for(var i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[0];

            if(td) {
                if(bezl.vars.filter.toUpperCase() == "ALL")
                {
                    tr[i].style.display = "";
                } else if(td.children[0].children[4].innerHTML.toUpperCase().indexOf(bezl.vars.filter.toUpperCase()) > -1){
                    tr[i].style.display = "";
                }
                else {
                    tr[i].style.display = "none";
                }
            }
        }

    }

    function Sort(bezl, sortColumn) {

        // If the previous sort column was picked, make it the opposite sort
        if (bezl.vars.sortCol == sortColumn) {
            if (bezl.vars.sort == "desc") {
                bezl.vars.sort = "asc";
            } else {
                bezl.vars.sort = "desc";
            }
        } else {
            bezl.vars.sort = "asc";
        }

        // Store the sort column so the UI can reflect it
        bezl.vars.sortCol = sortColumn;

        // Test for numeric sort columns, otherwise sort alphabetic
        if (sortColumn == "OrderAmt" || sortColumn == "OrderNum") {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn];
                    var B = b[sortColumn];
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn];
                    var B = b[sortColumn];
                    return B - A;
                });
            }
        } else if (sortColumn == "OrderDate" ) {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = Date.parse(a[sortColumn]) || Number.MAX_SAFE_INTEGER;
                    var B = Date.parse(b[sortColumn]) || Number.MAX_SAFE_INTEGER;
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = Date.parse(a[sortColumn]) || Number.MAX_SAFE_INTEGER * -1;
                    var B = Date.parse(b[sortColumn]) || Number.MAX_SAFE_INTEGER * -1;
                    return B - A;
                });
            }
        } else {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A < B) {
                        return -1;
                    }
                    if (A > B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            } else {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A > B) {
                        return -1;
                    }
                    if (A < B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            }
        }
    }

    function InnerSort(bezl, sortColumn) {

        // If the previous sort column was picked, make it the opposite sort
        if (bezl.vars.sortCol == sortColumn) {
            if (bezl.vars.sortInner == "desc") {
                bezl.vars.sortInner = "asc";
            } else {
                bezl.vars.sortInner = "desc";
            }
        } else {
            bezl.vars.sortInner = "asc";
        }

        // Store the sort column so the UI can reflect it
        bezl.vars.sortCol = sortColumn;

        // Test for numeric sort columns, otherwise sort alphabetic
        if (sortColumn == "LineNum" || sortColumn == "PartNum" || sortColumn == "InvoiceQty" || sortColumn == "ExtPrice" || sortColumn == "ShippedQty" || sortColumn == "UnitPrice") {
            if (bezl.vars.sortInner == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn] || Number.MAX_SAFE_INTEGER;
                    var B = b[sortColumn] || Number.MAX_SAFE_INTEGER;
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn] || Number.MAX_SAFE_INTEGER;
                    var B = b[sortColumn] || Number.MAX_SAFE_INTEGER;
                    return B - A;
                });
            }
        } else {
            if (bezl.vars.sortInner == "asc") {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A < B) {
                        return -1;
                    }
                    if (A > B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            } else {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A > B) {
                        return -1;
                    }
                    if (A < B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            }
        }
    }

    function custSelection(bezl, custId) {

        var cust = bezl.vars.custList.find(c => c.ID == parm);
        if(parm == "ALL_ACCOUNTS" ){
            bezl.vars.selectedAccount = cust;
            this.runQuery(bezl, 'GetAllOrders');
        }else{
            bezl.vars.selectedAccount = cust;
        }
    }

    return {
        runQuery: RunQuery,
        select: Select,
        filter: Filter,
        sort: Sort,
        innerSort: InnerSort
    }
});
<commit_msg>returned custSelection from order.js<commit_after>define(function () {

    function RunQuery (bezl, queryName) {

        switch (queryName) {
            case "Orders":
                bezl.vars.loading = true;

                // Pull in the accounts list for the logged in user
                bezl.dataService.add('Orders','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "OrderInquiry",
                    "Parameters": [
                        { "Key": "StartDate", "Value": bezl.vars.startDate || "01/01/1900"},
                        { "Key": "EndDate", "Value": bezl.vars.endDate || "01/01/2100"},
                        { "Key": "CustID", "Value": bezl.vars.selectedAccount.ID || ""},
                        { "Key": "Company", "Value": 'All' }
                    ] },0);
                break;
            case 'Accounts':
                bezl.vars.loading = true;
                // Get All Accounts associated with user
                bezl.dataService.add('Accounts','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "GetAccounts",
                    "Parameters": [
                        { "Key": "EmailAddress", "Value": bezl.env.currentUser }
                    ] },0);
                break;
            case 'GetAllOrders':
                bezl.vars.loading = true;
                // Get All Orders associated with user
                bezl.dataService.add('Orders','brdb','sales-rep-queries','ExecuteQuery', {
                    "QueryName": "GetAllOrders",
                    "Parameters": [
                      	{ "Key": "EmailAddress", "Value": bezl.env.currentUser },
                        { "Key": "StartDate", "Value": bezl.vars.startDate || "01/01/1900"},
                        { "Key": "EndDate", "Value": bezl.vars.endDate || "01/01/2100"},
                        { "Key": "Company", "Value": 'All' }
                    ] },0);
                break;
            default:
                break;
        }
    }

    function Select(bezl, Order) {
        // Mark the selected customer as selected
        for (var i = 0; i < bezl.vars.Orders.length; i++) {
            if (bezl.vars.Orders[i].OrderNum == Order.OrderNum) {
                bezl.vars.Orders[i].Selected = !bezl.vars.Orders[i].Selected;

                if (bezl.vars.Orders[i].Selected) {
                    localStorage.setItem('selectedOrder', JSON.stringify(bezl.vars.Orders[i]));
                    $('#bezlpanel').trigger('selectedOrder', [bezl.vars.Orders[i]]);
                } else {
                    localStorage.setItem('selectedOrder', '');
                    $('#bezlpanel').trigger('selectedOrder', [{}]);
                }

            } else {
                bezl.vars.Orders[i].Selected = false;
            }
        };
    }

    function Filter(bezl) {
        // Filter, will hide the table rows that do not match filter
        var tr, td;
        tr = document.getElementById("orderList").getElementsByTagName("tr");

        // Loop through all rows
        for(var i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[0];

            if(td) {
                if(bezl.vars.filter.toUpperCase() == "ALL")
                {
                    tr[i].style.display = "";
                } else if(td.children[0].children[4].innerHTML.toUpperCase().indexOf(bezl.vars.filter.toUpperCase()) > -1){
                    tr[i].style.display = "";
                }
                else {
                    tr[i].style.display = "none";
                }
            }
        }

    }

    function Sort(bezl, sortColumn) {

        // If the previous sort column was picked, make it the opposite sort
        if (bezl.vars.sortCol == sortColumn) {
            if (bezl.vars.sort == "desc") {
                bezl.vars.sort = "asc";
            } else {
                bezl.vars.sort = "desc";
            }
        } else {
            bezl.vars.sort = "asc";
        }

        // Store the sort column so the UI can reflect it
        bezl.vars.sortCol = sortColumn;

        // Test for numeric sort columns, otherwise sort alphabetic
        if (sortColumn == "OrderAmt" || sortColumn == "OrderNum") {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn];
                    var B = b[sortColumn];
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn];
                    var B = b[sortColumn];
                    return B - A;
                });
            }
        } else if (sortColumn == "OrderDate" ) {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = Date.parse(a[sortColumn]) || Number.MAX_SAFE_INTEGER;
                    var B = Date.parse(b[sortColumn]) || Number.MAX_SAFE_INTEGER;
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = Date.parse(a[sortColumn]) || Number.MAX_SAFE_INTEGER * -1;
                    var B = Date.parse(b[sortColumn]) || Number.MAX_SAFE_INTEGER * -1;
                    return B - A;
                });
            }
        } else {
            if (bezl.vars.sort == "asc") {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A < B) {
                        return -1;
                    }
                    if (A > B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            } else {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A > B) {
                        return -1;
                    }
                    if (A < B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            }
        }
    }

    function InnerSort(bezl, sortColumn) {

        // If the previous sort column was picked, make it the opposite sort
        if (bezl.vars.sortCol == sortColumn) {
            if (bezl.vars.sortInner == "desc") {
                bezl.vars.sortInner = "asc";
            } else {
                bezl.vars.sortInner = "desc";
            }
        } else {
            bezl.vars.sortInner = "asc";
        }

        // Store the sort column so the UI can reflect it
        bezl.vars.sortCol = sortColumn;

        // Test for numeric sort columns, otherwise sort alphabetic
        if (sortColumn == "LineNum" || sortColumn == "PartNum" || sortColumn == "InvoiceQty" || sortColumn == "ExtPrice" || sortColumn == "ShippedQty" || sortColumn == "UnitPrice") {
            if (bezl.vars.sortInner == "asc") {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn] || Number.MAX_SAFE_INTEGER;
                    var B = b[sortColumn] || Number.MAX_SAFE_INTEGER;
                    return A - B;
                });
            } else {
                bezl.vars.Orders.sort(function (a, b) {
                    var A = a[sortColumn] || Number.MAX_SAFE_INTEGER;
                    var B = b[sortColumn] || Number.MAX_SAFE_INTEGER;
                    return B - A;
                });
            }
        } else {
            if (bezl.vars.sortInner == "asc") {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A < B) {
                        return -1;
                    }
                    if (A > B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            } else {
                bezl.vars.Orders.sort(function(a, b) {
                    var A = a[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    var B = b[sortColumn] .toUpperCase(); // ignore upper and lowercase
                    if (A > B) {
                        return -1;
                    }
                    if (A < B) {
                        return 1;
                    }

                    // names must be equal
                    return 0;
                });
            }
        }
    }

    function CustSelection(bezl, custId) {

        var cust = bezl.vars.custList.find(c => c.ID == parm);
        if(parm == "ALL_ACCOUNTS" ){
            bezl.vars.selectedAccount = cust;
            this.runQuery(bezl, 'GetAllOrders');
        }else{
            bezl.vars.selectedAccount = cust;
        }
    }

    return {
        runQuery: RunQuery,
        select: Select,
        filter: Filter,
        sort: Sort,
        innerSort: InnerSort,
        custSelection: CustSelection
    }
});
<|endoftext|>


<commit_before>require('babel-register')({
  plugins: ['transform-async-to-generator'],
});
<commit_msg>Delete babelPlugins.js<commit_after><|endoftext|>


<commit_before>var http = require('http');
var server = http.createServer().listen(8005);
var io = require('socket.io')(server);
var cookie = require('cookie');
var querystring = require('querystring');
var Promise = require('promise');

function validate_sessionid(sessionid) {
  return new Promise(function (fulfill, reject) {
    var options = {
      method: 'HEAD',
      host: 'localhost',
      port: '8001',
      path: '/call_centre/',
      cookie: 'sessionid=' + sessionid
    };
    var request = http.request(options);

    request.on('response', function (response) {
      if (redirected_to_login(response)) {
        reject(Error('not authorized'));
      }
      fulfill();
    });

    request.on('error', function (e) {
      reject(Error('Problem with request: ' + e.message));
    });

    request.end();
  });
}

function redirected_to_login(response) {
  return 'Location' in response.headers;
}

io.use(function (socket, next) {
  if (socket.request.headers.cookie) {
    socket.request.cookie = cookie.parse(socket.request.headers.cookie);
    validate_sessionid(socket.request.cookie.sessionid).then(next, function (e) {
      log('FAIL invalid sessionid', socket);
      next(new Error('not authorized: ' + e.message));
    });
  } else {
    log('FAIL no cookie');
    next(new Error('not authorized'));
  }
});

io.on('connection', function (socket) {
  log('connected', socket);

  socket.on('client', function (data) {
    socket.broadcast.emit('server', data);
  });

  socket.on('disconnect', function () {
    log('disconnected', socket);
  });
});

function log(message, socket) {
  console.log(JSON.stringify({
    "@version": 1,
    "@timestamp": (new Date()).toISOString(),
    "message": message,
    "sessionid": socket.request.cookie.sessionid,
    "clientip": clientIp(socket.request),
    "user-agent": socket.request.headers['user-agent']
  }));
}

function clientIp(req) {
  return req.headers['x-forwarded-for'] ||
    req.connection.remoteAddress ||
    req.socket.remoteAddress ||
    req.connection.socket.remoteAddress;
}
<commit_msg>Temporarily disable sessionid validation<commit_after>var http = require('http');
var server = http.createServer().listen(8005);
var io = require('socket.io')(server);
var cookie = require('cookie');
var querystring = require('querystring');
var Promise = require('promise');

function validate_sessionid(sessionid) {
  return new Promise(function (fulfill, reject) {
    var options = {
      method: 'HEAD',
      host: 'localhost',
      port: '8001',
      path: '/call_centre/',
      cookie: 'sessionid=' + sessionid
    };
    var request = http.request(options);

    request.on('response', function (response) {
      if (redirected_to_login(response)) {
        reject(Error('not authorized'));
      }
      fulfill();
    });

    request.on('error', function (e) {
      reject(Error('Problem with request: ' + e.message));
    });

    request.end();
  });
}

function redirected_to_login(response) {
  return 'Location' in response.headers;
}

io.use(function (socket, next) {
  if (socket.request.headers.cookie) {
    socket.request.cookie = cookie.parse(socket.request.headers.cookie);
//    validate_sessionid(socket.request.cookie.sessionid).then(next, function (e) {
//      log('FAIL invalid sessionid', socket);
//      next(new Error('not authorized: ' + e.message));
//    });
    next();
  } else {
    log('FAIL no cookie');
    next(new Error('not authorized'));
  }
});

io.on('connection', function (socket) {
  log('connected', socket);

  socket.on('client', function (data) {
    socket.broadcast.emit('server', data);
  });

  socket.on('disconnect', function () {
    log('disconnected', socket);
  });
});

function log(message, socket) {
  console.log(JSON.stringify({
    "@version": 1,
    "@timestamp": (new Date()).toISOString(),
    "message": message,
    "sessionid": socket.request.cookie.sessionid,
    "clientip": clientIp(socket.request),
    "user-agent": socket.request.headers['user-agent']
  }));
}

function clientIp(req) {
  return req.headers['x-forwarded-for'] ||
    req.connection.remoteAddress ||
    req.socket.remoteAddress ||
    req.connection.socket.remoteAddress;
}
<|endoftext|>


<commit_before>/* File contains code for procedural quest generation. */

const prettybnf = require('prettybnf');
const debug = require('debug')('bitn:quest-gen');
// const fs = require('fs');
const RG = require('../src/rg');
RG.Random = require('../src/random');

const questGrammar = require('./quest-grammar');

const RNG = RG.Random.getRNG();

RNG.setSeed(Date.now());

/* A task represents a part of a quest. */
const Task = function(taskType) {
    this.stepType = 'Task';
    this.name = '';
    this.isQuest = () => false;
    this.taskType = taskType;
};

Task.prototype.getName = function() {
    return this.name;
};

Task.prototype.getTaskType = function() {
    return this.taskType;
};

/* A quest object which can be used to model quests. */
const Quest = function(name) {
    this.name = name;
    this.steps = []; // Atomics/sub-quests
    this.testType = 'Quest';

    this.isQuest = () => true;

    this.add = function(step) {
        if (Array.isArray(step)) {
            this.steps = this.steps.concat(step);
        }
        else {
            this.steps.push(step);
        }
    };

    this.numQuests = function() {
        let sum = 1;
        this.steps.forEach(step => {
            if (step.isQuest && step.isQuest()) {
                sum += 1;
            }
        });
        return sum;
    };

    /* Returns the number of immediate tasks. */
    this.numTasks = function() {
        const numSubquests = this.numQuests() - 1;
        return this.steps.length - numSubquests;
    };

    this.getSteps = function() {
        return this.steps.slice();
    };
};

/* Code adapted from erratic by Daniel Connelly. */
function extract(prop, o) {
    return o[prop];
}

/* Chooses a random rule from arrOfRules. */
function chooseRandomRule(arrOfRules) {
    if (Array.isArray(arrOfRules)) {
        const result = RNG.arrayGetRand(arrOfRules);
        debug('choose RANDOM', result);
        return result;
    }
    else {
        debug(`chooseRandomRule() not an ARRAY: |${arrOfRules}`);
    }
    return null;
}

/* QuestGen object. */
const QuestGen = function() {
    this._init();
};

/* Can be used for creating quest grammar/rules from a string in BNF format. */
QuestGen.parse = function(grammar) {
    const ast = prettybnf.parse(grammar);
    const rules = {};
    ast.productions.forEach(prod => {
        rules[prod.lhs.text] = prod.rhs.map(extract.bind(null, 'terms'));
    });
    return rules;
};

QuestGen.prototype._init = function() {
    this.stack = []; // Stack for quests
    this.currQuest = null;
    this.ruleHist = {};
    this.startRule = 'QUEST';
};

QuestGen.rules = QuestGen.parse(questGrammar);

/* Default config for quest generation. */
QuestGen.defaultConfig = {
    rules: QuestGen.rules,
    startRule: 'QUEST',
    maxTries: 20,
    debug: false,
    minQuests: 1,
    maxQuests: -1,
    minLength: 1,
    maxLength: -1
};

QuestGen.prototype.genQuestWithConf = function(conf = {}) {
    if (conf.debug) {debug.enabled = true;}
    const questRules = conf.rules || QuestGen.rules;
    const startRule = conf.startRule || 'QUEST';
    this.startRule = startRule;
    let ok = false;
    let watchdog = conf.maxTries || 20;
    let quest = [];
    while (!ok) {
        this._init();

        debug('=== Generating new quest now ===');
        quest = this.generateQuest(questRules, startRule).split('|');
        ok = this._questMeetsReqs(quest, conf);
        if (!ok) {
            debug('QUEST DISCARDED');
        }

        if (--watchdog === 0) {
            console.warn('Could not find a matching quest.');
            break;
        }
    }

    // return quest;
    return this.currQuest;
};

QuestGen.prototype.genQuestWithName = function(name) {
    const quest = new Quest(name);
    const taskGoto = new Task('<goto>already_there');
    quest.add(taskGoto);
    const taskKill = new Task('<kill>kill');
    quest.add(taskKill);
    return quest;
};

QuestGen.prototype._questMeetsReqs = function(quest, conf) {
    let ok = true;

    // Check if quest min/max length is met
    const minLength = conf.minLength || 1;
    const maxLength = conf.maxLength || -1;
    if (quest.length <= maxLength || maxLength === -1) {
        if (quest.length >= minLength) {
            ok = true;
            debug('MATCHING QUEST FOUND');
        }
        else {ok = false;}
    }
    else {ok = false;}

    if (conf.minQuests) {
        ok = ok && this.currQuest.numQuests() >= conf.minQuests;
    }
    if (conf.maxQuests) {
        ok = ok && this.currQuest.numQuests() <= conf.maxQuests;
    }
    return ok;
};

QuestGen.prototype.generateQuest = function(rules, rule) {
    if (!this.ruleHist[rule]) {this.ruleHist[rule] = 1;}
    else {this.ruleHist[rule] += 1;}

    if (rule === this.startRule) {
        debug('New (sub)-quest will be generated');
        this.currQuest = new Quest();
        this.stack.push(this.currQuest);
    }
    const randRule = chooseRandomRule(rules[rule]);
    if (Array.isArray(randRule)) {
        const steps = randRule.map(this.generateTerm.bind(this, rules));
        // const tasks = steps.map(step => new Task(step));
        // this.currQuest.add(tasks);
        this._checkIfQuestOver(rule);
        return steps.join('|');
    }
    debug(`generateQuest end reached, return |${randRule}|`);
    this._checkIfQuestOver(rule);
    return randRule;
};

QuestGen.prototype.generateTerm = function(rules, term) {
    if (!term.text) {
        const json = JSON.stringify(rules);
        throw new Error('Null/undef term.text with rules|', json, '|');
    }
    if (term.type === 'terminal') {
        this.currQuest.add(new Task(term.text));
        return term.text;
    }
    debug(`calling generate() with term.text |${term.text}|`);
    return this.generateQuest(rules, term.text);
};

QuestGen.prototype._checkIfQuestOver = function(rule) {
    if (rule === this.startRule) {
        debug('Finishing current quest');
        const qLen = this.stack.length;
        if (qLen > 1) {
            const subQuest = this.stack.pop();
            this.currQuest = this.stack[this.stack.length - 1];
            this.currQuest.add(subQuest);
        }
    }
};

const QuestData = function() {
    this.stacks = {};
    this.path = [];
    this._ptr = {}; // Pointers for iteration
};

QuestData.prototype.pop = function(targetType) {
    if (this.stacks[targetType]) {
        return this.stacks[targetType].pop();
    }
    return null;
};

QuestData.prototype.next = function(targetType) {
    if (this.stacks[targetType]) {
        if (!this._ptr.hasOwnProperty(targetType)) {
            this._ptr[targetType] = 0;
        }
        const ptrVal = this._ptr[targetType];
        if (ptrVal < this.stacks[targetType].length) {
            ++this._ptr[targetType];
            return this.stacks[targetType][ptrVal];
        }
    }
    return null;
};

QuestData.prototype.getCurrent = function(targetType) {
    if (this.stacks[targetType]) {
        const stack = this.stacks[targetType];
        return stack[stack.length - 1];
    }
    return null;
};

QuestData.prototype.add = function(targetType, obj) {
    if (!this.stacks[targetType]) {
        this.stacks[targetType] = obj;
    }
    this.stacks[targetType].push(obj);
    this.path.push(targetType);
};

/* Returns human-readable description of the quest. */
QuestData.prototype.toString = function() {
    let res = '';
    this.path.forEach(step => {
        res += step + ' ' + this.next(step).getName() + '. ';
    });
    return res;
};

//---------------------------------------------------------------------------
// OBJECT QUEST-POPULATE
//---------------------------------------------------------------------------

const QuestPopulate = function() {
    this.questData = {
        quests: [] // Stack of quests, current is the last
    };
};

QuestPopulate.prototype.createQuests = function(world, area, x, y) {
    const areaTile = area.getTileXY(x, y);
    const cities = areaTile.getZones('City');
    cities.forEach(city => {
        this.createQuestsForZone(city, areaTile);
    });
};

QuestPopulate.prototype.createQuestsForZone = function(zone, areaTile) {
    const numQuests = 1;
    for (let i = 0; i < numQuests; i++) {
        const questGen = new QuestGen();
        const quest = questGen.genQuestWithConf({maxLength: 10, minLength: 1});
        this.questData = {quests: []};
        this.mapQuestToResources(quest, zone, areaTile);
    }
};

QuestPopulate.prototype.mapQuestToResources = function(quest, zone, areaTile) {
    this.currQuest = new QuestData();
    this.questData.quests.push(this.currQuest);
    this.currQuest.add('location', zone);
    quest.getSteps().forEach(step => {
        const currLoc = this.currQuest.getCurrent('location');
        if (step.isQuest()) {
            // Recursive call for sub-quests, check which is the current
            // location for the quest
            this.mapQuestToResources(step, currLoc, areaTile);
        }
        else {
            this.mapTask(quest, step, currLoc, areaTile);
        }
    });
    if (this.questData.quests.length > 1) {
        this.currQuest = this.questData.quests.pop();
    }
    // Finally, add a quest to quest giver
    console.log('Created quest: ' + this.currQuest.toString());
};

/* Maps a single task to resources. Prev. or next step may also affect mapping.
 * */
QuestPopulate.prototype.mapTask = function(quest, task, zone, areaTile) {
    switch (task.getTaskType()) {
        case '<kill>kill': {
            const location = this.currQuest.getCurrent('location');
            const level = location.getLevels()[0];
            const actorToKill = RNG.arrayGetRand(level.getActors());
            this.currQuest.add('kill', actorToKill);
            break;
        }
        case '<goto>already_there': {
            this.currQuest.add('location', zone);
            break;
        }
        case '<goto>goto': {
            const newLocation = this.getNewLocation(zone, areaTile);
            this.currQuest.add('location', newLocation);
            break;
        }
        default: {
            console.log(`Task type ${task.taskType} not supported yet`);
        }
    }
};

const runningAsScript = !module.parent;
if (runningAsScript) {
    // The grammar is stored in the string g
    // console.log(JSON.stringify(rules));
    // console.log(generateQuest(rules, 'QUEST'));
    const questGen = new QuestGen();
    console.log(questGen.genQuestWithConf({maxLength: 10, minLength: 3}));
    console.log(JSON.stringify(questGen.stack));
    console.log(JSON.stringify(questGen.ruleHist));
}

module.exports = {
    Quest, Task, QuestGen, QuestPopulate
};
<commit_msg>Added addQuestComponents().<commit_after>/* File contains code for procedural quest generation. */

const prettybnf = require('prettybnf');
const debug = require('debug')('bitn:quest-gen');
// const fs = require('fs');
const RG = require('../src/rg');
RG.Random = require('../src/random');

const questGrammar = require('../data/quest-grammar');

const RNG = RG.Random.getRNG();

RNG.setSeed(Date.now());

/* A task represents a part of a quest. */
const Task = function(taskType) {
    this.stepType = 'Task';
    this.name = '';
    this.taskType = taskType;
};

Task.prototype.isTask = function() {return true;};
Task.prototype.isQuest = function() {return false;};

Task.prototype.getName = function() {
    return this.name;
};

Task.prototype.getTaskType = function() {
    return this.taskType;
};

/* A quest object which can be used to model quests. */
const Quest = function(name, tasks) {
    this.name = name;
    this.steps = []; // Atomics/sub-quests
    this.testType = 'Quest';

    if (Array.isArray(tasks)) {
        tasks.forEach(taskType => {
            const task = new Task(taskType);
            this.add(task);
        });
    }
};

Quest.prototype.isTask = function() {return false;};
Quest.prototype.isQuest = function() {return true;};

Quest.prototype.getTasks = function() {
    return this.steps.filter(step => step.isTask());
};

Quest.prototype.add = function(step) {
    if (Array.isArray(step)) {
        this.steps = this.steps.concat(step);
    }
    else {
        this.steps.push(step);
    }
};

Quest.prototype.numQuests = function() {
    let sum = 1;
    this.steps.forEach(step => {
        if (step.isQuest && step.isQuest()) {
            sum += 1;
        }
    });
    return sum;
};

/* Returns the number of immediate tasks. */
Quest.prototype.numTasks = function() {
    const numSubquests = this.numQuests() - 1;
    return this.steps.length - numSubquests;
};

Quest.prototype.getSteps = function() {
    return this.steps.slice();
};

/* Code adapted from erratic.js by Daniel Connelly. */
function extract(prop, o) {
    return o[prop];
}

/* Chooses a random rule from arrOfRules. */
function chooseRandomRule(arrOfRules) {
    if (Array.isArray(arrOfRules)) {
        const result = RNG.arrayGetRand(arrOfRules);
        debug('choose RANDOM', result);
        return result;
    }
    else {
        debug(`chooseRandomRule() not an ARRAY: |${arrOfRules}`);
    }
    return null;
}

//---------------------------------------------------------------------------
// QUESTGEN for generating quest sequences procedurally
//---------------------------------------------------------------------------
const QuestGen = function() {
    this._init();
};

/* Can be used for creating quest grammar/rules from a string in BNF format. */
QuestGen.parse = function(grammar) {
    const ast = prettybnf.parse(grammar);
    const rules = {};
    ast.productions.forEach(prod => {
        rules[prod.lhs.text] = prod.rhs.map(extract.bind(null, 'terms'));
    });
    return rules;
};

QuestGen.prototype._init = function() {
    this.stack = []; // Stack for quests
    this.currQuest = null;
    this.ruleHist = {};
    this.startRule = 'QUEST';
};

QuestGen.rules = QuestGen.parse(questGrammar);

/* Default config for quest generation. */
QuestGen.defaultConfig = {
    rules: QuestGen.rules,
    startRule: 'QUEST',
    maxTries: 20,
    debug: false,
    minQuests: 1,
    maxQuests: -1,
    minLength: 1,
    maxLength: -1
};

QuestGen.prototype.genQuestWithConf = function(conf = {}) {
    if (conf.debug) {debug.enabled = true;}
    const questRules = conf.rules || QuestGen.rules;
    const startRule = conf.startRule || 'QUEST';
    this.startRule = startRule;
    let ok = false;
    let watchdog = conf.maxTries || 20;
    let quest = [];
    while (!ok) {
        this._init();

        debug('=== Generating new quest now ===');
        quest = this.generateQuest(questRules, startRule).split('|');
        ok = this._questMeetsReqs(quest, conf);
        if (!ok) {
            debug('QUEST DISCARDED');
        }

        if (--watchdog === 0) {
            console.warn('Could not find a matching quest.');
            break;
        }
    }

    // return quest;
    return this.currQuest;
};

QuestGen.prototype.genQuestWithName = function(name) {
    const quest = new Quest(name);
    const taskGoto = new Task('<goto>already_there');
    quest.add(taskGoto);
    const taskKill = new Task('<kill>kill');
    quest.add(taskKill);
    return quest;
};

QuestGen.prototype._questMeetsReqs = function(quest, conf) {
    let ok = true;

    // Check if quest min/max length is met
    const minLength = conf.minLength || 1;
    const maxLength = conf.maxLength || -1;
    if (quest.length <= maxLength || maxLength === -1) {
        if (quest.length >= minLength) {
            ok = true;
            debug('MATCHING QUEST FOUND');
        }
        else {ok = false;}
    }
    else {ok = false;}

    if (conf.minQuests) {
        ok = ok && this.currQuest.numQuests() >= conf.minQuests;
    }
    if (conf.maxQuests) {
        ok = ok && this.currQuest.numQuests() <= conf.maxQuests;
    }
    return ok;
};

QuestGen.prototype.generateQuest = function(rules, rule) {
    if (!this.ruleHist[rule]) {this.ruleHist[rule] = 1;}
    else {this.ruleHist[rule] += 1;}

    if (rule === this.startRule) {
        debug('New (sub)-quest will be generated');
        this.currQuest = new Quest();
        this.stack.push(this.currQuest);
    }

    const randRule = chooseRandomRule(rules[rule]);
    if (Array.isArray(randRule)) {
        const steps = randRule.map(this.generateTerm.bind(this, rules));
        this._checkIfQuestOver(rule);
        return steps.join('|');
    }

    debug(`generateQuest end reached, return |${randRule}|`);
    this._checkIfQuestOver(rule);
    return randRule;
};

QuestGen.prototype.generateTerm = function(rules, term) {
    if (!term.text) {
        const json = JSON.stringify(rules);
        throw new Error('Null/undef term.text with rules|', json, '|');
    }

    if (term.type === 'terminal') {
        this.currQuest.add(new Task(term.text));
        return term.text;
    }

    debug(`calling generate() with term.text |${term.text}|`);
    return this.generateQuest(rules, term.text);
};

QuestGen.prototype._checkIfQuestOver = function(rule) {
    if (rule === this.startRule) {
        debug('Finishing current quest');
        const qLen = this.stack.length;
        if (qLen > 1) {
            const subQuest = this.stack.pop();
            this.currQuest = this.stack[this.stack.length - 1];
            this.currQuest.add(subQuest);
        }
    }
};

//---------------------------------------------------------------------------
// QUESTDATA for storing quest mapping information
//---------------------------------------------------------------------------

const QuestData = function() {
    this.stacks = {};
    this.path = [];
    this._ptr = {}; // Pointers for iteration
};

QuestData.prototype.keys = function() {
    const keys = Object.keys(this.stacks);
    console.log('QuestData keys returning', keys);
    return keys;
};

QuestData.prototype.pop = function(targetType) {
    if (this.stacks[targetType]) {
        return this.stacks[targetType].pop();
    }
    return null;
};

/* Reset iterators of the quest data. */
QuestData.prototype.resetIter = function() {
    this.keys().forEach(targetType => {
        this._ptr[targetType] = 0;
    });
};

QuestData.prototype.next = function(targetType) {
    if (this.stacks[targetType]) {
        if (!this._ptr.hasOwnProperty(targetType)) {
            this._ptr[targetType] = 0;
        }
        const ptrVal = this._ptr[targetType];
        if (ptrVal < this.stacks[targetType].length) {
            ++this._ptr[targetType];
            return this.stacks[targetType][ptrVal];
        }
    }
    return null;
};

QuestData.prototype.getCurrent = function(targetType) {
    if (this.stacks[targetType]) {
        const stack = this.stacks[targetType];
        return stack[stack.length - 1];
    }
    return null;
};

QuestData.prototype.add = function(targetType, obj) {
    if (!this.stacks[targetType]) {
        this.stacks[targetType] = [];
    }
    this.stacks[targetType].push(obj);
    this.path.push(targetType);
};

/* Returns human-readable description of the quest. */
QuestData.prototype.toString = function() {
    let res = '';
    this.path.forEach(step => {
        res += step + ' ' + this.next(step).getName() + '. ';
    });
    return res;
};

//---------------------------------------------------------------------------
// OBJECT QUEST-POPULATE
//---------------------------------------------------------------------------

const QuestPopulate = function() {
    this.questData = {
        quests: [] // Stack of quests, current is the last
    };
    this.questList = [];
};

QuestPopulate.prototype.createQuests = function(world, area, x, y) {
    const areaTile = area.getTileXY(x, y);
    const cities = areaTile.getZones('City');
    cities.forEach(city => {
        this.createQuestsForZone(city, areaTile);
    });
};

QuestPopulate.prototype.createQuestsForZone = function(zone, areaTile) {
    const numQuests = 1;
    for (let i = 0; i < numQuests; i++) {
        const questGen = new QuestGen();
        const quest = questGen.genQuestWithConf({maxLength: 10, minLength: 1});
        this.questData = {quests: []};
        this.mapQuestToResources(quest, zone, areaTile);
        this.addQuestComponents(zone);
    }
};

QuestPopulate.prototype.mapQuestToResources = function(quest, zone, areaTile) {
    this.currQuest = new QuestData();
    this.questData.quests.push(this.currQuest);
    this.currQuest.add('location', zone);
    quest.getSteps().forEach(step => {
        const currLoc = this.currQuest.getCurrent('location');
        if (step.isQuest()) {
            // Recursive call for sub-quests, check the current
            // location for the quest
            this.mapQuestToResources(step, currLoc, areaTile);
        }
        else {
            this.mapTask(quest, step, currLoc, areaTile);
        }
    });

    const nQuests = this.questData.quests.length;
    if (nQuests > 1) {
        this.questList.unshift(this.questData.quests.pop());
        this.currQuest = this.questData.quests[nQuests - 2];
    }
    else {
        this.questList.unshift(this.currQuest);
    }
    // Finally, add a quest to quest giver
    console.log('Created quest: ' + this.currQuest.toString());
};

/* Maps a single task to resources. Prev. or next step may also affect mapping.
 * */
QuestPopulate.prototype.mapTask = function(quest, task, zone, areaTile) {
    console.log('mapTask taskType is now', task.getTaskType());
    switch (task.getTaskType()) {
        case '<kill>kill': {
            const location = this.currQuest.getCurrent('location');
            const level = location.getLevels()[0]; // TODO make random
            const actorToKill = RNG.arrayGetRand(level.getActors());
            this.currQuest.add('kill', actorToKill);
            console.log('mapTask added an actor to kill');
            break;
        }
        case '<goto>already_there': {
            // Don't add current location because it's already in the stack
            // this.currQuest.add('location', zone);
            break;
        }
        case '<goto>goto': {
            const newLocation = this.getNewLocation(zone, areaTile);
            this.currQuest.add('location', newLocation);
            break;
        }
        default: {
            console.log(`Task type ${task.taskType} not supported yet`);
        }
    }
};

QuestPopulate.prototype.addQuestComponents = function(zone) {
    console.log('Adding quest components now');
    console.log('QuestList', JSON.stringify(this.questList));
    this.questList.forEach(questData => {
        questData.resetIter();
        questData.keys().forEach(key => {
            if (key === 'kill') {
                console.log('addQuestComponents Key was ' + key);
                let killTarget = questData.next(key);
                while (killTarget) {
                    const killComp = new RG.Component.QuestTarget();
                    killComp.setTargetType(key);
                    killComp.setTarget(killTarget);
                    killTarget.add(killComp);
                    killTarget = questData.next(key);
                }
            }
            else {
                console.log('addQuestComponents Key was ' + key);
            }
        });

        // Grab random actor and make it the quest giver
        const level = RNG.arrayGetRand(zone.getLevels());
        const questGiver = RNG.arrayGetRand(level.getActors());
        const giverComp = new RG.Component.QuestGiver(questData);
        giverComp.setQuestData(questData);
        questGiver.add(giverComp);
        console.log('QuestGiver will be ' + questGiver.getName());
    });

};

const runningAsScript = !module.parent;
if (runningAsScript) {
    // The grammar is stored in the string g
    // console.log(JSON.stringify(rules));
    // console.log(generateQuest(rules, 'QUEST'));
    const questGen = new QuestGen();
    console.log(questGen.genQuestWithConf({maxLength: 10, minLength: 3}));
    console.log(JSON.stringify(questGen.stack));
    console.log(JSON.stringify(questGen.ruleHist));
}

module.exports = {
    Quest, Task, QuestGen, QuestPopulate
};
<|endoftext|>