<commit_before>import _ from 'lodash';
import * as TextFormatting from 'src/helpers/TextFormatting';
import formatIrcMessage from 'src/libs/MessageFormatter';
import state from './state';

let nextId = 0;

export default class Message {
    constructor(message, user) {
        this.id = nextId++;
        this.time = message.time || Date.now();
        this.nick = message.nick;
        this.message = message.message;
        this.tags = message.tags;
        this.type = message.type || 'message';
        this.type_extra = message.type_extra;
        this.ignore = false;
        this.mentioned_urls = [];
        this.html = '';

        // We don't want the user object to be enumerable
        Object.defineProperty(this, 'user', {
            value: user,
        });
    }

    toHtml(messageList) {
        if (this.html) {
            return this.html;
        }

        let showEmoticons = state.setting('buffers.show_emoticons') &&
            !messageList.buffer.isSpecial();
        let emojiList = state.setting('emojis');
        let emojiLocation = state.setting('emojiLocation');
        let userList = messageList.buffer.users;
        let useExtraFormatting = !messageList.buffer.isSpecial() &&
            messageList.useExtraFormatting &&
            this.type === 'privmsg';

        let html = '';
        let blocks = formatIrcMessage(this.message, {
            extras: useExtraFormatting,
        });

        blocks.forEach((bl, idx) => {
            let style = '';
            let classes = '';

            Object.keys(bl.styles).forEach(s => {
                if (s === 'underline') {
                    style += 'text-decoration:underline;';
                } else if (s === 'bold') {
                    style += 'font-weight:bold;';
                } else if (s === 'italic') {
                    style += 'font-style:italic;';
                } else if (s === 'quote') {
                    classes += 'kiwi-formatting-extras-quote ';
                } else if (s === 'block') {
                    classes += 'kiwi-formatting-extras-block ';
                } else if (s === 'color') {
                    classes += `irc-fg-colour-${bl.styles[s]} `;
                } else if (s === 'background') {
                    classes += `irc-bg-colour-${bl.styles[s]} `;
                }
            });

            let content = this.enrichText(
                bl.content,
                showEmoticons,
                emojiList,
                emojiLocation,
                userList
            );

            if (style === '' && classes === '') {
                html += content;
            } else if (style !== '' && classes !== '') {
                html += `<span style="${style}" class="${classes}">${content}</span>`;
            } else if (style !== '') {
                html += `<span style="${style}">${content}</span>`;
            } else if (classes !== '') {
                html += `<span class="${classes}">${content}</span>`;
            }
        });

        this.html = html;
        return this.html;
    }

    enrichText(text, showEmoticons, emojiList, emojiLocation, userList) {
        let words = text.split(' ');
        words = words.map((word, wordIdx) => {
            let parsed;

            let linkified = TextFormatting.linkifyUrls(word, {
                addHandle: true,
                handleClass: 'fa fa-chevron-right kiwi-messagelist-message-linkhandle',
            });
            if (linkified.urls.length > 0) {
                this.mentioned_urls = this.mentioned_urls.concat(linkified.urls);
            }
            if (linkified.html !== word) return linkified.html;

            parsed = TextFormatting.linkifyChannels(word);
            if (parsed !== word) return parsed;

            parsed = TextFormatting.linkifyUsers(word, userList);
            if (parsed !== word) return parsed;

            if (showEmoticons) {
                parsed = TextFormatting.addEmojis(
                    { word, words, wordIdx },
                    emojiList,
                    emojiLocation
                );
                if (parsed !== word) return parsed;
            }

            return _.escape(word);
        });

        return words.join(' ');
    }
}
<commit_msg>Plugin support for rendering custom messages<commit_after>import _ from 'lodash';
import * as TextFormatting from 'src/helpers/TextFormatting';
import formatIrcMessage from 'src/libs/MessageFormatter';
import GlobalApi from 'src/libs/GlobalApi';
import state from './state';

let nextId = 0;

export default class Message {
    constructor(message, user) {
        this.id = nextId++;
        this.time = message.time || Date.now();
        this.nick = message.nick;
        this.message = message.message;
        this.tags = message.tags;
        this.type = message.type || 'message';
        this.type_extra = message.type_extra;
        this.ignore = false;
        this.mentioned_urls = [];
        this.html = '';

        // We don't want the user object to be enumerable
        Object.defineProperty(this, 'user', {
            value: user,
        });
    }

    toHtml(messageList) {
        if (this.html) {
            return this.html;
        }

        // Allow plugins to render their own messages if needed
        GlobalApi.singleton().emit('message:render', { message: this });
        if (this.html) {
            return this.html;
        }

        let showEmoticons = state.setting('buffers.show_emoticons') &&
            !messageList.buffer.isSpecial();
        let emojiList = state.setting('emojis');
        let emojiLocation = state.setting('emojiLocation');
        let userList = messageList.buffer.users;
        let useExtraFormatting = !messageList.buffer.isSpecial() &&
            messageList.useExtraFormatting &&
            this.type === 'privmsg';

        let html = '';
        let blocks = formatIrcMessage(this.message, {
            extras: useExtraFormatting,
        });

        blocks.forEach((bl, idx) => {
            let style = '';
            let classes = '';

            Object.keys(bl.styles).forEach(s => {
                if (s === 'underline') {
                    style += 'text-decoration:underline;';
                } else if (s === 'bold') {
                    style += 'font-weight:bold;';
                } else if (s === 'italic') {
                    style += 'font-style:italic;';
                } else if (s === 'quote') {
                    classes += 'kiwi-formatting-extras-quote ';
                } else if (s === 'block') {
                    classes += 'kiwi-formatting-extras-block ';
                } else if (s === 'color') {
                    classes += `irc-fg-colour-${bl.styles[s]} `;
                } else if (s === 'background') {
                    classes += `irc-bg-colour-${bl.styles[s]} `;
                }
            });

            let content = this.enrichText(
                bl.content,
                showEmoticons,
                emojiList,
                emojiLocation,
                userList
            );

            if (style === '' && classes === '') {
                html += content;
            } else if (style !== '' && classes !== '') {
                html += `<span style="${style}" class="${classes}">${content}</span>`;
            } else if (style !== '') {
                html += `<span style="${style}">${content}</span>`;
            } else if (classes !== '') {
                html += `<span class="${classes}">${content}</span>`;
            }
        });

        this.html = html;
        return this.html;
    }

    enrichText(text, showEmoticons, emojiList, emojiLocation, userList) {
        let words = text.split(' ');
        words = words.map((word, wordIdx) => {
            let parsed;

            let linkified = TextFormatting.linkifyUrls(word, {
                addHandle: true,
                handleClass: 'fa fa-chevron-right kiwi-messagelist-message-linkhandle',
            });
            if (linkified.urls.length > 0) {
                this.mentioned_urls = this.mentioned_urls.concat(linkified.urls);
            }
            if (linkified.html !== word) return linkified.html;

            parsed = TextFormatting.linkifyChannels(word);
            if (parsed !== word) return parsed;

            parsed = TextFormatting.linkifyUsers(word, userList);
            if (parsed !== word) return parsed;

            if (showEmoticons) {
                parsed = TextFormatting.addEmojis(
                    { word, words, wordIdx },
                    emojiList,
                    emojiLocation
                );
                if (parsed !== word) return parsed;
            }

            return _.escape(word);
        });

        return words.join(' ');
    }
}
<|endoftext|>


<commit_before>//
// Constants
//
export const UPDATE_INPUTS = 'UPDATE_INPUTS';
import { UPDATE_USER_CASE } from 'reducers/userCase';

//
// Selectors
//
import { createSelector } from 'reselect';
import incomeTaxRates from 'constants/incomeTaxRates';
import payrollTaxRates from 'constants/payrollTaxRates';
import estateTaxRates from 'constants/estateTaxRates';

export const inputsSelector = state => state.inputs;

export const taxableIncomeSelector = createSelector(
  inputsSelector,
  inputs => inputs.taxableIncome
);
export const filingStatusSelector = createSelector(
  inputsSelector,
  inputs => inputs.filingStatus
);
export const dependentsSelector = createSelector(
  inputsSelector,
  inputs => inputs.dependents
);
export const capitalGainsSelector = createSelector(
  inputsSelector,
  inputs => inputs.capitalGains
);
export const estateBenefitsSelector = createSelector(
  inputsSelector,
  inputs => inputs.estateBenefits
);
export const anticipatedYearlyHealthSpendingSelector = createSelector(
  inputsSelector,
  inputs => inputs.anticipatedYearlyHealthSpending
);

export const agiSelector = createSelector(
  taxableIncomeSelector,
  filingStatusSelector,
  dependentsSelector,
  (income, filingStatus, dependents) => {
    const exemptions = (filingStatus === 'married' ? 2 : 1) + dependents;
    const agi = income - (4000 * exemptions);

    return agi > 0 ? agi : 0;
  }
);

function incomeTaxCalculator(type, agi, filingStatus) {
  const incomeTaxRatesForStatus = incomeTaxRates[filingStatus];
  const incomeTaxBrackets = Array.from(incomeTaxRatesForStatus.keys());
  let totalTax = {
    current: 0,
    sanders: 0,
  };

  for (const bracketCeiling of incomeTaxBrackets) {
    const bracketIndex = incomeTaxBrackets.indexOf(bracketCeiling);
    const bracketFloor =
      bracketIndex === 0
      ? 0
      : incomeTaxBrackets[bracketIndex - 1]
    ;
    let difference;

    if (agi > bracketCeiling) {
      difference = bracketCeiling - bracketFloor;
    } else {
      difference = agi - bracketFloor;
    }

    const currentTax =
      difference * (incomeTaxRatesForStatus.get(bracketCeiling).current[type] / 100)
    ;
    const sandersTax =
      difference * (incomeTaxRatesForStatus.get(bracketCeiling).sanders[type] / 100)
    ;

    totalTax = {
      current: totalTax.current + currentTax,
      sanders: totalTax.sanders + sandersTax,
    };

    if (agi <= bracketCeiling) {
      break;
    }
  }

  return totalTax;
}

export const ordinaryIncomeTaxSelector = createSelector(
  taxableIncomeSelector,
  filingStatusSelector,
  agiSelector,
  (income, filingStatus, agi) => incomeTaxCalculator('ordinaryIncome', agi, filingStatus)
);
export const ordinaryIncomeSavingsSelector = createSelector(
  ordinaryIncomeTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const maxAnticipatedYearlyHealthSpendingSelector = createSelector(
  agiSelector,
  agi => {
    const calculatedMax = agi * 3;

    return calculatedMax > 50000 ? calculatedMax : 50000;
  }
);

export const capitalGainsTaxSelector = createSelector(
  capitalGainsSelector,
  filingStatusSelector,
  agiSelector,
  (income, filingStatus, agi) => incomeTaxCalculator('capitalGains', agi, filingStatus)
);
export const capitalGainsSavingsSelector = createSelector(
  capitalGainsTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const payrollTaxSelector = createSelector(
  agiSelector,
  filingStatusSelector,
  (agi, filingStatus) => {
    const payrollTaxRatesForStatus = payrollTaxRates[filingStatus];
    const payrollTaxBrackets = Array.from(payrollTaxRatesForStatus.keys());

    let totalTax = {
      current: 0,
      sanders: 0,
    };

    for (const bracketCeiling of payrollTaxBrackets) {
      const bracketIndex = payrollTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : payrollTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (agi > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = agi - bracketFloor;
      }

      const currentTax =
        difference * (payrollTaxRatesForStatus.get(bracketCeiling).current / 100)
      ;
      const sandersTax =
        difference * (payrollTaxRatesForStatus.get(bracketCeiling).sanders / 100)
      ;

      totalTax = {
        current: totalTax.current + currentTax,
        sanders: totalTax.sanders + sandersTax,
      };

      if (agi <= bracketCeiling) {
        break;
      }
    }

    return totalTax;
  }
);
export const payrollSavingsSelector = createSelector(
  payrollTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const estateTaxSelector = createSelector(
  estateBenefitsSelector,
  filingStatusSelector,
  (income, filingStatus) => {
    const { current: currentTaxRates, sanders: sandersTaxRates } = estateTaxRates;

    const currentTaxRatesForStatus = currentTaxRates[filingStatus];
    const currentTaxBrackets = Array.from(currentTaxRatesForStatus.keys());
    let currentTaxLiability = 0;

    for (const bracketCeiling of currentTaxBrackets) {
      const bracketIndex = currentTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : currentTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (income > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = income - bracketFloor;
      }

      currentTaxLiability = difference * (currentTaxRatesForStatus.get(bracketCeiling) / 100);

      if (income <= bracketCeiling) {
        break;
      }
    }

    const sandersTaxRatesForStatus = sandersTaxRates[filingStatus];
    const sandersTaxBrackets = Array.from(sandersTaxRatesForStatus.keys());
    let sandersTaxLiability = 0;

    for (const bracketCeiling of sandersTaxBrackets) {
      const bracketIndex = sandersTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : sandersTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (income > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = income - bracketFloor;
      }

      sandersTaxLiability = difference * (sandersTaxRatesForStatus.get(bracketCeiling) / 100);

      if (income <= bracketCeiling) {
        break;
      }
    }

    return {
      current: currentTaxLiability,
      sanders: sandersTaxLiability,
    };
  }
);
export const estateSavingsSelector = createSelector(
  estateTaxSelector,
  tax => tax.current - tax.sanders
);

const sandersACATaxRate = 2.2;
export const acaTaxSelector = createSelector(
  agiSelector,
  anticipatedYearlyHealthSpendingSelector,
  (agi, healthSpending) => ({
    current: healthSpending,
    sanders: (sandersACATaxRate / 100) * agi,
  })
);
export const acaSavingsSelector = createSelector(
  acaTaxSelector,
  tax => tax.current - tax.sanders
);

export const totalSavingsSelector = createSelector(
  ordinaryIncomeSavingsSelector,
  capitalGainsSavingsSelector,
  payrollSavingsSelector,
  acaSavingsSelector,
  (ordinaryIncomeSavings, capitalGainsSavings, payrollSavings, acaSavings) =>
    ordinaryIncomeSavings + capitalGainsSavings + payrollSavings + acaSavings
);

//
// Actions
//
export const actions = {
  updateInputs: (key, val) => ({ type: UPDATE_INPUTS, key, val }),
};

//
// Reducers
//
import cases from 'constants/cases';

export default function (state = {}, action) {
  switch (action.type) {
    case UPDATE_INPUTS:
      return Object.assign({}, state, { [action.key]: action.val });

    case UPDATE_USER_CASE:
      return cases[action.userCase];

    default:
      return state;
  }
}
<commit_msg>footer text<commit_after>//
// Constants
//
export const UPDATE_INPUTS = 'UPDATE_INPUTS';
import { UPDATE_USER_CASE } from 'reducers/userCase';

//
// Selectors
//
import { createSelector } from 'reselect';
import incomeTaxRates from 'constants/incomeTaxRates';
import payrollTaxRates from 'constants/payrollTaxRates';
import estateTaxRates from 'constants/estateTaxRates';

export const inputsSelector = state => state.inputs;

export const taxableIncomeSelector = createSelector(
  inputsSelector,
  inputs => inputs.taxableIncome
);
export const filingStatusSelector = createSelector(
  inputsSelector,
  inputs => inputs.filingStatus
);
export const dependentsSelector = createSelector(
  inputsSelector,
  inputs => inputs.dependents
);
export const capitalGainsSelector = createSelector(
  inputsSelector,
  inputs => inputs.capitalGains
);
export const estateBenefitsSelector = createSelector(
  inputsSelector,
  inputs => inputs.estateBenefits
);
export const anticipatedYearlyHealthSpendingSelector = createSelector(
  inputsSelector,
  inputs => inputs.anticipatedYearlyHealthSpending
);

export const agiSelector = createSelector(
  taxableIncomeSelector,
  capitalGainsSelector,
  filingStatusSelector,
  dependentsSelector,
  (income, capitalGains, filingStatus, dependents) => {
    const exemptions = (filingStatus === 'married' ? 2 : 1) + dependents;
    const agi = (income + capitalGains) - (4000 * exemptions);

    return agi > 0 ? agi : 0;
  }
);

function incomeTaxCalculator(type, agi, filingStatus) {
  const incomeTaxRatesForStatus = incomeTaxRates[filingStatus];
  const incomeTaxBrackets = Array.from(incomeTaxRatesForStatus.keys());
  let totalTax = {
    current: 0,
    sanders: 0,
  };

  for (const bracketCeiling of incomeTaxBrackets) {
    const bracketIndex = incomeTaxBrackets.indexOf(bracketCeiling);
    const bracketFloor =
      bracketIndex === 0
      ? 0
      : incomeTaxBrackets[bracketIndex - 1]
    ;
    let difference;

    if (agi > bracketCeiling) {
      difference = bracketCeiling - bracketFloor;
    } else {
      difference = agi - bracketFloor;
    }

    const currentTax =
      difference * (incomeTaxRatesForStatus.get(bracketCeiling).current[type] / 100)
    ;
    const sandersTax =
      difference * (incomeTaxRatesForStatus.get(bracketCeiling).sanders[type] / 100)
    ;

    totalTax = {
      current: totalTax.current + currentTax,
      sanders: totalTax.sanders + sandersTax,
    };

    if (agi <= bracketCeiling) {
      break;
    }
  }

  return totalTax;
}

export const ordinaryIncomeTaxSelector = createSelector(
  taxableIncomeSelector,
  filingStatusSelector,
  agiSelector,
  (income, filingStatus, agi) => incomeTaxCalculator('ordinaryIncome', agi, filingStatus)
);
export const ordinaryIncomeSavingsSelector = createSelector(
  ordinaryIncomeTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const maxAnticipatedYearlyHealthSpendingSelector = createSelector(
  agiSelector,
  agi => {
    const calculatedMax = agi * 3;

    return calculatedMax > 50000 ? calculatedMax : 50000;
  }
);

export const capitalGainsTaxSelector = createSelector(
  capitalGainsSelector,
  filingStatusSelector,
  agiSelector,
  (income, filingStatus, agi) => incomeTaxCalculator('capitalGains', agi, filingStatus)
);
export const capitalGainsSavingsSelector = createSelector(
  capitalGainsTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const payrollTaxSelector = createSelector(
  agiSelector,
  filingStatusSelector,
  (agi, filingStatus) => {
    const payrollTaxRatesForStatus = payrollTaxRates[filingStatus];
    const payrollTaxBrackets = Array.from(payrollTaxRatesForStatus.keys());

    let totalTax = {
      current: 0,
      sanders: 0,
    };

    for (const bracketCeiling of payrollTaxBrackets) {
      const bracketIndex = payrollTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : payrollTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (agi > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = agi - bracketFloor;
      }

      const currentTax =
        difference * (payrollTaxRatesForStatus.get(bracketCeiling).current / 100)
      ;
      const sandersTax =
        difference * (payrollTaxRatesForStatus.get(bracketCeiling).sanders / 100)
      ;

      totalTax = {
        current: totalTax.current + currentTax,
        sanders: totalTax.sanders + sandersTax,
      };

      if (agi <= bracketCeiling) {
        break;
      }
    }

    return totalTax;
  }
);
export const payrollSavingsSelector = createSelector(
  payrollTaxSelector,
  incomeTax => incomeTax.current - incomeTax.sanders
);

export const estateTaxSelector = createSelector(
  estateBenefitsSelector,
  filingStatusSelector,
  (income, filingStatus) => {
    const { current: currentTaxRates, sanders: sandersTaxRates } = estateTaxRates;

    const currentTaxRatesForStatus = currentTaxRates[filingStatus];
    const currentTaxBrackets = Array.from(currentTaxRatesForStatus.keys());
    let currentTaxLiability = 0;

    for (const bracketCeiling of currentTaxBrackets) {
      const bracketIndex = currentTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : currentTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (income > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = income - bracketFloor;
      }

      currentTaxLiability = difference * (currentTaxRatesForStatus.get(bracketCeiling) / 100);

      if (income <= bracketCeiling) {
        break;
      }
    }

    const sandersTaxRatesForStatus = sandersTaxRates[filingStatus];
    const sandersTaxBrackets = Array.from(sandersTaxRatesForStatus.keys());
    let sandersTaxLiability = 0;

    for (const bracketCeiling of sandersTaxBrackets) {
      const bracketIndex = sandersTaxBrackets.indexOf(bracketCeiling);
      const bracketFloor =
        bracketIndex === 0
        ? 0
        : sandersTaxBrackets[bracketIndex - 1]
      ;
      let difference;

      if (income > bracketCeiling) {
        difference = bracketCeiling - bracketFloor;
      } else {
        difference = income - bracketFloor;
      }

      sandersTaxLiability = difference * (sandersTaxRatesForStatus.get(bracketCeiling) / 100);

      if (income <= bracketCeiling) {
        break;
      }
    }

    return {
      current: currentTaxLiability,
      sanders: sandersTaxLiability,
    };
  }
);
export const estateSavingsSelector = createSelector(
  estateTaxSelector,
  tax => tax.current - tax.sanders
);

const sandersACATaxRate = 2.2;
export const acaTaxSelector = createSelector(
  agiSelector,
  anticipatedYearlyHealthSpendingSelector,
  (agi, healthSpending) => ({
    current: healthSpending,
    sanders: (sandersACATaxRate / 100) * agi,
  })
);
export const acaSavingsSelector = createSelector(
  acaTaxSelector,
  tax => tax.current - tax.sanders
);

export const totalSavingsSelector = createSelector(
  ordinaryIncomeSavingsSelector,
  capitalGainsSavingsSelector,
  payrollSavingsSelector,
  acaSavingsSelector,
  (ordinaryIncomeSavings, capitalGainsSavings, payrollSavings, acaSavings) =>
    ordinaryIncomeSavings + capitalGainsSavings + payrollSavings + acaSavings
);

//
// Actions
//
export const actions = {
  updateInputs: (key, val) => ({ type: UPDATE_INPUTS, key, val }),
};

//
// Reducers
//
import cases from 'constants/cases';

export default function (state = {}, action) {
  switch (action.type) {
    case UPDATE_INPUTS:
      return Object.assign({}, state, { [action.key]: action.val });

    case UPDATE_USER_CASE:
      return cases[action.userCase];

    default:
      return state;
  }
}
<|endoftext|>


<commit_before>var tabsCtrl = require(“/PagingControl/tabs");
var OS_IOS = Titanium.Platform.osname != "android";

var iWidth,
    indicator,
    localArgs,
    anterior = 0,
    atual = 0;

var scrollableView = Titanium.UI.createScrollableView();

var pagingcontrol = Titanium.UI.createScrollView({
	scrollType : 'horizontal',
	width : Ti.UI.FILL,
	contentWidth : 'auto',
	contentHeight : Ti.UI.FILL,
	showHorizontalScrollIndicator : false,
	showVerticalScrollIndicator : false,
	top: 0
});

function postLayout(callback) {
	pagingcontrol.addEventListener('postlayout', function onPostLayout(evt) {

		// callback
		callback();

		// remove eventlistener
		evt.source.removeEventListener('postlayout', onPostLayout);
	});
}

exports.create = function(args) {

	localArgs = args;

	Titanium.API.info(JSON.stringify(localArgs));

	// xml boolean localArgs is string ("false" == true)

	var checkBoolArgs = ['hasTabs', 'findScrollableView'];
	for (item in checkBoolArgs) {
		try {
			localArgs[checkBoolArgs[item]] = JSON.parse(localArgs[checkBoolArgs[item]]);
		} catch (e) {
			delete localArgs[checkBoolArgs[item]];
			Ti.API.error("Unable to set argument '" + checkBoolArgs[item] + "'. It must be boolean.");
		}
	}

	// fill undefined args with defaults
	if (localArgs.indicatorColor == null) {
		localArgs.indicatorColor = "#000";
	};
	if (localArgs.indicatorHeight == null) {
		localArgs.indicatorHeight = 5;
	};
	if (localArgs.hasTabs == null) {
		localArgs.hasTabs = true;
	};
	if (localArgs.scrollOffset == null) {
		localArgs.scrollOffset = 40;
	};
	if (localArgs.height == null) {
		localArgs.height = localArgs.hasTabs ? 48 : 5;
	};
	if (localArgs.width == null) {
		localArgs.width = Ti.UI.FILL;
	};
	if (localArgs.findScrollableView == null) {
		localArgs.findScrollableView = true;
	};
	if (localArgs.tabsColor == null) {
		localArgs.tabsColor = "#EDEDED";
	};
	if (localArgs.dividerColor == null) {
		localArgs.dividerColor = "#CCC";
	};
	if (localArgs.labelsColor == null) {
		localArgs.labelsColor = "#000";
	};
	if (localArgs.highlightEffect == null) {
		localArgs.highlightEffect = false;
	};
	if (localArgs.shadowBar == null) {
		localArgs.shadowBar = true;
	};
	if (localArgs.font == null) {
		localArgs.font = {
	    	fontSize: "12dp",
	    	fontFamily: "Robotto",
	    	fontWeight: "normal"
	    };
	};

	// additional adjustments for tabs
	if (localArgs.hasTabs) {
		localArgs.tabProps = {
			dividerColor : localArgs.dividerColor,
			width : localArgs.tabWidth.toString()
		};
	}

	// apply properties of Ti.UI.View that can be applied to paging control view
	var propsArray = ["backgroundColor", "backgroundImage", "backgroundLeftCap", "backgroundRepeat", "backgroundTopCap", "borderRadius", "borderWidth", "bottom", "height", "horizontalWrap", "left", "opacity", "right", "top", "visible", "width", "zIndex"];

	for (prop in propsArray) {
		if (localArgs[propsArray[prop]]) {
			pagingcontrol[propsArray[prop]] = localArgs[propsArray[prop]];
		}
	}

	// assign passed reference of scrollable view
	if (localArgs["scrollableView"]) {
		scrollableView = localArgs.scrollableView;
	}

	if (localArgs.hasTabs) {

		scrollableView.setViews(localArgs.tabs);

		var titlesArray = [];
		var tempViewArray = localArgs.tabs;
		for (v in tempViewArray) {
			titlesArray.push(tempViewArray[v].title);
		}
		tempViewArray = null;

		// create tabs
		tabsCtrl = tabsCtrl.init({
			tabs : localArgs.tabProps,
			titles : titlesArray,
			font: localArgs.font,
			labelsColor: localArgs.labelsColor,
			highlightEffect: localArgs.highlightEffect
		});

		// add tabs
		pagingcontrol.setBackgroundColor(localArgs.tabsColor);
		pagingcontrol.add(tabsCtrl);

		// add bottom border
		pagingcontrol.add(Ti.UI.createView({
			width : Ti.UI.FILL,
			height : 2,
			bottom : 0,
			backgroundColor : localArgs.tabsColor
		}));

		scrollableView.add(pagingcontrol);

		if(localArgs.shadowBar){
			var shadowBar = Titanium.UI.createImageView({
				top: pagingcontrol.height,
				left: 0,
				right: 0,
				image: "/PagingControl/res/shadowBar.png",
				height: Titanium.UI.SIZE,
				touchEnabled: false
			});
			scrollableView.add(shadowBar);
		}

		// add tab select listener
		tabsCtrl.addEventListener('select', function(e) {

			scrollableView.fireEvent('select', {
				tab : e.tab,
				view : e.view
			});

			if(localArgs.fancyScroll){
				scrollableView.scrollToView(e.tab);
			}else{
				scrollableView.currentPage = e.tab;
				indicator.setLeft(e.tab * iWidth);
			}
		});
	}

	// create the indicator view
	indicator = Ti.UI.createView({
		backgroundColor : localArgs.indicatorColor,
		height : localArgs.indicatorHeight,
		width : Ti.UI.SIZE,
		bottom : 0,
		left : 0,
		zIndex : 2
	});

	adjustePositions();

	// add the indicator
	pagingcontrol.add(indicator);

	// add scroll listener to scrollable view
	scrollableView.addEventListener('scroll', onScroll);

	return scrollableView;
};

/**
 * Callback for scroll event
 */
function onScroll(e) {
	Titanium.API.info("Scroll");

	// restrict this to scrollableView to support nesting scrollableViews
	if (e.source !== scrollableView){
		return;
	}

	// update the indicator position
	indicator.setLeft(e.currentPageAsFloat * iWidth);
	updateOffset(e.currentPageAsFloat);

	if(e.currentPage != undefined){
		atual = e.currentPage;
		if(anterior != atual && localArgs.highlightEffect){
			this.getChildren()[0].getChildren()[0].getChildren()[anterior * 2].getChildren()[0].opacity = 0.4;
			anterior = atual;
		}
		this.getChildren()[0].getChildren()[0].getChildren()[atual * 2].getChildren()[0].opacity = 1;
	}
}

/**
 * sets the tab bar offset
 * @param {Number} index
 */
function updateOffset(index) {
	var width = pagingcontrol.size.width,
	    tabsWidth = tabsCtrl.getWidth(),
	    maxOffset = tabsWidth - width,
	    tabSpace = tabsWidth * index / scrollableView.views.length;

	if (width < tabsWidth) {

		var offset = tabSpace - localArgs.scrollOffset,
		    offsetDp = offset < maxOffset ? offset : maxOffset,
		    newOffset = OS_IOS ? (offsetDp < 0 ? 0 : offsetDp) : DPUnitsToPixels(offsetDp);

		pagingcontrol.setContentOffset({
			x : newOffset,
			y : 0
		}, {
			animated : false
		});
	}
}

function DPUnitsToPixels(TheDPUnits)
{
  return (TheDPUnits * (Titanium.Platform.displayCaps.dpi / 160));
}

/**
 * Adjust initial layout positions
 */
function adjustePositions() {
	var totalWidth = localArgs.hasTabs ? tabsCtrl.getWidth() : pagingcontrol.size.width;
	iWidth = Math.floor(totalWidth / scrollableView.views.length);
	indicator.setWidth(iWidth);
	indicator.setLeft(scrollableView.getCurrentPage() * iWidth);
}

/**
 * if you need to set it in the controller
 * @param {Titanium.UI.Scrollableview} scrollable view
 */
exports.setScrollableView = function(_sv) {
	if (scrollableView) {
		Ti.API.error("Already initialized");
		return;
	}
	scrollableView = _sv;
	postLayout(create);
};
<commit_msg>Wrapped it all one function<commit_after>exports.create = function(args) {

	var tabsCtrl = require("/services/PagingControl/tabs");
	var OS_IOS = Titanium.Platform.osname != "android";

	localArgs = args;

	// fill undefined args with defaults
	if (localArgs.indicatorColor == null) {
		localArgs.indicatorColor = "#000";
	};
	if (localArgs.indicatorHeight == null) {
		localArgs.indicatorHeight = 5;
	};
	if (localArgs.top == null) {
		localArgs.top = 0;
	};
	if (localArgs.hasTabs == null) {
		localArgs.hasTabs = true;
	};
	if (localArgs.scrollOffset == null) {
		localArgs.scrollOffset = 40;
	};
	if (localArgs.height == null) {
		localArgs.height = localArgs.hasTabs ? 48 : 5;
	};
	if (localArgs.scrollableViewHeight == null) {
		localArgs.scrollableViewHeight = Titanium.UI.FILL;
	};
	if (localArgs.width == null) {
		localArgs.width = Ti.UI.FILL;
	};
	if (localArgs.findScrollableView == null) {
		localArgs.findScrollableView = true;
	};
	if (localArgs.tabsColor == null) {
		localArgs.tabsColor = "#EDEDED";
	};
	if (localArgs.dividerColor == null) {
		localArgs.dividerColor = "#CCC";
	};
	if (localArgs.tabWidth == null) {
		localArgs.tabWidth = "80";
	};
	if (localArgs.labelsColor == null) {
		localArgs.labelsColor = "#000";
	};
	if (localArgs.highlightEffect == null) {
		localArgs.highlightEffect = false;
	};
	if (localArgs.shadowBar == null) {
		localArgs.shadowBar = true;
	};
	if (localArgs.font == null) {
		localArgs.font = {
	    	fontSize: "14dp",
	    	fontFamily: 'Roboto-Medium',
	    	fontWeight: "normal"
	    };
	};

	var iWidth,
	    indicator,
	    localArgs,
	    anterior = 0,
		atual = 0;

	var scrollableView = Titanium.UI.createScrollableView({
		top: localArgs.top,
		backgroundColor: 'transparent',
		bubbleParent: false,
		cacheSize: 1,
		currentPage: 0,
		height: localArgs.scrollableViewHeight,
		overScrollMode: Titanium.UI.Android.OVER_SCROLL_NEVER,
		zIndex: 100
		//showPagingControl: true
	});

	var pagingcontrol = Titanium.UI.createScrollView({
		scrollType : 'horizontal',
		bubbleParent: false,
		scrollingEnabled: true,
		width : Ti.UI.FILL,
		contentWidth : 'auto',
		contentHeight : Ti.UI.FILL,
		showHorizontalScrollIndicator : false,
		showVerticalScrollIndicator : false,
		top: 0
	});

	function postLayout(callback) {
		pagingcontrol.addEventListener('postlayout', function onPostLayout(evt) {
			//Titanium.API.info('---------- PagingControl ScrollView PostLayout ----------');
			// callback
			callback();

			// remove eventlistener
			evt.source.removeEventListener('postlayout', onPostLayout);
		});
	}

	////Titanium.API.info(JSON.stringify(localArgs));

	// xml boolean localArgs is string ("false" == true)

	var checkBoolArgs = ['hasTabs', 'findScrollableView'];
	for (item in checkBoolArgs) {
		try {
			localArgs[checkBoolArgs[item]] = JSON.parse(localArgs[checkBoolArgs[item]]);
		} catch (e) {
			delete localArgs[checkBoolArgs[item]];
			Ti.API.error("Unable to set argument '" + checkBoolArgs[item] + "'. It must be boolean.");
		}
	}

	// additional adjustments for tabs
	if (localArgs.hasTabs) {
		localArgs.tabProps = {
			dividerColor : localArgs.dividerColor,
			width : localArgs.tabWidth.toString()
		};
	}

	// apply properties of Ti.UI.View that can be applied to paging control view
	var propsArray = ["backgroundColor", "backgroundImage", "backgroundLeftCap", "backgroundRepeat", "backgroundTopCap", "borderRadius", "borderWidth", "bottom", "height", "horizontalWrap", "left", "opacity", "right", "visible", "width", "zIndex"];

	for (prop in propsArray) {
		if (localArgs[propsArray[prop]]) {
			pagingcontrol[propsArray[prop]] = localArgs[propsArray[prop]];
		}
	}

	// assign passed reference of scrollable view
	if (localArgs["scrollableView"]) {
		scrollableView = localArgs.scrollableView;
	}

	if (localArgs.hasTabs) {

		scrollableView.setViews(localArgs.tabs);

		var titlesArray = [];
		var tempViewArray = localArgs.tabs;
		for (v in tempViewArray) {
			if(tempViewArray[v].title){
				titlesArray.push(tempViewArray[v].title.toUpperCase());
			}else{
				Titanium.API.error('A View de índice ' + v + ' não tem o atributo "title"');
			}
		}
		tempViewArray = null;

		// create tabs
		tabsCtrl = tabsCtrl.init({
			tabs : localArgs.tabProps,
			titles : titlesArray,
			font: localArgs.font,
			labelsColor: localArgs.labelsColor,
			highlightEffect: localArgs.highlightEffect
		});

		// add tabs
		pagingcontrol.setBackgroundColor(localArgs.tabsColor);
		pagingcontrol.add(tabsCtrl);

		// add bottom border
		pagingcontrol.add(Ti.UI.createView({
			width : Ti.UI.FILL,
			height : 2,
			bottom : 0,
			backgroundColor : localArgs.tabsColor
		}));

		scrollableView.add(pagingcontrol);

		if(localArgs.shadowBar){
			var shadowBar = Titanium.UI.createImageView({
				top: pagingcontrol.height,
				left: 0,
				right: 0,
				image: "/shadowBar.png",
				height: Titanium.UI.SIZE,
				touchEnabled: false
			});
			scrollableView.add(shadowBar);
		}

		// add tab select listener
		tabsCtrl.addEventListener('select', function(e) {

			//Titanium.API.info("============= EVENT ==============");
			////Titanium.API.info(JSON.stringify(e));
			//Titanium.API.info("============= EVENT ==============");

			scrollableView.fireEvent('select', {
				tab : e.tab,
				view : e.view
			});

			if(localArgs.fancyScroll){
				scrollableView.scrollToView(e.tab);
			}else{
				scrollableView.currentPage = e.tab;
				indicator.setLeft(e.tab * iWidth);
			}
		});
	}

	// create the indicator view
	indicator = Ti.UI.createView({
		backgroundColor : localArgs.indicatorColor,
		height : localArgs.indicatorHeight,
		width : Ti.UI.SIZE,

		bottom : 0,
		left : 0,
		zIndex : 2
	});

	adjustePositions();

	// add the indicator
	pagingcontrol.add(indicator);

	// add scroll listener to scrollable view
	scrollableView.addEventListener('scroll', onScroll);

	// FUNCTIONS SECTIO ======================================================================
	/**
	 * Callback for scroll event
	 */
	function onScroll(e) {
		//Titanium.API.info("========== PagingControl ScrollableView Scroll ===========");

		// restrict this to scrollableView to support nesting scrollableViews
		if (e.source !== scrollableView){
			return;
		}

		// update the indicator position
		indicator.setLeft(e.currentPageAsFloat * iWidth);
		updateOffset(e.currentPageAsFloat);

		if(e.currentPage != undefined){
			atual = e.currentPage;
			if(anterior != atual && localArgs.highlightEffect){
				this.getChildren()[0].getChildren()[0].getChildren()[anterior * 2].getChildren()[0].opacity = 0.4;
				anterior = atual;
			}
			this.getChildren()[0].getChildren()[0].getChildren()[atual * 2].getChildren()[0].opacity = 1;
		}
	}

	/**
	 * sets the tab bar offset
	 * @param {Number} index
	 */
	function updateOffset(index) {
		var width = pagingcontrol.size.width,
		    tabsWidth = tabsCtrl.getWidth,
		    maxOffset = tabsWidth - width,
		    tabSpace = tabsWidth * index / scrollableView.views.length;

		if (width < tabsWidth) {

			var offset = tabSpace - localArgs.scrollOffset,
			    offsetDp = offset < maxOffset ? offset : maxOffset,
			    newOffset = OS_IOS ? (offsetDp < 0 ? 0 : offsetDp) : DPUnitsToPixels(offsetDp);

			pagingcontrol.setContentOffset({
				x : newOffset,
				y : 0
			}, {
				animated : false
			});
		}
	}

	function DPUnitsToPixels(TheDPUnits)
	{
	  return (TheDPUnits * (Titanium.Platform.displayCaps.dpi / 160));
	}

	/**
	 * Adjust initial layout positions
	 */
	function adjustePositions() {
		var totalWidth = localArgs.hasTabs ? tabsCtrl.getWidth : pagingcontrol.size.width;
		iWidth = Math.floor(totalWidth / scrollableView.views.length);
		indicator.setWidth(iWidth);
		indicator.setLeft(scrollableView.getCurrentPage() * iWidth);
	}

	scrollableView.cleanup = function() {
		scrollableView.setViews([]);
		scrollableView.removeAllChildren();
		localArgs.tabs && tabsCtrl && tabsCtrller.removeAllChildren();
	};

	return scrollableView;
};
<|endoftext|>


<commit_before>goog.provide('chem.render.Geometry');

/**
 * Static method for calculating geometry center
 * @param {chem.core.Molecule} mol Molecule to calculate geometry center.
 */

chem.render.Geometry.getGeometryCenter=function(mol){
        var totalX=0;
        var totalY=0;
		var atomCount=mol.countAtoms()
        for(var i=0;i<atomCount;i++){
            var atom = mol.getAtom(i);
            totalX+=atom.x;
            totalY+=atom.y;
        }
		return {x:(totalX/atomCount),y:(totalY/atomCount)};
}
<commit_msg>Add Geometry methods<commit_after>goog.provide('chem.render.Geometry');

//Ported from CDK's GeometryTool

/**
 * Calculates the center of the given atoms and returns it as a object.
 * Use return value by result.x and result.y
 *
 * @param {chem.core.Molecule} mol Molecule to calculate geometry center.
 */

chem.render.Geometry.getGeometryCenter=function(mol){
	var totalX=0;
    var totalY=0;
	var atomCount=mol.countAtoms()
    for(var i=0;i<atomCount;i++){
    	var atom = mol.getAtom(i);
        totalX+=atom.x;
        totalY+=atom.y;
	}
	return {x:(totalX/atomCount),y:(totalY/atomCount)};
}

/**
 * Returns the minimum and maximum X and Y coordinates of the atoms in the Molecule
 * Use return value by result.minX, result.maxX, result.minY and result.maxY
 *
 * @param {chem.core.Molecule} mol Molecule to calculate maximum X and Y.
 */

chem.render.Geometry.getMinMax = function(mol){
	var obj={
		minX:Number.MAX_VALUE,
		maxX:-Number.MAX_VALUE,
		minY:Number.MAX_VALUE,
		maxY:-Number.MAX_VALU
	}
	for(var i=0,il=mol.countAtoms();i<=il;i++){
		var atom = mol.getAtom(i);
		if(atom.x>obj.maxX){
			obj.maxX=atom.x;
		}
		if(atom.x<obj.minX){
			obj.minX=atom.x;
		}
		if(atom.y>obj.maxY){
			obj.maxY=atom.x;
		}
		if(atom.y<obj.minY){
			obj.minY=atom.x;
		}
	}
	return obj;
}

/**
 * Translates the given molecule by the given Vector.
 *
 * @param {chem.core.Molecule} mol Molecule to calculate maximum X and Y.
 * @param {number} transX translation in x direction
 * @param {number} transY translation in y direction
 * @param {number} transZ translation in z direction. Optional, default to 0;
 */

chem.render.Geometry.translate2D=function(mol,transX,transY,transZ){
	if(transZ==undefined)transZ=0;
	for (var i = 0, il = mol.countAtoms(); i <= il; i++) {
		var atom = mol.getAtom(i);
		atom.x+=transX;
		atom.y+=transY;
		atom.z+=transZ;
	}
}

/*
 * TODO: To migrate
 *  public static void center(Molecule molecule, Dimension areaDim) {
        Dimension molDim = get2DDimension(molecule);
        int transX = (areaDim.width - molDim.width) / 2;
        int transY = (areaDim.height - molDim.height) / 2;
        translateAllPositive(molecule);
        translate2D(molecule, transX, transY);
    }
    public static Dimension get2DDimension(Molecule molecule) {
        double[] minmax = getMinMax(molecule);
        double maxX = minmax[2];
        double maxY = minmax[3];
        double minX = minmax[0];
        double minY = minmax[1];
        return new Dimension((int) (maxX - minX + 1), (int) (maxY - minY + 1));
    }
 */
/**
 *  Adds an automatically calculated offset to the coordinates of all atoms
 *  such that all coordinates are positive and the smallest x or y coordinate
 *  is exactly zero.
 *
 *	@param {chem.core.Molecule} mol AtomContainer for which all the atoms are translated to positive coordinates
 */

chem.render.Geometry.translateAllPositive=function(mol){
		var minX=Number.MAX_VALUE,minY=Number.MAX_VALUE;
		for(var i=0,il=mol.countAtoms();i<=il;i++){
			var atom = mol.getAtom(i);
			if (atom.x < minX) {
                minX = atom.x;
            }
            if (atom.y < minY) {
                minY = atom.y;
            }
		}
		translate2D(mol, minX * -1, minY * -1);
}   <|endoftext|>


<commit_before>udefine(['../graphics', '../graphics/rootelement'], function(Graphics, createRootElement) {
  'use strict';

  Graphics.renderer = 'Canvas';

  var rootElement = null;
  var context = null;

  Graphics.on('initialize', function(Game) {
    rootElement = createRootElement.call(Game, 'canvas', function(rootElement) {
      rootElement.width = Game.width;
      rootElement.height = Game.height;
      context = rootElement.getContext('2d');
    });
  });

  Graphics.before('render', function(obj) {
    switch (obj.type) {
    case 'Game':
      context.clearRect(0, 0, obj.width, obj.height);

      context.fillStyle = obj.color;
      context.fillRect(0, 0, obj.width, obj.height);
      break;
    default:
      break;
    }
  });

  Graphics.on('render', function(obj) {
    switch (obj.type) {
    case 'GameObject':
      if (obj.texture.color !== 'transparent') {
        context.fillStyle = obj.texture.color;
        context.fillRect(obj.x, obj.y, obj.width, obj.height);
      }

      if (obj.texture.image.drawable) {
        context.drawImage(obj.texture.image.data, obj.x, obj.y);
      }

      if (obj.texture.label.drawable) {

      }
      break;
    case 'Scene':
      if (obj.parent.activeScene !== obj.name) {
        return;
      }
      break;
    default:
      break;
    }
  });

});
<commit_msg>First try at basic text rendering<commit_after>udefine(['../graphics', '../graphics/rootelement'], function(Graphics, createRootElement) {
  'use strict';

  Graphics.renderer = 'Canvas';

  var rootElement = null;
  var context = null;

  Graphics.on('initialize', function(Game) {
    rootElement = createRootElement.call(Game, 'canvas', function(rootElement) {
      rootElement.width = Game.width;
      rootElement.height = Game.height;
      context = rootElement.getContext('2d');
    });
  });

  Graphics.before('render', function(obj) {
    switch (obj.type) {
    case 'Game':
      context.clearRect(0, 0, obj.width, obj.height);

      context.fillStyle = obj.color;
      context.fillRect(0, 0, obj.width, obj.height);
      break;
    default:
      break;
    }
  });

  Graphics.on('render', function(obj) {
    switch (obj.type) {
    case 'GameObject':
      if (obj.texture.color !== 'transparent') {
        context.fillStyle = obj.texture.color;
        context.fillRect(obj.x, obj.y, obj.width, obj.height);
      }

      if (obj.texture.image.drawable) {
        context.drawImage(obj.texture.image.data, obj.x, obj.y);
      }

      if (obj.texture.label.drawable) {
        var fontName = obj.texture.label.font.size + 'px ' + obj.texture.label.font.name;

        context.fillStyle = obj.texture.label.font.color;
        context.fillText(obj.texture.label.text, obj.x, obj.y);
      }
      break;
    case 'Scene':
      if (obj.parent.activeScene !== obj.name) {
        return;
      }
      break;
    default:
      break;
    }
  });

});
<|endoftext|>


<commit_before>'use strict'
const url = require('url')
const util = require('util')
const moment = require('moment')

const pkg = require('../package.json')
const USER_AGENT = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0; ${pkg.name}/${pkg.version}; +${pkg.homepage}) Gecko/20100101 Firefox/59.0`

const fetchBackOff = use('fetch-back-off')
const rawFetch = require('make-fetch-happen').defaults({
  cache: 'no-store',
  retry: 0
})
const tough = require('tough-cookie')

const cache = use('cache')
const curryOptions = use('curry-options')

const CookieJar = tough.CookieJar

const cookieJar = new CookieJar()
const globalCookies = []

module.exports = curryOptions(cookiedFetch, addCookieFuncs, {cookieJar})

let limitedFetch
function cookiedFetch (href, opts) {
  const ourCookieJar = opts.cookieJar || cookieJar
  for (let cookie of globalCookies) {
    try {
      ourCookieJar.setCookieSync(cookie, href)
    } catch (_) {}
  }
  if (opts.referer) {
    if (!opts.headers) opts.headers = {}
    opts.headers.Referer = opts.referer
  }
  if (!limitedFetch) {
    limitedFetch = fetchBackOff(rawFetch.defaults({
      maxConcurrency: opts.maxConcurrency || 4,
      requestsPerSecond: opts.requestsPerSecond || 1
    }))
  }
  return fetchWithCache(limitedFetch, href, opts)
}

function addCookieFuncs (fetch) {
  fetch.setCookieSync = function () {
    const ourCookieJar = fetch.options.cookieJar || cookieJar
    return ourCookieJar.setCookieSync.apply(ourCookieJar, arguments)
  }
  fetch.setGlobalCookie = cookie => { globalCookies.push(cookie); return fetch }
  return fetch
}

function NoNetwork (toFetch, opts) {
  const err = new Error(`Not found in cache: ${toFetch}`)
  err.code = 'ENETWORKDISABLED'
  return err
}

function getCookieStringP (jar, url) {
  return new Promise((resolve, reject) => {
    if (!jar) return resolve()
    return jar.getCookieString(url, (err, cookies) => {
      return err ? reject(err) : resolve(cookies)
    })
  })
}

function setCookieP (jar, cookie, link) {
  const linkP = url.parse(link)
  linkP.pathname = ''
  return new Promise((resolve, reject) => {
    jar.setCookie(cookie, url.format(linkP), (err, cookie) => {
      return err ? reject(err) : resolve(cookie)
    })
  })
}

async function fetchWithCache (fetch, toFetch, opts$) {
  const opts = Object.assign({}, await opts$)
  process.emit('debug', 'Fetching', toFetch, opts)
  if (opts.cacheBreak) await cache.invalidateUrl(toFetch)
  const [meta, content] = await cache.readUrl(toFetch, async (toFetch, meta) => {
    if (opts.noNetwork) throw NoNetwork(toFetch, opts)
    const cookies = await getCookieStringP(opts.cookieJar, toFetch)
    delete opts.cookieJar
    if (!opts.headers) opts.headers = {}
    opts.headers.Cookie = cookies
    const domain = url.parse(toFetch).hostname.replace(/^forums?[.]/, '')
    if (meta.headers && meta.headers['last-modified']) {
      opts.headers['If-Modified-Since'] = meta.headers['last-modified']
    }
    opts.headers['user-agent'] = USER_AGENT
    process.emit('debug', 'Downloading', toFetch, opts)
    return fetch(toFetch, opts)
  })
  if (meta.headers && meta.headers['set-cookie']) {
    for (let rawCookie of meta.headers['set-cookie']) {
      try {
        await setCookieP(opts.cookieJar, rawCookie, meta.finalUrl || toFetch)
      } catch (_) {}
    }
  }
  return [meta, content]
}
<commit_msg>fetch: this is awful, and temporary, but only maintain cookies for one site<commit_after>'use strict'
const url = require('url')
const util = require('util')
const moment = require('moment')

const pkg = require('../package.json')
const USER_AGENT = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0; ${pkg.name}/${pkg.version}; +${pkg.homepage}) Gecko/20100101 Firefox/59.0`

const fetchBackOff = use('fetch-back-off')
const rawFetch = require('make-fetch-happen').defaults({
  cache: 'no-store',
  retry: 0
})
const tough = require('tough-cookie')

const cache = use('cache')
const curryOptions = use('curry-options')

const CookieJar = tough.CookieJar

const cookieJar = new CookieJar()
const globalCookies = []

module.exports = curryOptions(cookiedFetch, addCookieFuncs, {cookieJar})

let limitedFetch
function cookiedFetch (href, opts) {
  const ourCookieJar = opts.cookieJar || cookieJar
  for (let cookie of globalCookies) {
    try {
      ourCookieJar.setCookieSync(cookie, href)
    } catch (_) {}
  }
  if (opts.referer) {
    if (!opts.headers) opts.headers = {}
    opts.headers.Referer = opts.referer
  }
  if (!limitedFetch) {
    limitedFetch = fetchBackOff(rawFetch.defaults({
      maxConcurrency: opts.maxConcurrency || 4,
      requestsPerSecond: opts.requestsPerSecond || 1
    }))
  }
  return fetchWithCache(limitedFetch, href, opts)
}

function addCookieFuncs (fetch) {
  fetch.setCookieSync = function () {
    const ourCookieJar = fetch.options.cookieJar || cookieJar
    return ourCookieJar.setCookieSync.apply(ourCookieJar, arguments)
  }
  fetch.setGlobalCookie = cookie => { globalCookies.push(cookie); return fetch }
  return fetch
}

function NoNetwork (toFetch, opts) {
  const err = new Error(`Not found in cache: ${toFetch}`)
  err.code = 'ENETWORKDISABLED'
  return err
}

function getCookieStringP (jar, url) {
  return new Promise((resolve, reject) => {
    if (!jar) return resolve()
    return jar.getCookieString(url, (err, cookies) => {
      return err ? reject(err) : resolve(cookies)
    })
  })
}

function setCookieP (jar, cookie, link) {
  const linkP = url.parse(link)
  linkP.pathname = ''
  return new Promise((resolve, reject) => {
    jar.setCookie(cookie, url.format(linkP), (err, cookie) => {
      return err ? reject(err) : resolve(cookie)
    })
  })
}

async function fetchWithCache (fetch, toFetch, opts$) {
  const opts = Object.assign({}, await opts$)
  process.emit('debug', 'Fetching', toFetch, opts)
  if (opts.cacheBreak) await cache.invalidateUrl(toFetch)
  const [meta, content] = await cache.readUrl(toFetch, async (toFetch, meta) => {
    if (opts.noNetwork) throw NoNetwork(toFetch, opts)
    const cookies = await getCookieStringP(opts.cookieJar, toFetch)
    delete opts.cookieJar
    if (!opts.headers) opts.headers = {}
    opts.headers.Cookie = cookies
    const domain = url.parse(toFetch).hostname.replace(/^forums?[.]/, '')
    if (meta.headers && meta.headers['last-modified']) {
      opts.headers['If-Modified-Since'] = meta.headers['last-modified']
    }
    opts.headers['user-agent'] = USER_AGENT
    process.emit('debug', 'Downloading', toFetch, opts)
    return fetch(toFetch, opts)
  })
  if (meta.headers && meta.headers['set-cookie'] && /questionablequest/.test(toFetch)) {
    for (let rawCookie of meta.headers['set-cookie']) {
      try {
        await setCookieP(opts.cookieJar, rawCookie, meta.finalUrl || toFetch)
      } catch (_) {}
    }
  }
  return [meta, content]
}
<|endoftext|>


<commit_before>
    /**
     * If needed, adds line numbers with a proper start to the given
     * dom_element
     *
     * @param {Element} dom_element
     */
    function checkLineNumbers( dom_element )
    {
        var $that = $(dom_element).parent();
        var classes = $that.attr( 'class' );
        var ln = /ln-(\d+)-([\w][\w\-]*)|ln-(\d+)|ln-/.exec( classes );
        if ( ln )
        {
            addLineNumbers( dom_element );
            setLineNumbersStart.apply( dom_element, ln );
        }
        else if ( $.chili.options.lineNumbers )
        {
            addLineNumbers(dom_element);
        }
        return;

        /**
         * Sets the start of the ol tag of the current DOM element
         *
         * @param {String} groupStart
         * @param {String} groupId
         * @param {String} start
         */
        function setLineNumbersStart( groupStart, groupId, start )
        {
            if ( groupStart )
            {
                start = parseInt( groupStart, 10 );
                var $pieces = $( '.ln-' + groupStart + '-' + groupId );
                var $that = $(this).parent();
                var pos = $pieces.index( $that[0] );
                $pieces
                    .slice( 0, pos )
                    .each(
                        function()
                        {
                            start += $( this ).find( 'li' ).length;
                        }
                    )
                ;
            }
            else if ( start )
            {
                start = parseInt( start, 10 );
            }
            else
            {
                start = 1;
            }
            $(this).find( 'ol' )[0].start = start;
            // the following should refresh the window
            $('body')
                .width( $('body').width() - 1 )
                .width( $('body').width() + 1 )
            ;
        }

        /**
         * Converts lines inside the given dom_element to list items
         *
         * @param {Element} dom_element
         */
        function addLineNumbers( dom_element )
        {
            var result = $( dom_element ).html();
            result = extractImmediateBreaksInsideSpans(result);
            result = convertLinesInsideSpans(result);
            result = convertRemainingLines(result);
            result = fillEmptyListItems(result);
            result = '
' + result + '
';
            dom_element.innerHTML = result;
        }

    	/**
         * Returns a list item that wraps he given textBeforeLastLine or
         * lastLine
         *
         * @param {String} lineBeforeLastLine
         * @param {String} textBeforeLastLine
         * @param {String} lastLine
         * @param {String} openSpan
         *
         * @return String
         */
        function makeListItem( lineBeforeLastLine, textBeforeLastLine, lastLine, openSpan )
        {
            var closeSpan = openSpan ? '' : '';
            var result = '';
            if (lineBeforeLastLine)
            {
                result = '
' + openSpan + textBeforeLastLine + closeSpan + '
';
            }
            else if (lastLine)
            {
                result = '
' + openSpan + lastLine + closeSpan + '
';
            }
            return result;
        }

        /**
         * Returns the given html, after moving out of the spans their immediate
         * breaks, if any
         *
         * @param {String} html
         *
         * @return String
         */
        function extractImmediateBreaksInsideSpans( html )
        {
            var expr = /(]+>)((?:(?: |\xA0)
)+)(.*?)(<\/span>)/ig;
            var repl = '$2$1$3$4';
            var result = html.replace( expr, repl );
            return result;
        }

        /**
         * Returns the given html, after wrapping each line inside spans with an
         *
 element
         *
         * @param {String} html
         *
         * @return String
         */
        function convertLinesInsideSpans( html )
        {
            var expr = /(.*?)()(.*?)(?:<\/span>(?: |\xA0)
|<\/span>)/ig;
            var repl = function( all, anythingBeforeSpan, openSpan, anythingInsideSpan )
            {
                if (! /
/i.test(anythingInsideSpan))
                {
                    return all;
                }
                var expr = /((.*?)(?: |\xA0)
)|(.*)/ig;
                var repl = function( all, lineBeforeLastLine, textBeforeLastLine, lastLine )
                {
                    var result = makeListItem(lineBeforeLastLine, textBeforeLastLine, lastLine, openSpan);
                    return result;
                };
                var result = anythingBeforeSpan + anythingInsideSpan.replace(expr, repl);
                return result;
            };
            var result = html.replace(expr, repl);
            return result;
        }

        /**
         * Returns the given html, after wrapping each remaining line with an
         *
 element
         *
         * @param {String} html
         *
         * @return String
         */
        function convertRemainingLines( html )
        {
            var expr = /(
.*?<\/li>)|((.*?)(?: |\xA0)
)|(.+)/ig;
            var repl = function( all, prev_li, lineBeforeLastLine, textBeforeLastLine, lastLine )
            {
                if (prev_li)
                {
                    return all;
                }
                var result = makeListItem(lineBeforeLastLine, textBeforeLastLine, lastLine, '');
                return result;
            };
            var result = html.replace(expr, repl);
            return result;
        }

        /**
         * Returns the given html, after filling each empty
 element with a
         * space replacement
         *
         * @param {String} html
         *
         * @return String
         */
        function fillEmptyListItems( html )
        {
            var expr = /
<\/li>/ig;
            var repl = '
' + $.chili.replaceSpace + '
';
            var result = html.replace( expr, repl );
            return result;
        }
    }
<commit_msg>fix - properly start line numbers<commit_after>
    /**
     * If needed, adds line numbers with a proper start to the given
     * dom_element
     *
     * @param {Element} dom_element
     */
    function checkLineNumbers( dom_element )
    {
        var $that = $(dom_element).parent();
        var classes = $that.attr( 'class' );
        var ln = /ln-(\d+)-([\w][\w\-]*)|ln-(\d+)|ln-/.exec( classes );
        if ( ln )
        {
            addLineNumbers( dom_element );
            setLineNumbersStart.apply( dom_element, ln );
        }
        else if ( $.chili.options.lineNumbers )
        {
            addLineNumbers(dom_element);
        }
        return;

        /**
         * Sets the start of the ol tag of the current DOM element
         *
         * @param {String} groupStart
         * @param {String} groupId
         * @param {String} start
         */
        function setLineNumbersStart( all, groupStart, groupId, start )
        {
            if ( groupStart )
            {
                start = parseInt( groupStart, 10 );
                var $pieces = $( '.ln-' + groupStart + '-' + groupId );
                var $that = $(this).parent();
                var pos = $pieces.index( $that[0] );
                $pieces
                    .slice( 0, pos )
                    .each(
                        function()
                        {
                            start += $( this ).find( 'li' ).length;
                        }
                    )
                ;
            }
            else if ( start )
            {
                start = parseInt( start, 10 );
            }
            else
            {
                start = 1;
            }
            $(this).find( 'ol' )[0].start = start;
            // the following should refresh the window
            $('body')
                .width( $('body').width() - 1 )
                .width( $('body').width() + 1 )
            ;
        }

        /**
         * Converts lines inside the given dom_element to list items
         *
         * @param {Element} dom_element
         */
        function addLineNumbers( dom_element )
        {
            var result = $( dom_element ).html();
            result = extractImmediateBreaksInsideSpans(result);
            result = convertLinesInsideSpans(result);
            result = convertRemainingLines(result);
            result = fillEmptyListItems(result);
            result = '
' + result + '
';
            dom_element.innerHTML = result;
        }

    	/**
         * Returns a list item that wraps he given textBeforeLastLine or
         * lastLine
         *
         * @param {String} lineBeforeLastLine
         * @param {String} textBeforeLastLine
         * @param {String} lastLine
         * @param {String} openSpan
         *
         * @return String
         */
        function makeListItem( lineBeforeLastLine, textBeforeLastLine, lastLine, openSpan )
        {
            var closeSpan = openSpan ? '' : '';
            var result = '';
            if (lineBeforeLastLine)
            {
                result = '
' + openSpan + textBeforeLastLine + closeSpan + '
';
            }
            else if (lastLine)
            {
                result = '
' + openSpan + lastLine + closeSpan + '
';
            }
            return result;
        }

        /**
         * Returns the given html, after moving out of the spans their immediate
         * breaks, if any
         *
         * @param {String} html
         *
         * @return String
         */
        function extractImmediateBreaksInsideSpans( html )
        {
            var expr = /(]+>)((?:(?: |\xA0)
)+)(.*?)(<\/span>)/ig;
            var repl = '$2$1$3$4';
            var result = html.replace( expr, repl );
            return result;
        }

        /**
         * Returns the given html, after wrapping each line inside spans with an
         *
 element
         *
         * @param {String} html
         *
         * @return String
         */
        function convertLinesInsideSpans( html )
        {
            var expr = /(.*?)()(.*?)(?:<\/span>(?: |\xA0)
|<\/span>)/ig;
            var repl = function( all, anythingBeforeSpan, openSpan, anythingInsideSpan )
            {
                if (! /
/i.test(anythingInsideSpan))
                {
                    return all;
                }
                var expr = /((.*?)(?: |\xA0)
)|(.*)/ig;
                var repl = function( all, lineBeforeLastLine, textBeforeLastLine, lastLine )
                {
                    var result = makeListItem(lineBeforeLastLine, textBeforeLastLine, lastLine, openSpan);
                    return result;
                };
                var result = anythingBeforeSpan + anythingInsideSpan.replace(expr, repl);
                return result;
            };
            var result = html.replace(expr, repl);
            return result;
        }

        /**
         * Returns the given html, after wrapping each remaining line with an
         *
 element
         *
         * @param {String} html
         *
         * @return String
         */
        function convertRemainingLines( html )
        {
            var expr = /(
.*?<\/li>)|((.*?)(?: |\xA0)
)|(.+)/ig;
            var repl = function( all, prev_li, lineBeforeLastLine, textBeforeLastLine, lastLine )
            {
                if (prev_li)
                {
                    return all;
                }
                var result = makeListItem(lineBeforeLastLine, textBeforeLastLine, lastLine, '');
                return result;
            };
            var result = html.replace(expr, repl);
            return result;
        }

        /**
         * Returns the given html, after filling each empty
 element with a
         * space replacement
         *
         * @param {String} html
         *
         * @return String
         */
        function fillEmptyListItems( html )
        {
            var expr = /
<\/li>/ig;
            var repl = '
' + $.chili.replaceSpace + '
';
            var result = html.replace( expr, repl );
            return result;
        }
    }
<|endoftext|>


<commit_before>(function (factory) {
  var noop = {fn: {}};

  /* istanbul ignore else */
  if (typeof module === "object" && typeof module.exports === "object") {
    module.exports = factory(global.$ || noop);
  } else {
    factory($ || noop);
  }
}(function ($) {

  /* istanbul ignore next */
  $.fn.liteUploader = function (options) {
    return this.each(function () {
      options.ref = options.ref || $(this).attr("name");

      var getFiles = function () {
        return $(this).get(0).files;
      }.bind(this);

      var onEvent = function (name, data) {
        $(this).trigger.bind($(this))(name, [data]);
      }.bind(this)

      $.data(this, "liteUploader", new LiteUploader(options, getFiles, onEvent));
    });
  };

  function LiteUploader (options, getFiles, onEvent) {
    this.options = this._applyDefaults(options);
    this._getFiles = getFiles;
    this._triggerEvent = onEvent;
    this.xhrs = [];
  }

  LiteUploader.prototype = {
    _applyDefaults: function (options) {
      return Object.assign({
        script: null,
        ref: null,
        rules: {},
        params: {},
        headers: {},
        validators: [],
        singleFileUploads: false,
        beforeRequest: function (files, formData) { return Promise.resolve(formData); }
      }, options);
    },

    _init: function (files) {
      files = files || this._getFiles();
      if (!files || !files.length) throw new Error("No files");

      return Promise.all([this._validateOptions(), this._validateFiles(files)])
      .then(function (allErrors) {
        var errors = allErrors[0];
        if (!errors) errors = allErrors[1];

        if (errors) {
          this._triggerEvent("lu:errors", errors);
        } else {
          this._triggerEvent("lu:start", files);
          this.xhrs = [];
          this._startUpload(files);
        }
      }.bind(this));
    },

    _startUpload: function (files) {
      return this._splitFiles(files).map(function (fileSplit) {
        var xhr = this._buildXhrObject(fileSplit);

        return this._beforeRequest(fileSplit)
        .then(function (formData) {
          return xhr.send(formData);
        });
      }.bind(this));
    },

    _splitFiles: function (files) {
      if (this.options.singleFileUploads) {
        return Array.prototype.map.call(files, function (file) {
          return [file];
        });
      } else {
        return [files];
      }
    },

    _beforeRequest: function (files) {
      this._triggerEvent("lu:before", files);
      var formData = this._collateFormData(files);
      return this.options.beforeRequest(files, formData);
    },

    _validateOptions: function () {
      var requiredOptions = ["script", "ref"];

      var errors = requiredOptions.reduce(function (acc, option) {
        if (!this.options[option]) acc.push({ type: option + "Required" });
        return acc;
      }.bind(this), []);

      if (!errors.length) return null;

      return [{
        name: "_options",
        errors: errors
      }];
    },

    _allowedFileTypeValidator: function (rule, file) {
      var allowedTypes = rule.split(",");
      var isWildcardType = /([a-z]+)\/\*$/;

      if (allowedTypes.indexOf(file.type) !== -1) return;

      var allowed = allowedTypes.reduce(function(result, allowedType) {
        if (result) {
          return result;
        } else {
          var matches = allowedType.match(isWildcardType) || [];
          return matches[1] === file.type.split("/")[0];
        }
      }, false);

      if (!allowed) {
        return {
          type: "type",
          rule: rule,
          given: file.type
        };
      }
    },

    _maxSizeValidator: function (rule, file) {
      if (file.size > rule) {
        return {
          type: "size",
          rule: rule,
          given: file.size
        };
      }
    },

    _validateFiles: function (files) {
      var promises = Array.prototype.map.call(files, function (file) {
        return this._validateFile(file);
      }.bind(this));

      return Promise.all(promises)
      .then(function (fileErrors) {
        var allErrors = fileErrors.filter(function (file) {
          return file.errors.length;
        });

        return (allErrors.length) ? allErrors : null;
      });
    },

    _validateFile: function (file) {
      var validatorMap = {
        "allowedFileTypes": this._allowedFileTypeValidator,
        "maxSize": this._maxSizeValidator
      };

      var builtIn = Object.keys(this.options.rules).reduce(function (acc, key) {
        var rule = this.options.rules[key];
        if (rule && validatorMap[key]) acc.push(validatorMap[key](rule, file));
        return acc;
      }.bind(this), []);

      var custom = this.options.validators.map(function (fn) {
        return fn(file);
      });

      return Promise.all(builtIn.concat(custom))
      .then(function (fileErrors) {
        return {
          name: file.name,
          errors: fileErrors.filter(function (error) {
            return !!error;
          })
        }
      });
    },

    _getFormDataObject: function() {
      return new FormData()
    },

    _collateFormData: function (files) {
      var formData = this._getFormDataObject();

      for (var key in this.options.params) {
        formData.append(key, this.options.params[key]);
      }

      Array.prototype.forEach.call(files, function (file) {
        formData.append(this.options.ref, file);
      }.bind(this));

      return formData;
    },

    _getXmlHttpRequestObject: function () {
      return new XMLHttpRequest();
    },

    _buildXhrObject: function (files) {
      var xhr = this._getXmlHttpRequestObject();
      xhr.open("POST", this.options.script);

      for (var key in this.options.headers) {
        xhr.setRequestHeader(key, this.options.headers[key]);
      }

      xhr.upload.addEventListener("progress", this._onXHRProgress.bind(this, files), false);

      xhr.onreadystatechange = function () {
        this._onXHRResponse(xhr);
      }.bind(this);

      this.xhrs.push(xhr);
      return xhr;
    },

    _onXHRProgress: function (files, e) {
      if (!e.lengthComputable) return;

      this._triggerEvent("lu:progress", {
        percentage: Math.floor((e.loaded / e.total) * 100),
        files: files
      });
    },

    _onXHRResponse: function (xhr) {
      if (xhr.readyState !== 4) return;

      if (xhr.status === 200) {
        this._triggerEvent("lu:success", xhr.responseText);
      } else {
        this._triggerEvent("lu:fail", xhr);
      }
    },

    /* Public Methods */

    startUpload: function (files) {
      this._init(files);
    },

    addParam: function (key, value) {
      this.options.params[key] = value;
    },

    cancelUpload: function () {
      this._triggerEvent("lu:cancelled");

      this.xhrs.forEach(function (xhr) {
        xhr.abort();
      });
    }
  };

  return LiteUploader;
}));
<commit_msg>Remove noop in favour of defensive if statement<commit_after>(function (factory) {

  /* istanbul ignore else */
  if (typeof module === "object" && typeof module.exports === "object") {
    module.exports = factory(global.$);
  } else {
    factory($);
  }
}(function ($) {

  /* istanbul ignore next */
  if ($ && $.fn) {
    $.fn.liteUploader = function (options) {
      return this.each(function () {
        options.ref = options.ref || $(this).attr("name");

        var getFiles = function () {
          return $(this).get(0).files;
        }.bind(this);

        var onEvent = function (name, data) {
          $(this).trigger.bind($(this))(name, [data]);
        }.bind(this)

        $.data(this, "liteUploader", new LiteUploader(options, getFiles, onEvent));
      });
    };
  }

  function LiteUploader (options, getFiles, onEvent) {
    this.options = this._applyDefaults(options);
    this._getFiles = getFiles;
    this._triggerEvent = onEvent;
    this.xhrs = [];
  }

  LiteUploader.prototype = {
    _applyDefaults: function (options) {
      return Object.assign({
        script: null,
        ref: null,
        rules: {},
        params: {},
        headers: {},
        validators: [],
        singleFileUploads: false,
        beforeRequest: function (files, formData) { return Promise.resolve(formData); }
      }, options);
    },

    _init: function (files) {
      files = files || this._getFiles();
      if (!files || !files.length) throw new Error("No files");

      return Promise.all([this._validateOptions(), this._validateFiles(files)])
      .then(function (allErrors) {
        var errors = allErrors[0];
        if (!errors) errors = allErrors[1];

        if (errors) {
          this._triggerEvent("lu:errors", errors);
        } else {
          this._triggerEvent("lu:start", files);
          this.xhrs = [];
          this._startUpload(files);
        }
      }.bind(this));
    },

    _startUpload: function (files) {
      return this._splitFiles(files).map(function (fileSplit) {
        var xhr = this._buildXhrObject(fileSplit);

        return this._beforeRequest(fileSplit)
        .then(function (formData) {
          return xhr.send(formData);
        });
      }.bind(this));
    },

    _splitFiles: function (files) {
      if (this.options.singleFileUploads) {
        return Array.prototype.map.call(files, function (file) {
          return [file];
        });
      } else {
        return [files];
      }
    },

    _beforeRequest: function (files) {
      this._triggerEvent("lu:before", files);
      var formData = this._collateFormData(files);
      return this.options.beforeRequest(files, formData);
    },

    _validateOptions: function () {
      var requiredOptions = ["script", "ref"];

      var errors = requiredOptions.reduce(function (acc, option) {
        if (!this.options[option]) acc.push({ type: option + "Required" });
        return acc;
      }.bind(this), []);

      if (!errors.length) return null;

      return [{
        name: "_options",
        errors: errors
      }];
    },

    _allowedFileTypeValidator: function (rule, file) {
      var allowedTypes = rule.split(",");
      var isWildcardType = /([a-z]+)\/\*$/;

      if (allowedTypes.indexOf(file.type) !== -1) return;

      var allowed = allowedTypes.reduce(function(result, allowedType) {
        if (result) {
          return result;
        } else {
          var matches = allowedType.match(isWildcardType) || [];
          return matches[1] === file.type.split("/")[0];
        }
      }, false);

      if (!allowed) {
        return {
          type: "type",
          rule: rule,
          given: file.type
        };
      }
    },

    _maxSizeValidator: function (rule, file) {
      if (file.size > rule) {
        return {
          type: "size",
          rule: rule,
          given: file.size
        };
      }
    },

    _validateFiles: function (files) {
      var promises = Array.prototype.map.call(files, function (file) {
        return this._validateFile(file);
      }.bind(this));

      return Promise.all(promises)
      .then(function (fileErrors) {
        var allErrors = fileErrors.filter(function (file) {
          return file.errors.length;
        });

        return (allErrors.length) ? allErrors : null;
      });
    },

    _validateFile: function (file) {
      var validatorMap = {
        "allowedFileTypes": this._allowedFileTypeValidator,
        "maxSize": this._maxSizeValidator
      };

      var builtIn = Object.keys(this.options.rules).reduce(function (acc, key) {
        var rule = this.options.rules[key];
        if (rule && validatorMap[key]) acc.push(validatorMap[key](rule, file));
        return acc;
      }.bind(this), []);

      var custom = this.options.validators.map(function (fn) {
        return fn(file);
      });

      return Promise.all(builtIn.concat(custom))
      .then(function (fileErrors) {
        return {
          name: file.name,
          errors: fileErrors.filter(function (error) {
            return !!error;
          })
        }
      });
    },

    _getFormDataObject: function() {
      return new FormData()
    },

    _collateFormData: function (files) {
      var formData = this._getFormDataObject();

      for (var key in this.options.params) {
        formData.append(key, this.options.params[key]);
      }

      Array.prototype.forEach.call(files, function (file) {
        formData.append(this.options.ref, file);
      }.bind(this));

      return formData;
    },

    _getXmlHttpRequestObject: function () {
      return new XMLHttpRequest();
    },

    _buildXhrObject: function (files) {
      var xhr = this._getXmlHttpRequestObject();
      xhr.open("POST", this.options.script);

      for (var key in this.options.headers) {
        xhr.setRequestHeader(key, this.options.headers[key]);
      }

      xhr.upload.addEventListener("progress", this._onXHRProgress.bind(this, files), false);

      xhr.onreadystatechange = function () {
        this._onXHRResponse(xhr);
      }.bind(this);

      this.xhrs.push(xhr);
      return xhr;
    },

    _onXHRProgress: function (files, e) {
      if (!e.lengthComputable) return;

      this._triggerEvent("lu:progress", {
        percentage: Math.floor((e.loaded / e.total) * 100),
        files: files
      });
    },

    _onXHRResponse: function (xhr) {
      if (xhr.readyState !== 4) return;

      if (xhr.status === 200) {
        this._triggerEvent("lu:success", xhr.responseText);
      } else {
        this._triggerEvent("lu:fail", xhr);
      }
    },

    /* Public Methods */

    startUpload: function (files) {
      this._init(files);
    },

    addParam: function (key, value) {
      this.options.params[key] = value;
    },

    cancelUpload: function () {
      this._triggerEvent("lu:cancelled");

      this.xhrs.forEach(function (xhr) {
        xhr.abort();
      });
    }
  };

  return LiteUploader;
}));
<|endoftext|>


<commit_before>'use strict';

/*
 * nextroomer is used to build up rooms
 *
 * Bring the controller to level 3 after that build constructionSites
 * and continue upgrading.
 *
 * If the room is 'underSiege', build a tower next to a source, build ramparts
 * and fill the tower.
 */

roles.nextroomer = {};

roles.nextroomer.died = function(name, creepMemory) {
  let roomName = creepMemory.routing.route[creepMemory.routing.route].room;
  let message = `${name} ${roomName} ${JSON.stringify(creepMemory)}`;
  if (roomName === creepMemory.routing.targetRoom) {
    // TODO make underSiege to a counter
  }
  console.log('DIED:', message);
};

roles.nextroomer.settings = {
  layoutString: 'MWC',
  amount: [6, 3, 3],
};

roles.nextroomer.checkForRampart = function(coords) {
  let pos = new RoomPosition(coords.x, coords.y, coords.roomName);
  let structures = pos.lookFor('structure');
  return _.find(structures, (s) => s.structureType === STRUCTURE_RAMPART);
};

roles.nextroomer.buildRamparts = function(creep) {
  let ramparts = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: {
      structureType: STRUCTURE_RAMPART
    }
  });

  // TODO Guess roles.nextroomer should be higher
  let rampartMinHits = 10000;

  creep.say('checkRamparts');
  let posRampart = roles.nextroomer.checkForRampart(creep.pos);
  if (posRampart) {
    if (posRampart.hits < rampartMinHits) {
      creep.repair(posRampart);
      return true;
    }
  } else {
    creep.room.createConstructionSite(creep.pos.x, creep.pos.y, STRUCTURE_RAMPART);
    return true;
  }

  let room = Game.rooms[creep.room.name];
  let linkPosMem = room.memory.position.structure.link[1];
  if (creep.pos.getRangeTo(linkPosMem.x, linkPosMem.y) > 1) {
    linkPosMem = room.memory.position.structure.link[2];
  }

  let links = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: function(object) {
      return object.structureType === STRUCTURE_LINK;
    }
  });
  if (links.length) {
    creep.say('dismantle');
    creep.log(JSON.stringify(links));
    creep.dismantle(links[0]);
    return true;
  }

  creep.say('cr');
  let towerRampart = roles.nextroomer.checkForRampart(linkPosMem);
  if (towerRampart) {
    creep.say('tr');
    if (towerRampart.hits < rampartMinHits) {
      creep.repair(towerRampart);
      return true;
    }
  } else {
    let returnCode = creep.room.createConstructionSite(linkPosMem.x, linkPosMem.y, STRUCTURE_RAMPART);
    creep.log('Build tower rampart: ' + returnCode);
    return true;
  }
  return false;
};

roles.nextroomer.defendTower = function(creep, source) {
  let room = Game.rooms[creep.room.name];
  let constructionSites = creep.pos.findInRange(FIND_CONSTRUCTION_SITES, 1);
  if (constructionSites.length > 0) {
    for (let constructionSiteId in constructionSites) {
      creep.build(constructionSites[constructionSiteId]);
    }
    return true;
  }

  let towers = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: {
      structureType: STRUCTURE_TOWER
    }
  });

  if (towers.length > 0) {
    if (roles.nextroomer.buildRamparts(creep)) {
      return true;
    }

    for (let towerId in towers) {
      let tower = towers[towerId];
      if (tower.energy === tower.energyCapacity) {
        room.memory.underSiege = false;
        return false;
      } else {
        let returnCode = creep.transfer(tower, RESOURCE_ENERGY);
        if (returnCode === OK) {
          return true;
        }

        //if (returnCode === ERR_FULL) {}
        // Don't know what to do
        creep.say(returnCode);
        return true;
      }
    }
    return roles.nextroomer.buildRamparts(creep);
  } else if (roles.nextroomer.buildRamparts(creep)) {
    return true;
  }

  let linkPosMem = room.memory.position.structure.link[1];

  if (creep.pos.getRangeTo(linkPosMem.x, linkPosMem.y) > 2) {
    linkPosMem = room.memory.position.structure.link[2];
  }
  let linkPos = new RoomPosition(linkPosMem.x, linkPosMem.y, linkPosMem.roomName);
  let returnCode = linkPos.createConstructionSite(STRUCTURE_TOWER);
  if (returnCode === ERR_RCL_NOT_ENOUGH) {
    delete room.memory.underSiege;
  }
  creep.log('Build tower: ' + returnCode);
};

roles.nextroomer.stayAtSource = function(creep, source) {
  if (creep.carry.energy < creep.carryCapacity - 30) {
    let returnCode = creep.harvest(source);
    if (returnCode === OK) {
      if (creep.carry.energy >= 0) {
        var creepWithoutEnergy = creep.pos.findClosestByRange(FIND_MY_CREEPS, {
          filter: function(object) {
            return (object.carry.energy === 0 && object.id !== creep.id);
          }
        });
        let range = creep.pos.getRangeTo(creepWithoutEnergy);

        if (range === 1) {
          creep.transfer(creepWithoutEnergy, RESOURCE_ENERGY);
        }
      }
      return true;
    }
  }
  return roles.nextroomer.defendTower(creep, source);
};

roles.nextroomer.underSiege = function(creep) {
  let room = Game.rooms[creep.room.name];
  if (creep.memory.targetId) {
    let sourcerPosMem = room.memory.position.creep[creep.memory.targetId];
    let source = Game.getObjectById(creep.memory.targetId);
    if (creep.pos.isEqualTo(sourcerPosMem.x, sourcerPosMem.y)) {
      return roles.nextroomer.stayAtSource(creep, source);
    } else {
      delete creep.memory.targetId;
    }
  }
  let sources = room.find(FIND_SOURCES);
  for (var sourceId in sources) {
    let source = sources[sourceId];
    let sourcerPosMem = room.memory.position.creep[source.id];
    let sourcerPos = new RoomPosition(sourcerPosMem.x, sourcerPosMem.y, sourcerPosMem.roomName);

    if (creep.pos.isEqualTo(sourcerPos)) {
      creep.memory.targetId = source.id;
      return roles.nextroomer.stayAtSource(creep, source);
    }

    let creeps = sourcerPos.lookFor('creep');
    if (creeps.length === 0) {
      creep.moveTo(sourcerPos.x, sourcerPos.y);
      return true;
    }
  }
  return false;
};

roles.nextroomer.settle = function(creep) {
  let room = Game.rooms[creep.room.name];
  let hostileCreeps = room.find(FIND_HOSTILE_CREEPS);
  if (hostileCreeps.length) {
    room.memory.underSiege = true;
    if (creep.room.controller.ticksToDowngrade < CONTROLLER_DOWNGRADE[creep.room.controller.level] / 10 || creep.room.controller.level === 1) {
      let methods = [Creep.getEnergy, Creep.upgradeControllerTask];
      return Creep.execute(creep, methods);
    }
  }
  room.memory.wayBlocked = false;
  if (room.memory.underSiege && room.controller && room.controller.level >= 3) {
    creep.log('underSiege: ' + room.memory.attackTimer);
    return roles.nextroomer.underSiege(creep);
  }

  if (creep.carry.energy > 0) {
    var towers = creep.room.find(FIND_STRUCTURES, {
      filter: function(object) {
        return (object.structureType === STRUCTURE_TOWER &&
          object.energy < 10);
      }
    });
    if (towers.length) {
      creep.moveTo(towers[0]);
      creep.transfer(towers[0], RESOURCE_ENERGY);
      return true;
    }
  }

  if (_.sum(creep.carry) === 0) {
    let hostileStructures = creep.room.findPropertyFiltre(FIND_HOSTILE_STRUCTURES, 'structureType',
      [STRUCTURE_RAMPART, STRUCTURE_EXTRACTOR, STRUCTURE_WALL, STRUCTURE_CONTROLLER]);
    if (hostileStructures.length) {
      let structure = _.max(hostileStructures, s => s.structureType === STRUCTURE_STORAGE);

      if (structure.structureType === STRUCTURE_STORAGE) {
        if (structure.store.energy === 0) {
          structure.destroy();
          return true;
        }
      } else if (!structure.energy) {
        structure.destroy();
        return true;
      }
      creep.say('ho: ' + structure.pos, true);
      creep.log(structure.structureType);
      creep.moveTo(structure);
      creep.withdraw(structure, RESOURCE_ENERGY);
      return true;
    }
  }

  if (creep.room.energyCapacityAvailable < 300) {
    let constructionSites = creep.room.findPropertyFiltre(FIND_CONSTRUCTION_SITES, 'structureType', [STRUCTURE_LAB, STRUCTURE_NUKER, STRUCTURE_TERMINAL]);
    for (let cs of constructionSites) {
      cs.remove();
    }
  }

  let methods = [Creep.getEnergy];
  if (creep.room.controller.ticksToDowngrade < 1500) {
    methods.push(Creep.upgradeControllerTask);
  }
  let structures = creep.room.findPropertyFiltre(FIND_MY_CONSTRUCTION_SITES, 'structureType', [STRUCTURE_RAMPART, STRUCTURE_CONTROLLER], true);
  if (creep.room.controller.level >= 3 && structures.length > 0) {
    methods.push(Creep.constructTask);
  }

  if (creep.room.controller.level < 8) {
    methods.push(Creep.upgradeControllerTask);
  }

  methods.push(Creep.transferEnergy);
  return Creep.execute(creep, methods);
};

roles.nextroomer.preMove = function(creep, directions) {
  if (!directions) {
    return false;
  }
  let posForward = creep.pos.getAdjacentPosition(directions.forwardDirection);
  let structures = posForward.lookFor(LOOK_STRUCTURES);
  for (let structure of structures) {
    if (structure.structureType === STRUCTURE_ROAD) {
      continue;
    }
    if (structure.structureType === STRUCTURE_RAMPART && structure.my) {
      continue;
    }

    creep.dismantle(structure);
    creep.say('dismantle');
    break;
  }
};

roles.nextroomer.action = function(creep) {
  // TODO when does this happen?
  if (creep.room.name != creep.memory.routing.targetRoom) {
    delete creep.memory.routing.reached;
    return false;
  }

  // TODO ugly fix cause, target gets deleted
  creep.memory.targetBackup = creep.memory.targetBackup || creep.memory.target;
  if (creep.room.name === creep.memory.targetBackup) {
    return roles.nextroomer.settle(creep);
  }
  return roles.nextroomer.settle(creep);
};

roles.nextroomer.execute = function(creep) {
  creep.log('Execute!!!');
  //creep.moveTo(25, 25);
};
<commit_msg>Fix: crash in roles.nextroomer.died<commit_after>'use strict';

/*
 * nextroomer is used to build up rooms
 *
 * Bring the controller to level 3 after that build constructionSites
 * and continue upgrading.
 *
 * If the room is 'underSiege', build a tower next to a source, build ramparts
 * and fill the tower.
 */

roles.nextroomer = {};

roles.nextroomer.died = function(name, creepMemory) {
  let roomName = creepMemory.routing.route[creepMemory.routing.routePos].room;
  let message = `${name} ${roomName} ${JSON.stringify(creepMemory)}`;
  if (roomName === creepMemory.routing.targetRoom) {
    // TODO make underSiege to a counter
  }
  console.log('DIED:', message);
};

roles.nextroomer.settings = {
  layoutString: 'MWC',
  amount: [6, 3, 3],
};

roles.nextroomer.checkForRampart = function(coords) {
  let pos = new RoomPosition(coords.x, coords.y, coords.roomName);
  let structures = pos.lookFor('structure');
  return _.find(structures, (s) => s.structureType === STRUCTURE_RAMPART);
};

roles.nextroomer.buildRamparts = function(creep) {
  let ramparts = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: {
      structureType: STRUCTURE_RAMPART
    }
  });

  // TODO Guess roles.nextroomer should be higher
  let rampartMinHits = 10000;

  creep.say('checkRamparts');
  let posRampart = roles.nextroomer.checkForRampart(creep.pos);
  if (posRampart) {
    if (posRampart.hits < rampartMinHits) {
      creep.repair(posRampart);
      return true;
    }
  } else {
    creep.room.createConstructionSite(creep.pos.x, creep.pos.y, STRUCTURE_RAMPART);
    return true;
  }

  let room = Game.rooms[creep.room.name];
  let linkPosMem = room.memory.position.structure.link[1];
  if (creep.pos.getRangeTo(linkPosMem.x, linkPosMem.y) > 1) {
    linkPosMem = room.memory.position.structure.link[2];
  }

  let links = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: function(object) {
      return object.structureType === STRUCTURE_LINK;
    }
  });
  if (links.length) {
    creep.say('dismantle');
    creep.log(JSON.stringify(links));
    creep.dismantle(links[0]);
    return true;
  }

  creep.say('cr');
  let towerRampart = roles.nextroomer.checkForRampart(linkPosMem);
  if (towerRampart) {
    creep.say('tr');
    if (towerRampart.hits < rampartMinHits) {
      creep.repair(towerRampart);
      return true;
    }
  } else {
    let returnCode = creep.room.createConstructionSite(linkPosMem.x, linkPosMem.y, STRUCTURE_RAMPART);
    creep.log('Build tower rampart: ' + returnCode);
    return true;
  }
  return false;
};

roles.nextroomer.defendTower = function(creep, source) {
  let room = Game.rooms[creep.room.name];
  let constructionSites = creep.pos.findInRange(FIND_CONSTRUCTION_SITES, 1);
  if (constructionSites.length > 0) {
    for (let constructionSiteId in constructionSites) {
      creep.build(constructionSites[constructionSiteId]);
    }
    return true;
  }

  let towers = creep.pos.findInRange(FIND_STRUCTURES, 1, {
    filter: {
      structureType: STRUCTURE_TOWER
    }
  });

  if (towers.length > 0) {
    if (roles.nextroomer.buildRamparts(creep)) {
      return true;
    }

    for (let towerId in towers) {
      let tower = towers[towerId];
      if (tower.energy === tower.energyCapacity) {
        room.memory.underSiege = false;
        return false;
      } else {
        let returnCode = creep.transfer(tower, RESOURCE_ENERGY);
        if (returnCode === OK) {
          return true;
        }

        //if (returnCode === ERR_FULL) {}
        // Don't know what to do
        creep.say(returnCode);
        return true;
      }
    }
    return roles.nextroomer.buildRamparts(creep);
  } else if (roles.nextroomer.buildRamparts(creep)) {
    return true;
  }

  let linkPosMem = room.memory.position.structure.link[1];

  if (creep.pos.getRangeTo(linkPosMem.x, linkPosMem.y) > 2) {
    linkPosMem = room.memory.position.structure.link[2];
  }
  let linkPos = new RoomPosition(linkPosMem.x, linkPosMem.y, linkPosMem.roomName);
  let returnCode = linkPos.createConstructionSite(STRUCTURE_TOWER);
  if (returnCode === ERR_RCL_NOT_ENOUGH) {
    delete room.memory.underSiege;
  }
  creep.log('Build tower: ' + returnCode);
};

roles.nextroomer.stayAtSource = function(creep, source) {
  if (creep.carry.energy < creep.carryCapacity - 30) {
    let returnCode = creep.harvest(source);
    if (returnCode === OK) {
      if (creep.carry.energy >= 0) {
        var creepWithoutEnergy = creep.pos.findClosestByRange(FIND_MY_CREEPS, {
          filter: function(object) {
            return (object.carry.energy === 0 && object.id !== creep.id);
          }
        });
        let range = creep.pos.getRangeTo(creepWithoutEnergy);

        if (range === 1) {
          creep.transfer(creepWithoutEnergy, RESOURCE_ENERGY);
        }
      }
      return true;
    }
  }
  return roles.nextroomer.defendTower(creep, source);
};

roles.nextroomer.underSiege = function(creep) {
  let room = Game.rooms[creep.room.name];
  if (creep.memory.targetId) {
    let sourcerPosMem = room.memory.position.creep[creep.memory.targetId];
    let source = Game.getObjectById(creep.memory.targetId);
    if (creep.pos.isEqualTo(sourcerPosMem.x, sourcerPosMem.y)) {
      return roles.nextroomer.stayAtSource(creep, source);
    } else {
      delete creep.memory.targetId;
    }
  }
  let sources = room.find(FIND_SOURCES);
  for (var sourceId in sources) {
    let source = sources[sourceId];
    let sourcerPosMem = room.memory.position.creep[source.id];
    let sourcerPos = new RoomPosition(sourcerPosMem.x, sourcerPosMem.y, sourcerPosMem.roomName);

    if (creep.pos.isEqualTo(sourcerPos)) {
      creep.memory.targetId = source.id;
      return roles.nextroomer.stayAtSource(creep, source);
    }

    let creeps = sourcerPos.lookFor('creep');
    if (creeps.length === 0) {
      creep.moveTo(sourcerPos.x, sourcerPos.y);
      return true;
    }
  }
  return false;
};

roles.nextroomer.settle = function(creep) {
  let room = Game.rooms[creep.room.name];
  let hostileCreeps = room.find(FIND_HOSTILE_CREEPS);
  if (hostileCreeps.length) {
    room.memory.underSiege = true;
    if (creep.room.controller.ticksToDowngrade < CONTROLLER_DOWNGRADE[creep.room.controller.level] / 10 || creep.room.controller.level === 1) {
      let methods = [Creep.getEnergy, Creep.upgradeControllerTask];
      return Creep.execute(creep, methods);
    }
  }
  room.memory.wayBlocked = false;
  if (room.memory.underSiege && room.controller && room.controller.level >= 3) {
    creep.log('underSiege: ' + room.memory.attackTimer);
    return roles.nextroomer.underSiege(creep);
  }

  if (creep.carry.energy > 0) {
    var towers = creep.room.find(FIND_STRUCTURES, {
      filter: function(object) {
        return (object.structureType === STRUCTURE_TOWER &&
          object.energy < 10);
      }
    });
    if (towers.length) {
      creep.moveTo(towers[0]);
      creep.transfer(towers[0], RESOURCE_ENERGY);
      return true;
    }
  }

  if (_.sum(creep.carry) === 0) {
    let hostileStructures = creep.room.findPropertyFiltre(FIND_HOSTILE_STRUCTURES, 'structureType',
      [STRUCTURE_RAMPART, STRUCTURE_EXTRACTOR, STRUCTURE_WALL, STRUCTURE_CONTROLLER]);
    if (hostileStructures.length) {
      let structure = _.max(hostileStructures, s => s.structureType === STRUCTURE_STORAGE);

      if (structure.structureType === STRUCTURE_STORAGE) {
        if (structure.store.energy === 0) {
          structure.destroy();
          return true;
        }
      } else if (!structure.energy) {
        structure.destroy();
        return true;
      }
      creep.say('ho: ' + structure.pos, true);
      creep.log(structure.structureType);
      creep.moveTo(structure);
      creep.withdraw(structure, RESOURCE_ENERGY);
      return true;
    }
  }

  if (creep.room.energyCapacityAvailable < 300) {
    let constructionSites = creep.room.findPropertyFiltre(FIND_CONSTRUCTION_SITES, 'structureType', [STRUCTURE_LAB, STRUCTURE_NUKER, STRUCTURE_TERMINAL]);
    for (let cs of constructionSites) {
      cs.remove();
    }
  }

  let methods = [Creep.getEnergy];
  if (creep.room.controller.ticksToDowngrade < 1500) {
    methods.push(Creep.upgradeControllerTask);
  }
  let structures = creep.room.findPropertyFiltre(FIND_MY_CONSTRUCTION_SITES, 'structureType', [STRUCTURE_RAMPART, STRUCTURE_CONTROLLER], true);
  if (creep.room.controller.level >= 3 && structures.length > 0) {
    methods.push(Creep.constructTask);
  }

  if (creep.room.controller.level < 8) {
    methods.push(Creep.upgradeControllerTask);
  }

  methods.push(Creep.transferEnergy);
  return Creep.execute(creep, methods);
};

roles.nextroomer.preMove = function(creep, directions) {
  if (!directions) {
    return false;
  }
  let posForward = creep.pos.getAdjacentPosition(directions.forwardDirection);
  let structures = posForward.lookFor(LOOK_STRUCTURES);
  for (let structure of structures) {
    if (structure.structureType === STRUCTURE_ROAD) {
      continue;
    }
    if (structure.structureType === STRUCTURE_RAMPART && structure.my) {
      continue;
    }

    creep.dismantle(structure);
    creep.say('dismantle');
    break;
  }
};

roles.nextroomer.action = function(creep) {
  // TODO when does this happen?
  if (creep.room.name != creep.memory.routing.targetRoom) {
    delete creep.memory.routing.reached;
    return false;
  }

  // TODO ugly fix cause, target gets deleted
  creep.memory.targetBackup = creep.memory.targetBackup || creep.memory.target;
  if (creep.room.name === creep.memory.targetBackup) {
    return roles.nextroomer.settle(creep);
  }
  return roles.nextroomer.settle(creep);
};

roles.nextroomer.execute = function(creep) {
  creep.log('Execute!!!');
  //creep.moveTo(25, 25);
};
<|endoftext|>