<commit_before>import PickupListModule from "./pickupList";
import UserModule from "../../common/user/user";
import StoreModule from "../../common/store/store";
import AuthenticationModule from "../../common/authentication/authentication";
import PickupDateModule from "../../common/pickupDate/pickupDate";

describe("PickupList", () => {
  let $rootScope, $componentController, $httpBackend;

  let { module } = angular.mock;

  beforeEach(module(PickupListModule));
  beforeEach(module(UserModule));
  beforeEach(module(StoreModule));
  beforeEach(module(AuthenticationModule));
  beforeEach(module(PickupDateModule));

  beforeEach(inject(($injector) => {
    $httpBackend = $injector.get("$httpBackend");
    $rootScope = $injector.get("$rootScope");
    $componentController = $injector.get("$componentController");
  }));

  afterEach(() => {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  let authData = {
    "id": 1,
    "display_name": "Lars",
    "first_name": "Lars",
    "last_name": "Wolf",
    "email": "l@l.de",
    "address": null,
    "latitude": null,
    "longitude": null
  };

  let pickupData = [{
    "id": 15,
    "date": "2016-09-16T21:40:00Z",
    "collector_ids": [],
    "max_collectors": 2,
    "store": 9
  },
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9
    },
    {
      "id": 11,
      "date": "2016-09-17T16:00:00Z",
      "collector_ids": [
        1
      ],
      "max_collectors": 3,
      "store": 9
    },
    {
      "id": 5,
      "date": "2016-09-18T12:00:18Z",
      "collector_ids": [],
      "max_collectors": 5,
      "store": 9
    },
    {
      "id": 4,
      "date": "2017-09-22T20:00:05Z",
      "collector_ids": [],
      "max_collectors": 2,
      "store": 9
    }];

  let pickupDataInfoAdded = [{
    "id": 15,
    "date": "2016-09-16T21:40:00Z",
    "collector_ids": [],
    "max_collectors": 2,
    "store": 9,
    "isUserMember": false,
    "isFull": false
  },
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": true,
      "isFull": true
    },
    {
      "id": 11,
      "date": "2016-09-17T16:00:00Z",
      "collector_ids": [
        1
      ],
      "max_collectors": 3,
      "store": 9,
      "isUserMember": true,
      "isFull": false
    },
    {
      "id": 5,
      "date": "2016-09-18T12:00:18Z",
      "collector_ids": [],
      "max_collectors": 5,
      "store": 9,
      "isUserMember": false,
      "isFull": false
    },
    {
      "id": 4,
      "date": "2017-09-22T20:00:05Z",
      "collector_ids": [],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": false,
      "isFull": false
    }];

  let pickupDataInfoAddedGrouped = [
    {
      "date": "2016-09-16",
      "items": [{
        "id": 15,
        "date": "2016-09-16T21:40:00Z",
        "collector_ids": [],
        "max_collectors": 2,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      },
        {
          "id": 14,
          "date": "2016-09-16T01:00:00Z",
          "collector_ids": [
            1,
            8
          ],
          "max_collectors": 2,
          "store": 9,
          "isUserMember": true,
          "isFull": true
        }]
    },
    {
      "date": "2016-09-17",
      "items": [{
        "id": 11,
        "date": "2016-09-17T16:00:00Z",
        "collector_ids": [
          1
        ],
        "max_collectors": 3,
        "store": 9,
        "isUserMember": true,
        "isFull": false
      }]
    },
    {
      "date": "2016-09-18",
      "items": [{
        "id": 5,
        "date": "2016-09-18T12:00:18Z",
        "collector_ids": [],
        "max_collectors": 5,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      }]
    },
    {
      "date": "2017-09-22",
      "items": [{
        "id": 4,
        "date": "2017-09-22T20:00:05Z",
        "collector_ids": [],
        "max_collectors": 2,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      }]
    }];

  let fullPickups = [
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": true,
      "isFull": true
    }
  ];

  let storeData = {
    "id": 9,
    "name": "REWE Neuried",
    "description": "dasdsd",
    "group": 4,
    "address": "Muenchen",
    "latitude": 51.6180165487737,
    "longitude": 2.8125
  };

  describe("Controller with showDetail = date (default)", () => {
    let controller;

    beforeEach(() => {
      controller = $componentController("pickupList", {
        $scope: $rootScope.$new()
      }, {
        storeId: 9,
        header: "My amazing Pickups"
      });

      $httpBackend.whenGET("/api/auth/status/").respond(authData);
      $httpBackend.whenGET("/api/pickup-dates/?store=9").respond(pickupData);
    });

    afterEach(() => {
      $httpBackend.flush();
    });

    it("bindings", () => {
      expect(controller.storeId).to.equal(9);
      expect(controller.header).to.equal("My amazing Pickups");
    });

    it("automatic update", () => {
      $httpBackend.expectGET("/api/auth/status/").respond(authData);
      $httpBackend.expectGET("/api/pickup-dates/?store=9").respond(pickupData);
    });

    it("addPickupInfo functionality", () => {
      controller.userId = 1;
      controller.addPickuplistInfos(pickupData);
      let updatedData = controller.allPickups;
      expect(updatedData).to.deep.equal(pickupDataInfoAdded);
      expect(updatedData[0].store).to.deep.equal(9);
    });

    it("filter functionality", () => {
      controller.allPickups = pickupDataInfoAdded;
      controller.pickupList = {
        showJoined: false,
        showOpen: false,
        showFull: true
      };
      expect(controller.filterPickups()).to.deep.equal(fullPickups);
    });

    it("groupByDate functionality", () => {
      expect(controller.groupByDate(pickupDataInfoAdded)).to.deep.equal(pickupDataInfoAddedGrouped);
    });
  });

  describe("Controller with showDetail = store", () => {
    let controller;

    beforeEach(() => {
      controller = $componentController("pickupList", {
        $scope: $rootScope.$new()
      }, {
        storeId: 9,
        header: "My amazing Pickups",
        showDetail: "store"
      });

      $httpBackend.whenGET("/api/auth/status/").respond(authData);
      $httpBackend.whenGET("/api/pickup-dates/?store=9").respond(pickupData);
      $httpBackend.whenGET("/api/stores/9/").respond(storeData);
    });

    afterEach(() => {
      $httpBackend.flush();
    });

    it("addPickupInfo get Store Info functionality", () => {
      controller.userId = 1;
      controller.addPickuplistInfos(pickupData);
      let updatedData = controller.allPickups;
      expect(updatedData[0].store).to.eventually.deep.equal(storeData);
    });
  });
});
<commit_msg>fix broken test<commit_after>import PickupListModule from "./pickupList";
import UserModule from "../../common/user/user";
import StoreModule from "../../common/store/store";
import AuthenticationModule from "../../common/authentication/authentication";
import PickupDateModule from "../../common/pickupDate/pickupDate";

describe("PickupList", () => {
  let $rootScope, $componentController, $httpBackend;

  let { module } = angular.mock;

  beforeEach(module(PickupListModule));
  beforeEach(module(UserModule));
  beforeEach(module(StoreModule));
  beforeEach(module(AuthenticationModule));
  beforeEach(module(PickupDateModule));

  beforeEach(inject(($injector) => {
    $httpBackend = $injector.get("$httpBackend");
    $rootScope = $injector.get("$rootScope");
    $componentController = $injector.get("$componentController");
  }));

  afterEach(() => {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  let authData = {
    "id": 1,
    "display_name": "Lars",
    "first_name": "Lars",
    "last_name": "Wolf",
    "email": "l@l.de",
    "address": null,
    "latitude": null,
    "longitude": null
  };

  let pickupData = [{
    "id": 15,
    "date": "2016-09-16T21:40:00Z",
    "collector_ids": [],
    "max_collectors": 2,
    "store": 9
  },
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9
    },
    {
      "id": 11,
      "date": "2016-09-17T16:00:00Z",
      "collector_ids": [
        1
      ],
      "max_collectors": 3,
      "store": 9
    },
    {
      "id": 5,
      "date": "2016-09-18T12:00:18Z",
      "collector_ids": [],
      "max_collectors": 5,
      "store": 9
    },
    {
      "id": 4,
      "date": "2017-09-22T20:00:05Z",
      "collector_ids": [],
      "max_collectors": 2,
      "store": 9
    }];

  let pickupDataInfoAdded = [{
    "id": 15,
    "date": "2016-09-16T21:40:00Z",
    "collector_ids": [],
    "max_collectors": 2,
    "store": 9,
    "isUserMember": false,
    "isFull": false
  },
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": true,
      "isFull": true
    },
    {
      "id": 11,
      "date": "2016-09-17T16:00:00Z",
      "collector_ids": [
        1
      ],
      "max_collectors": 3,
      "store": 9,
      "isUserMember": true,
      "isFull": false
    },
    {
      "id": 5,
      "date": "2016-09-18T12:00:18Z",
      "collector_ids": [],
      "max_collectors": 5,
      "store": 9,
      "isUserMember": false,
      "isFull": false
    },
    {
      "id": 4,
      "date": "2017-09-22T20:00:05Z",
      "collector_ids": [],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": false,
      "isFull": false
    }];

  let pickupDataInfoAddedGrouped = [
    {
      "date": "2016-09-16",
      "items": [{
        "id": 15,
        "date": "2016-09-16T21:40:00Z",
        "collector_ids": [],
        "max_collectors": 2,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      },
        {
          "id": 14,
          "date": "2016-09-16T01:00:00Z",
          "collector_ids": [
            1,
            8
          ],
          "max_collectors": 2,
          "store": 9,
          "isUserMember": true,
          "isFull": true
        }]
    },
    {
      "date": "2016-09-17",
      "items": [{
        "id": 11,
        "date": "2016-09-17T16:00:00Z",
        "collector_ids": [
          1
        ],
        "max_collectors": 3,
        "store": 9,
        "isUserMember": true,
        "isFull": false
      }]
    },
    {
      "date": "2016-09-18",
      "items": [{
        "id": 5,
        "date": "2016-09-18T12:00:18Z",
        "collector_ids": [],
        "max_collectors": 5,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      }]
    },
    {
      "date": "2017-09-22",
      "items": [{
        "id": 4,
        "date": "2017-09-22T20:00:05Z",
        "collector_ids": [],
        "max_collectors": 2,
        "store": 9,
        "isUserMember": false,
        "isFull": false
      }]
    }];

  let fullPickups = [
    {
      "id": 14,
      "date": "2016-09-16T01:00:00Z",
      "collector_ids": [
        1,
        8
      ],
      "max_collectors": 2,
      "store": 9,
      "isUserMember": true,
      "isFull": true
    }
  ];

  let storeData = {
    "id": 9,
    "name": "REWE Neuried",
    "description": "dasdsd",
    "group": 4,
    "address": "Muenchen",
    "latitude": 51.6180165487737,
    "longitude": 2.8125
  };

  describe("Controller with showDetail = date (default)", () => {
    let controller;

    beforeEach(() => {
      controller = $componentController("pickupList", {
        $scope: $rootScope.$new()
      }, {
        storeId: 9,
        header: "My amazing Pickups"
      });

      $httpBackend.whenGET("/api/auth/status/").respond(authData);
      $httpBackend.whenGET("/api/pickup-dates/?store=9").respond(pickupData);
    });

    afterEach(() => {
      $httpBackend.flush();
    });

    it("bindings", () => {
      expect(controller.storeId).to.equal(9);
      expect(controller.header).to.equal("My amazing Pickups");
    });

    it("automatic update", () => {
      $httpBackend.expectGET("/api/auth/status/").respond(authData);
      $httpBackend.expectGET("/api/pickup-dates/?store=9").respond(pickupData);
    });

    it("addPickupInfo functionality", () => {
      controller.userId = 1;
      controller.addPickuplistInfos(pickupData);
      let updatedData = controller.allPickups;
      expect(updatedData).to.deep.equal(pickupDataInfoAdded);
      expect(updatedData[0].store).to.deep.equal(9);
    });

    it("filter functionality", () => {
      controller.allPickups = pickupDataInfoAdded;
      controller.pickupList = {
        showJoined: false,
        showOpen: false,
        showFull: true
      };
      expect(controller.filterPickups()).to.deep.equal(fullPickups);
    });

    it("groupByDate functionality", () => {
      expect(controller.groupByDate(pickupDataInfoAdded)).to.deep.equal(pickupDataInfoAddedGrouped);
    });
  });

  describe("Controller with showDetail = store", () => {
    let controller;

    beforeEach(() => {
      controller = $componentController("pickupList", {
        $scope: $rootScope.$new()
      }, {
        storeId: 9,
        header: "My amazing Pickups",
        showDetail: "store"
      });

      $httpBackend.whenGET("/api/auth/status/").respond(authData);
      $httpBackend.whenGET("/api/pickup-dates/?store=9").respond(pickupData);
      $httpBackend.whenGET("/api/stores/9/").respond(storeData);
      $httpBackend.flush();
    });

    afterEach(() => {
      $httpBackend.flush();
    });

    it("addPickupInfo get Store Info functionality", () => {
      controller.userId = 1;
      controller.addPickuplistInfos(pickupData);
      let updatedData = controller.allPickups;
      expect(updatedData[0].store).to.eventually.deep.equal(storeData);
    });
  });
});
<|endoftext|>


<commit_before>/* String utils */
import React from 'react';
import { FormattedNumber } from 'react-intl';

import config from 'constants/config';

export function makeHandle(owner, pkg) {
  return config.team ? `${config.team.id}:${owner}/${pkg}` : `${owner}/${pkg}`;
}

export function makeMatcher(exp, flags = 'i') {
  const re = new RegExp(exp, flags);
  return (s) => re.test(s);
}

export function printObject(obj) {
  return JSON.stringify(obj, null, '  ');
}

export function readableBytes(bytes) {
  if (Number.isInteger(bytes)) {
    // https://en.wikipedia.org/wiki/Kilobyte
    const sizes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
    const log = bytes === 0 ? 0 : Math.log10(bytes);
    const index = Math.min(Math.floor(log / 3), sizes.length - 1);
    const display = (bytes / (10 ** (index * 3))).toFixed(1);
    return (

        <FormattedNumber value={display} /> {sizes[index]}B

    );
  }
  return '?';
}
<commit_msg>utils/string: readableQuantity (#587)<commit_after>/* String utils */
import React from 'react';
import { FormattedNumber } from 'react-intl';

import config from 'constants/config';

export function makeHandle(owner, pkg) {
  return config.team ? `${config.team.id}:${owner}/${pkg}` : `${owner}/${pkg}`;
}

export function makeMatcher(exp, flags = 'i') {
  const re = new RegExp(exp, flags);
  return (s) => re.test(s);
}

export function printObject(obj) {
  return JSON.stringify(obj, null, '  ');
}

const suffixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];

const splitNumber = (n) => {
  const exp = n === 0 ? 0 : Math.log10(n);
  const index = Math.min(Math.floor(exp / 3), suffixes.length - 1);
  const coeff = (n / (10 ** (index * 3))).toFixed(1);
  return [coeff, suffixes[index]];
};

export function readableBytes(bytes) {
  if (!Number.isInteger(bytes)) return '?';
  // https://en.wikipedia.org/wiki/Kilobyte
  const [coeff, suffix] = splitNumber(bytes);
  return <FormattedNumber value={coeff} /> {suffix}B;
}

export function readableQuantity(q) {
  if (!Number.isInteger(q)) return '?';
  const [coeff, suffix] = splitNumber(q);
  return <FormattedNumber value={coeff} />{suffix};
}
<|endoftext|>


<commit_before>require ([
    'event_utils'
], function (
    eventUtils
) {
    eventUtils.onReady( function() {
        var l = ['e', 'd.l', 'ebi', 'b-en', 'eff', 'o', 'gar', 'tie', 'Bniem'];
        l.splice(6, 0, '@');
        var r = l.join("");
        var e = r.split("").reverse().join("");

        var beitragEmail = document.getElementById('ofbi-beitrag-email');
        if (beitragEmail) {
            beitragEmail.innerHTML =
                ''
              + e
              + '';
        }
    });
});

<commit_msg>Add another email obfuscation helper.<commit_after>require ([
    'event_utils'
], function (
    eventUtils
) {
    eventUtils.onReady( function() {
        var l = ['e', 'd.l', 'ebi', 'b-en', 'eff', 'o', 'gar', 'tie', 'Bniem'];
        l.splice(6, 0, '@');
        var r = l.join("");
        var e = r.split("").reverse().join("");

        var beitragEmail = document.getElementById('ofbi-beitrag-email');
        if (beitragEmail) {
            beitragEmail.innerHTML =
                ''
              + e
              + '';
        }

        l = ['e', 'd.l', 'ebi', 'b-en', 'eff', 'o', 'mae', 'tk', 'inhcet'];
        l.splice(6, 0, '@');
        r = l.join("");
        e = r.split("").reverse().join("");

        var technikEmail = document.getElementById('ofbi-technik-email');
        if (technikEmail) {
            technikEmail.innerHTML =
                ''
              + e
              + '';
        }
    });
});

<|endoftext|>


<commit_before>const messages = {
    after: (field, [target]) => `${field} muss nach ${target} liegen.`,
    alpha_dash: (field) => `${field} darf alphanumerische Zeichen sowie Striche und Unterstriche enthalten.`,
    alpha_num: (field) => `${field} darf nur alphanumerische Zeichen enthalten.`,
    alpha: (field) => `${field} darf nur alphabetische Zeichen enthalten.`,
    before: (field, [target]) => `${field} muss vor ${target} liegen.`,
    between: (field, [min, max]) => `${field} muss zwischen ${min} und ${max} liegen.`,
    confirmed: (field, [confirmedField]) => `${field} passt nicht zum Inhalt von ${confirmedField}.`,
    date_between: (field, [min, max]) => `${field} muss zwischen ${min} und ${max} liegen.`,
    date_format: (field, [format]) => `${field} muss das Format ${format} haben.`,
    decimal: (field, [decimals] = ['*']) => `${field} muss numerisch sein und darf ${decimals === '*' ? '' : decimals} Dezimalpunkte enthalten.`,
    digits: (field, [length]) => `${field} muss numerisch sein und exakt ${length} Ziffern enthalten.`,
    dimensions: (field, [width, height]) => `${field} muss ${width} x ${height} Bildpunkte groß sein.`,
    email: (field) => `${field} muss eine gültige E-Mail-Adresse sein.`,
    ext: (field) => `${field} muss eine gültige Datei sein.`,
    image: (field) => `${field} muss eine Grafik sein.`,
    in: (field) => `${field} muss ein gültiger Wert sein.`,
    ip: (field) => `${field} muss eine gültige IP-Adresse sein.`,
    max: (field, [length]) => `${field} darf nicht länger als ${length} Zeichen sein.`,
    mimes: (field) => `${field} muss einen gültigen Dateityp haben.`,
    min: (field, [length]) => `${field} muss mindestens ${length} Zeichen lang sein.`,
    not_in: (field) => `${field} muss ein gültiger Wert sein.`,
    numeric: (field) => `${field} darf nur numerische Zeichen enthalten.`,
    regex: (field) => `Das Format von ${field} ist ungültig.`,
    required: (field) => `${field} ist ein Pflichtfeld.`,
    size: (field, [size]) => `${field} muss kleiner als ${size} KB sein.`,
    url: (field) => `${field} ist keine gültige URL.`,
};

const locale = {
    name: 'de',
    messages,
    attributes: {}
};

if (typeof VeeValidate !== 'undefined' && VeeValidate && typeof VeeValidate.Validator) {
    VeeValidate.Validator.addLocale(locale);
}

export default locale;
<commit_msg>added missing _default in de.js<commit_after>const messages = {
    _default: (field) => `${field} ist ungültig.`,
    after: (field, [target]) => `${field} muss nach ${target} liegen.`,
    alpha_dash: (field) => `${field} darf alphanumerische Zeichen sowie Striche und Unterstriche enthalten.`,
    alpha_num: (field) => `${field} darf nur alphanumerische Zeichen enthalten.`,
    alpha: (field) => `${field} darf nur alphabetische Zeichen enthalten.`,
    before: (field, [target]) => `${field} muss vor ${target} liegen.`,
    between: (field, [min, max]) => `${field} muss zwischen ${min} und ${max} liegen.`,
    confirmed: (field, [confirmedField]) => `${field} passt nicht zum Inhalt von ${confirmedField}.`,
    date_between: (field, [min, max]) => `${field} muss zwischen ${min} und ${max} liegen.`,
    date_format: (field, [format]) => `${field} muss das Format ${format} haben.`,
    decimal: (field, [decimals] = ['*']) => `${field} muss numerisch sein und darf ${decimals === '*' ? '' : decimals} Dezimalpunkte enthalten.`,
    digits: (field, [length]) => `${field} muss numerisch sein und exakt ${length} Ziffern enthalten.`,
    dimensions: (field, [width, height]) => `${field} muss ${width} x ${height} Bildpunkte groß sein.`,
    email: (field) => `${field} muss eine gültige E-Mail-Adresse sein.`,
    ext: (field) => `${field} muss eine gültige Datei sein.`,
    image: (field) => `${field} muss eine Grafik sein.`,
    in: (field) => `${field} muss ein gültiger Wert sein.`,
    ip: (field) => `${field} muss eine gültige IP-Adresse sein.`,
    max: (field, [length]) => `${field} darf nicht länger als ${length} Zeichen sein.`,
    mimes: (field) => `${field} muss einen gültigen Dateityp haben.`,
    min: (field, [length]) => `${field} muss mindestens ${length} Zeichen lang sein.`,
    not_in: (field) => `${field} muss ein gültiger Wert sein.`,
    numeric: (field) => `${field} darf nur numerische Zeichen enthalten.`,
    regex: (field) => `Das Format von ${field} ist ungültig.`,
    required: (field) => `${field} ist ein Pflichtfeld.`,
    size: (field, [size]) => `${field} muss kleiner als ${size} KB sein.`,
    url: (field) => `${field} ist keine gültige URL.`,
};

const locale = {
    name: 'de',
    messages,
    attributes: {}
};

if (typeof VeeValidate !== 'undefined' && VeeValidate && typeof VeeValidate.Validator) {
    VeeValidate.Validator.addLocale(locale);
}

export default locale;
<|endoftext|>


<commit_before>var fs=require("fs");
module.exports=function(opt){
    opt=opt||{};
    var error=opt.error||console.error;
    var debug=opt.debug||false;
    var path=opt.path||'./';
    var pattern=/<\?fs [\s\S]*? fs\?>/g;

    /*
        this plugin assumes that another plugin has loaded a template
        and assigned its value to res.body

        if that's not the case, then it falls through to the next plugin
        if that is the case, it looks for sections that look like
            <?fs path/to/a/file path/to/any/number/of/fallback/files fs?>
        if a file fails, it falls through to the next

        once all files in the template have been loaded, such tags are replaced
        with their intended contents

        the plugin then falls through to the next middleware
    */

    return function(req,res,next){
        if(res.body && pattern.test(res.body)){
            var total=0,
                count=0,
                files={},
                results={},
                done=function(){
                    --count; // can make this a one-liner
                    if(count == 0){
                        // swap things back in!
                        res.body=res.body.replace(/\{file\d+?\}/g,function(id){
                            return results[id];
                        });
                        next();
                    }
                };

                // parse out the files you should grab
                // replace them with {file?}
                res.body=res.body.replace(pattern,function(block){
                    //console.log("Replacing %s",block);
                    var id='{file'+(total++)+'}';
                    var targets=block.slice(4,-4)
                        .split(/\s+/)
                        .map(function(x){return x.trim();})
                        .filter(function(x){return x;});
                    files[id]=targets;
                    return id;
                });

                count=total;

                for(var file in files){
                    //console.log(file);
                    (function(){
                        var id=file,
                            howMany=files[file].length,
                            current=0,
                            again=function(){
                                var lookingFor=path+files[id][current];
                                fs.readFile(lookingFor,'utf-8',function(e,out){
                                    if(e){
                                        error(e);
                                        if(files[id][++current]){
                                            // there are fallback to try
                                            again();
                                        }else if(debug){
                                            // set the return value to the error message
                                            results[id]=e;
                                        }else{
                                            // return nothing
                                            results[id]='';
                                            done();
                                        }
                                    }else if(out){
                                        results[id]=out;
                                        done();
                                    }else{
                                        done();
                                    }
                                });
                            };
                        again();
                    }());
                }
        }else{
            next();
        }
    };
};
<commit_msg>fix fragile regex<commit_after>var fs=require("fs");
module.exports=function(opt){
    opt=opt||{};
    var error=opt.error||console.error;
    var debug=opt.debug||false;
    var path=opt.path||'./';
    var pattern=/<\?fs[\s\S]*?fs\?>/g;

    /*
        this plugin assumes that another plugin has loaded a template
        and assigned its value to res.body

        if that's not the case, then it falls through to the next plugin
        if that is the case, it looks for sections that look like
            <?fs path/to/a/file path/to/any/number/of/fallback/files fs?>
        if a file fails, it falls through to the next

        once all files in the template have been loaded, such tags are replaced
        with their intended contents

        the plugin then falls through to the next middleware
    */

    return function(req,res,next){
        if(res.body && pattern.test(res.body)){
            var total=0,
                count=0,
                files={},
                results={},
                done=function(){
                    --count; // can make this a one-liner
                    if(count == 0){
                        // swap things back in!
                        res.body=res.body.replace(/\{file\d+?\}/g,function(id){
                            return results[id];
                        });
                        next();
                    }
                };

                // parse out the files you should grab
                // replace them with {file?}
                res.body=res.body.replace(pattern,function(block){
                    //console.log("Replacing %s",block);
                    var id='{file'+(total++)+'}';
                    var targets=block.slice(4,-4)
                        .split(/\s+/)
                        .map(function(x){return x.trim();})
                        .filter(function(x){return x;});
                    files[id]=targets;
                    return id;
                });

                count=total;

                for(var file in files){
                    //console.log(file);
                    (function(){
                        var id=file,
                            howMany=files[file].length,
                            current=0,
                            again=function(){
                                var lookingFor=path+files[id][current];
                                fs.readFile(lookingFor,'utf-8',function(e,out){
                                    if(e){
                                        error(e);
                                        if(files[id][++current]){
                                            // there are fallback to try
                                            again();
                                        }else if(debug){
                                            // set the return value to the error message
                                            results[id]=e;
                                        }else{
                                            // return nothing
                                            results[id]='';
                                            done();
                                        }
                                    }else if(out){
                                        results[id]=out;
                                        done();
                                    }else{
                                        done();
                                    }
                                });
                            };
                        again();
                    }());
                }
        }else{
            next();
        }
    };
};
<|endoftext|>


<commit_before>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: matrix_group_mgr.js
 */

var the_matrix_group_mgr_object = null;

module.exports = {
    malloc: function (root_object_val) {
        the_matrix_group_mgr_object = new MatrixGroupMgrClass(root_object_val);
        return the_matrix_group_mgr_object;
    },

    malloc_group: function (data_val, session_val) {
        return the_matrix_group_mgr_object.mallocGroup(data_val, session_val);
    },

    receive_data: function (group_object_val, data_val) {
        the_matrix_group_mgr_object.receiveData(group_object_val, data_val);
    },
};

function MatrixGroupMgrClass(root_object_val) {
    "use strict";

    this.init__ = function (root_object_val) {
        this.theRootObject = root_object_val;
        this.theGlobalGroupId = 100;
        this.debug(true, "init__", "");
    };

    this.objectName = function () {
        return "MatrixGroupMgrClass";
    };

    this.rootObject = function () {
        return this.theRootObject;
    };

    this.clusterBaseObject = function () {
        return this.rootObject().clusterBaseObject();
    };

    this.utilObject = function () {
        return this.rootObject().utilObject();
    };

    this.globalGroupId = function () {
        return this.theGlobalGroupId;
    };

    this.incrementGlobalGroupId = function () {
        this.theGlobalGroupId += 1;
    };

    this.mallocGroup = function (data_val, cluster_val) {
        var group = this.rootObject().importObject().importGroup().malloc(this.rootObject(), data_val, cluster_val);
        //this.groupListObject().insertEntry(group);
        this.incrementGlobalGroupId();
        return group;
    };

    this.receiveData = function (group_object_val, data_val) {
        group_object_val.receiveData(data_val);
    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, str2_val);
        }
    };

    this.logit = function (str1_val, str2_val) {
        this.rootObject().LOG_IT(this.objectName() + "." + str1_val, str2_val);
    };

    this.abend = function (str1_val, str2_val) {
        this.rootObject().ABEND(this.objectName() + "." + str1_val, str2_val);
    };

    this.init__(root_object_val);
}

<commit_msg>cluster<commit_after>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: matrix_group_mgr.js
 */

var the_matrix_group_mgr_object = null;

module.exports = {
    malloc: function (root_object_val) {
        the_matrix_group_mgr_object = new MatrixGroupMgrClass(root_object_val);
        return the_matrix_group_mgr_object;
    },

    malloc_group: function (data_val, session_val) {
        return the_matrix_group_mgr_object.mallocGroup(data_val, session_val);
    },

    receive_data: function (group_object_val, data_val) {
        the_matrix_group_mgr_object.receiveData(group_object_val, data_val);
    },
};

function MatrixGroupMgrClass(root_object_val) {
    "use strict";

    this.init__ = function (root_object_val) {
        this.theRootObject = root_object_val;
        this.theGroupListObject = this.importObject().importListMgr().malloc_mgr(this, 0);
        this.theGlobalGroupId = 100;
        this.debug(true, "init__", "");
    };

    this.objectName = function () {
        return "MatrixGroupMgrClass";
    };

    this.rootObject = function () {
        return this.theRootObject;
    };

    this.groupListObject = function () {
        return this.theGroupListObject;
    };

    this.importObject = function () {
        return this.rootObject().importObject();
    };

    this.utilObject = function () {
        return this.rootObject().utilObject();
    };

    this.globalGroupId = function () {
        return this.theGlobalGroupId;
    };

    this.incrementGlobalGroupId = function () {
        this.theGlobalGroupId += 1;
    };

    this.mallocGroup = function (data_val, cluster_val) {
        var group = this.rootObject().importObject().importGroup().malloc(this.rootObject(), data_val, cluster_val);
        //this.groupListObject().insertEntry(group);
        this.incrementGlobalGroupId();
        return group;
    };

    this.receiveData = function (group_object_val, data_val) {
        group_object_val.receiveData(data_val);
    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, str2_val);
        }
    };

    this.logit = function (str1_val, str2_val) {
        this.rootObject().LOG_IT(this.objectName() + "." + str1_val, str2_val);
    };

    this.abend = function (str1_val, str2_val) {
        this.rootObject().ABEND(this.objectName() + "." + str1_val, str2_val);
    };

    this.init__(root_object_val);
}

<|endoftext|>


<commit_before>import { formatFileSize, isDefinedGlobally } from './utils';

const messages = {
  after: (field, [target]) => `Câmpul ${field} trebuie să fie după ${target}.`,
  alpha_dash: (field) => `Câmpul ${field} poate conține caracter alfanumerice, cât și caracterele "-" sau "_".`,
  alpha_num: (field) => `Câmpul ${field} poate conține doar caracter alfanumerice.`,
  alpha_spaces: (field) => `Câmpul ${field} poate conține literele alfabetului cât și spații.`,
  alpha: (field) => `Câmpul ${field} poate conține doar literele alfabetului.`,
  before: (field, [target]) => `Câmpul ${field} trebuie să fie după ${target}.`,
  between: (field, [min, max]) => `Câmpul ${field} trebuie să fie între ${min} și ${max}.`,
  confirmed: (field) => `Câmpul ${field} nu coincide.`,
  credit_card: (field) => `Câmpul ${field} este invalid.`,
  date_between: (field, [min, max]) => `Câmpul ${field} trebuie să fie între ${min} și ${max}.`,
  date_format: (field, [format]) => `Câmpul ${field} trebuie să fie în următorul format ${format}.`,
  decimal: (field, [decimals = '*'] = []) => `Câmpul ${field} trebuie să fie numberic și poate conține ${decimals === '*' ? '' : decimale} zecimale.`,
  digits: (field, [length]) => `Câmpul ${field} trebuie să fie numeric și să conțină exact ${length} caractere.`,
  dimensions: (field, [width, height]) => `Câmpul ${field} trebuie să fie ${width} pixeli lungime și ${height} pixeli înălțime.`,
  email: (field) => `Câmpul ${field} trebuie să conțină un email valid.`,
  ext: (field) => `Câmpul ${field} trebuie să fie un nume de fișier valid.`,
  image: (field) => `Câmpul ${field} trebuie să fie o imagine.`,
  included: (field) => `Câmpul ${field} trebuie să conțină o valoare validă.`,
  ip: (field) => `Câmpul ${field} trebuie să conțină o adresa IP vaidă.`,
  max: (field, [length]) => `Câmpul ${field} nu poate fi mai mare de ${length} caractere.`,
  max_value: (field, [max]) => `Câmpul ${field} trebuie să fie maxim ${max}.`,
  mimes: (field) => `Câmpul ${field} trebuie să conțină un fișier cu extensie validă.`,
  min: (field, [length]) => `Câmpul ${field} trebuie să fie cel puțin ${length} caractere.`,
  min_value: (field, [min]) => `Câmpul ${field}trebuie să fie cel puțin ${min}.`,
  excluded: (field) => `Câmpul ${field} trebuie să conțină o valoare validă.`,
  numeric: (field) => `Câmpul ${field} poate conține doar valori numerice.`,
  regex: (field) => `Formatul câmpului ${field} este invalid.`,
  required: (field) => `Câmpul ${field} este necesar.`,
  size: (field, [size]) => `Câmpul ${field} nu trebuie să depășească ${formatFileSize(size)}.`,
  url: (field) => `Câmpul ${field} nu este un URL valid.`
};

const locale = {
  name: 'ro',
  messages,
  attributes: {}
};

if (isDefinedGlobally()) {
  VeeValidate.Validator.localize({ [locale.name]: locale });
}

export default locale;
<commit_msg>Fixed 'decimale' is not defined<commit_after>import { formatFileSize, isDefinedGlobally } from './utils';

const messages = {
  after: (field, [target]) => `Câmpul ${field} trebuie să fie după ${target}.`,
  alpha_dash: (field) => `Câmpul ${field} poate conține caracter alfanumerice, cât și caracterele "-" sau "_".`,
  alpha_num: (field) => `Câmpul ${field} poate conține doar caracter alfanumerice.`,
  alpha_spaces: (field) => `Câmpul ${field} poate conține literele alfabetului cât și spații.`,
  alpha: (field) => `Câmpul ${field} poate conține doar literele alfabetului.`,
  before: (field, [target]) => `Câmpul ${field} trebuie să fie după ${target}.`,
  between: (field, [min, max]) => `Câmpul ${field} trebuie să fie între ${min} și ${max}.`,
  confirmed: (field) => `Câmpul ${field} nu coincide.`,
  credit_card: (field) => `Câmpul ${field} este invalid.`,
  date_between: (field, [min, max]) => `Câmpul ${field} trebuie să fie între ${min} și ${max}.`,
  date_format: (field, [format]) => `Câmpul ${field} trebuie să fie în următorul format ${format}.`,
  decimal: (field, [decimals = '*'] = []) => `Câmpul ${field} trebuie să fie numberic și poate conține ${decimals === '*' ? '' : decimals} zecimale.`,
  digits: (field, [length]) => `Câmpul ${field} trebuie să fie numeric și să conțină exact ${length} caractere.`,
  dimensions: (field, [width, height]) => `Câmpul ${field} trebuie să fie ${width} pixeli lungime și ${height} pixeli înălțime.`,
  email: (field) => `Câmpul ${field} trebuie să conțină un email valid.`,
  ext: (field) => `Câmpul ${field} trebuie să fie un nume de fișier valid.`,
  image: (field) => `Câmpul ${field} trebuie să fie o imagine.`,
  included: (field) => `Câmpul ${field} trebuie să conțină o valoare validă.`,
  ip: (field) => `Câmpul ${field} trebuie să conțină o adresa IP vaidă.`,
  max: (field, [length]) => `Câmpul ${field} nu poate fi mai mare de ${length} caractere.`,
  max_value: (field, [max]) => `Câmpul ${field} trebuie să fie maxim ${max}.`,
  mimes: (field) => `Câmpul ${field} trebuie să conțină un fișier cu extensie validă.`,
  min: (field, [length]) => `Câmpul ${field} trebuie să fie cel puțin ${length} caractere.`,
  min_value: (field, [min]) => `Câmpul ${field}trebuie să fie cel puțin ${min}.`,
  excluded: (field) => `Câmpul ${field} trebuie să conțină o valoare validă.`,
  numeric: (field) => `Câmpul ${field} poate conține doar valori numerice.`,
  regex: (field) => `Formatul câmpului ${field} este invalid.`,
  required: (field) => `Câmpul ${field} este necesar.`,
  size: (field, [size]) => `Câmpul ${field} nu trebuie să depășească ${formatFileSize(size)}.`,
  url: (field) => `Câmpul ${field} nu este un URL valid.`
};

const locale = {
  name: 'ro',
  messages,
  attributes: {}
};

if (isDefinedGlobally()) {
  VeeValidate.Validator.localize({ [locale.name]: locale });
}

export default locale;
<|endoftext|>


<commit_before>'use strict';

function File(obj) {
  this.history = [];
  this.pattern = obj.pattern;
  this.recurse = obj.recurse;
  this.dirname = obj.dirname;
  this.segment = obj.segment;
  this.path = obj.path;
  this.stat = obj.stat;
}

/**
 * Expose `File`
 */

module.exports = File;
<commit_msg>allow `stat` to be mixed in later<commit_after>'use strict';

function File(obj) {
  this.history = [];
  this.pattern = obj.pattern;
  this.recurse = obj.recurse;
  this.dirname = obj.dirname;
  this.segment = obj.segment;
  this.path = obj.path;
}

/**
 * Expose `File`
 */

module.exports = File;
<|endoftext|>


<commit_before>//
//   Copyright 2009-2015 Ilkka Oksanen <iao@iki.fi>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

import { observer } from '@ember/object';
import TextArea from '@ember/component/text-area';
import emojione from 'emojione';

const emojisList = Object.keys(emojione.emojioneList)
  .sort()
  .map((value, i) => ({ id: i, name: value }));

export default TextArea.extend({
  participants: null,
  pendingClear: false,

  attributeBindings: ['autocomplete'],

  autocomplete: 'off',

  keyPress(e) {
    if (e.keyCode === 13 && !e.shiftKey) {
      e.preventDefault();

      const value = this.value;

      if (value !== '') {
        this.sendAction('sendMessage', value);
        this.set('value', '');
        this.$().height('100%');
      }
    }
  },

  input() {
    this._updateHeight();
  },

  nickCompletion: observer('participants', function() {
    const participants = this.participants || [];

    this.$().atwho({
      at: '@',
      data: participants.map(item => item.nick),
      limit: 15
    });
  }),

  didInsertElement() {
    this.$().atwho({
      at: ':',
      displayTpl: data => {
        const emoji = emojione.emojioneList[data.name];
        const unicode = emoji.unicode[emoji.unicode.length - 1];
        return `<li><img src="/app/assets/images/emoji/${unicode}.png"> ${data.name}</li>`;
      },
      insertTpl: '${name}', // eslint-disable-line no-template-curly-in-string
      data: emojisList,
      highlightFirst: false,
      limit: 20
    });

    this.$().on('hidden.atwho', e => {
      e.stopPropagation();
    });
  },

  _updateHeight() {
    const prevHeight = this.$().prop('style').height; // Get the non-computed value

    if (prevHeight !== '100%') {
      // By setting the height to 100%, scrollHeight below returns the actual value even when
      // content shrinks. We do this trick only when necessary as it causes noticeable lag
      // on Firefox.
      this.$().css('height', '100%');
    }

    let newHeight = Math.min(this.$().prop('scrollHeight'), 300);

    if (newHeight < 35) {
      newHeight = '100%';
    }

    if (newHeight !== '100%') {
      this.$().height(newHeight);
    }
  }
});
<commit_msg>A hack to really disable address autocompletion in Chrome<commit_after>//
//   Copyright 2009-2015 Ilkka Oksanen <iao@iki.fi>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

import { observer } from '@ember/object';
import TextArea from '@ember/component/text-area';
import emojione from 'emojione';

const emojisList = Object.keys(emojione.emojioneList)
  .sort()
  .map((value, i) => ({ id: i, name: value }));

export default TextArea.extend({
  participants: null,
  pendingClear: false,

  attributeBindings: ['autocomplete'],

  autocomplete: 'nope',

  keyPress(e) {
    if (e.keyCode === 13 && !e.shiftKey) {
      e.preventDefault();

      const value = this.value;

      if (value !== '') {
        this.sendAction('sendMessage', value);
        this.set('value', '');
        this.$().height('100%');
      }
    }
  },

  input() {
    this._updateHeight();
  },

  nickCompletion: observer('participants', function() {
    const participants = this.participants || [];

    this.$().atwho({
      at: '@',
      data: participants.map(item => item.nick),
      limit: 15
    });
  }),

  didInsertElement() {
    this.$().atwho({
      at: ':',
      displayTpl: data => {
        const emoji = emojione.emojioneList[data.name];
        const unicode = emoji.unicode[emoji.unicode.length - 1];
        return `<li><img src="/app/assets/images/emoji/${unicode}.png"> ${data.name}</li>`;
      },
      insertTpl: '${name}', // eslint-disable-line no-template-curly-in-string
      data: emojisList,
      highlightFirst: false,
      limit: 20
    });

    this.$().on('hidden.atwho', e => {
      e.stopPropagation();
    });
  },

  _updateHeight() {
    const prevHeight = this.$().prop('style').height; // Get the non-computed value

    if (prevHeight !== '100%') {
      // By setting the height to 100%, scrollHeight below returns the actual value even when
      // content shrinks. We do this trick only when necessary as it causes noticeable lag
      // on Firefox.
      this.$().css('height', '100%');
    }

    let newHeight = Math.min(this.$().prop('scrollHeight'), 300);

    if (newHeight < 35) {
      newHeight = '100%';
    }

    if (newHeight !== '100%') {
      this.$().height(newHeight);
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Created by Gaplo917 on 9/1/2016.
*/
const PROXY_URL = 'https://ionic-reader.xyz'
const BASE_URL = `https://www.hkepc.com`
const BASE_FORUM_URL = `${BASE_URL}/forum`
const IMAGE_URL = 'https://www.hkepc.com/forum'
const VERSION = "v2.1.0"
function getMobileOperatingSystem(userAgent){
  const ua = userAgent || navigator.userAgent || navigator.vendor || window.opera;

  return ua.match(/Windows Phone \d+/i)
      || ua.match( /iPad/i )
      || ua.match( /iPhone/i )
      || ua.match( /iPod/i )
      || ua.match( /Android/i )
      || 'Web'

}
module.exports = {
  userAgent: () => getMobileOperatingSystem(),
  proxy: PROXY_URL,
  baseUrl: BASE_URL,
  baseForumUrl: BASE_FORUM_URL,
  imageUrl:IMAGE_URL,
  version: VERSION,
  forum: {
    index: () => `${BASE_FORUM_URL}/index.php`,
    latestNext: (searchId,page) => {
      return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=lastpost&ascdesc=desc&searchsubmit=yes&page=${page}`
    },
    latestPostNext: (searchId,page) => {
      if(searchId){
        return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=dateline&ascdesc=desc&searchsubmit=yes&page=${page}`
      } else {
        return `${BASE_FORUM_URL}/search.php?srchfrom=86400&&orderby=dateline&ascdesc=desc&searchsubmit=yes&page=${page}`
      }
    },
    search:() => {
      return `${BASE_FORUM_URL}/search.php`
    },
    searchNext: (searchId, page) => {
      return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=lastpost&ascdesc=desc&searchsubmit=yes&page=${page}`
    },
    topics: (topicId,page,filter,orderby) => {
      return topicId == 'latest'
          ? `${BASE_FORUM_URL}/search.php?srchfrom=12000&searchsubmit=yes&page=${page}`
          : [
              `${BASE_FORUM_URL}/forumdisplay.php?fid=${topicId}`,
              `page=${page}`,
              `filter=${filter >= 0 ? `type&typeid=${filter}` : ''}`,
              `orderby=${orderby||''}`
            ].join("&")
    },
    posts: (topicId,postId,page,orderType,filterOnlyAuthorId) => `${BASE_FORUM_URL}/viewthread.php?fid=${topicId}&tid=${postId}&page=${page}&ordertype=${orderType}&authorid=${filterOnlyAuthorId}`,
    login: () => `${BASE_FORUM_URL}/logging.php?action=login&loginsubmit=yes&loginfield=username`,
    logout: (formhash) => `${BASE_FORUM_URL}/logging.php?action=logout&formhash=${formhash}`,
    news: (page) => `${BASE_URL}/moreNews/page/${page}`,
    replyPage:(reply) => {

      /**
       * reply :{
       *    id: Int,
       *    postId: Int,
       *    topicId: Int,
       *    type: Int ,  1 = None, 2 = Reply , 3 = Quote
       * }
       */

      const url = `${BASE_FORUM_URL}/post.php?action=reply&fid=${reply.topicId}&tid=${reply.postId}`

      switch(reply.type){
        case 1:
          return url
        case 2:
          return `${url}&reppost=${reply.id}`
        case 3:
          return `${url}&repquote=${reply.id}`
        default:
          return url
      }

    },
    reportPage:(topicId,postId,messageId) => `${BASE_FORUM_URL}/misc.php?action=report&fid=${topicId}&tid=${postId}&pid=${messageId}`,
    editMessage:(topicId,postId,messageId) => `${BASE_FORUM_URL}/post.php?action=edit&fid=${topicId}&tid=${postId}&pid=${messageId}`,
    pmList: (page) => `${BASE_FORUM_URL}/pm.php?filter=privatepm&page=${page}`,
    pm: (id) => `${BASE_FORUM_URL}/pm.php?uid=${id}&filter=privatepm&daterange=5#new`,
    notifications: (page) => `${BASE_FORUM_URL}/notice.php?page=${page}`,
    findMessage:(postId,messageId) => `${BASE_FORUM_URL}/redirect.php?goto=findpost&ptid=${postId}&pid=${messageId}`,
    newPost:(fid) => `${BASE_FORUM_URL}/post.php?action=newthread&fid=${fid}`,
    memberCenter: () => `${BASE_FORUM_URL}/memcp.php`,
    checkPM: () => `${BASE_FORUM_URL}/pm.php?checknewpm=0&inajax=1&ajaxtarget=myprompt_check`,
    settings:() => `${BASE_FORUM_URL}/memcp.php?action=profile&typeid=5`,
    subscribeNewReply: (postId) => `${BASE_FORUM_URL}/my.php?item=attention&action=add&tid=${postId}&inajax=1&ajaxtarget=favorite_msg`,
    space: (uid) => `${BASE_FORUM_URL}/space.php?uid=${uid}`,
    myPost: (page) => `${BASE_FORUM_URL}/my.php?item=threads&page=${page}`,
    myReply: (page) => `${BASE_FORUM_URL}/my.php?item=posts&page=${page}`,
    preSendPm: (uid) => `${BASE_FORUM_URL}/pm.php?action=new&uid=${uid}&infloat=yes&handlekey=sendpm&inajax=1&ajaxtarget=fwin_content_sendpm`,
  },
  auth:{
    id: 'cdb_sid',
    token: 'cdb_auth',
    expire: 'expires',
    formhash: 'formhash'
  },
  signature: (color) => {
    return `[size=1][color=Silver]via HKEPC IR Pro ${VERSION} - ${getMobileOperatingSystem()}[/color][/size]`
  },
  data:{
    gifs:[
      {
        "code": ":dev:",
        "url": "icon_dev.gif"
      },
      {
        "code": ":loveliness:",
        "url": "loveliness.gif"
      },
      {
        "code": ":wahaha:",
        "url": "icon_clap.gif"
      },
      {
        "code": ":xd:",
        "url": "icon77.gif"
      },
      {
        "code": ":?:",
        "url": "icon_confused.gif"
      },
      {
        "code": ":d:",
        "url": "icon_biggrin.gif"
      },
      {
        "code": ":p:",
        "url": "icon_tongue.gif"
      },
      {
        "code": ":redface:",
        "url": "icon22.gif"
      },
      {
        "code": ":dizzy:",
        "url": "dizzy.gif"
      },
      {
        "code": ":cry:",
        "url": "icon_cry.gif"
      },
      {
        "code": ":help:",
        "url": "icon_help.gif"
      },
      {
        "code": ":naug:",
        "url": "icon_naughty.gif"
      },
      {
        "code": ":good:",
        "url": "icon_good.gif"
      },
      {
        "code": ":discuss:",
        "url": "icon_discuss.gif"
      },
      {
        "code": ":hitwall:",
        "url": "icon_hitwall.gif"
      },
      {
        "code": ":goodjob:",
        "url": "icon_goodjob.gif"
      },
      {
        "code": ":kicking:",
        "url": "icon_kicking.gif"
      },
      {
        "code": ":giveup:",
        "url": "icon_giveup.gif"
      },
      {
        "code": ":shutup:",
        "url": "shutup.gif"
      },
      {
        "code": ":titter:",
        "url": "titter.gif"
      },
      {
        "code": ":cheers:",
        "url": "icon_cheers2.gif"
      },
      {
        "code": ":shifty:",
        "url": "VsX4_shifty_P31Twc0M1TeT.gif"
      },
      {
        "code": ":crybye:",
        "url": "icon_crybye.gif"
      },
      {
        "code": ":agree:",
        "url": "icon_agree.gif"
      },
      {
        "code": ":adore:",
        "url": "icon_adore.gif"
      },
      {
        "code": ":haha:",
        "url": "icon_haha.gif"
      },
      {
        "code": ":silent:",
        "url": "smile_44.gif"
      },
      {
        "code": ":crutch:",
        "url": "icon_crutch.gif"
      },
      {
        "code": ":faint:",
        "url": "smile_27.gif"
      },
      {
        "code": ":drool:",
        "url": "icon_drool.gif"
      },
      {
        "code": ":chair:",
        "url": "icon_chair.gif"
      },
      {
        "code": ":angry:",
        "url": "icon_angry2.gif"
      },
      {
        "code": ":sleep:",
        "url": "icon_sleep.gif"
      },
      {
        "code": ":noway:",
        "url": "noway.gif"
      },
      {
        "code": ":fight:",
        "url": "icon_fight.gif"
      },
      {
        "code": ":smoke:",
        "url": "icon_smoke.gif"
      },
      {
        "code": ":photo:",
        "url": "icon_photo.gif"
      },
      {
        "code": ":baby:",
        "url": "icon_baby.gif"
      },
      {
        "code": ":band:",
        "url": "icon_band.gif"
      },
      {
        "code": ":kiss:",
        "url": "icon_kiss.gif"
      },
      {
        "code": ":nono:",
        "url": "icon_nono.gif"
      },
      {
        "code": ":mad:",
        "url": "icon_mad.gif"
      },
      {
        "code": ":eek:",
        "url": "icon_eek.gif"
      },
      {
        "code": ":gun:",
        "url": "icon_gun2.gif"
      },
      {
        "code": ":ar:",
        "url": "smile_38.gif"
      },
      {
        "code": ":happybday:",
        "url": "icon_happybday.gif"
      }
    ]
  }
}<commit_msg>fix latest api may not work when searchid is undefined<commit_after>/**
 * Created by Gaplo917 on 9/1/2016.
*/
const PROXY_URL = 'https://ionic-reader.xyz'
const BASE_URL = `https://www.hkepc.com`
const BASE_FORUM_URL = `${BASE_URL}/forum`
const IMAGE_URL = 'https://www.hkepc.com/forum'
const VERSION = "v2.1.0"
function getMobileOperatingSystem(userAgent){
  const ua = userAgent || navigator.userAgent || navigator.vendor || window.opera;

  return ua.match(/Windows Phone \d+/i)
      || ua.match( /iPad/i )
      || ua.match( /iPhone/i )
      || ua.match( /iPod/i )
      || ua.match( /Android/i )
      || 'Web'

}
module.exports = {
  userAgent: () => getMobileOperatingSystem(),
  proxy: PROXY_URL,
  baseUrl: BASE_URL,
  baseForumUrl: BASE_FORUM_URL,
  imageUrl:IMAGE_URL,
  version: VERSION,
  forum: {
    index: () => `${BASE_FORUM_URL}/index.php`,
    latestNext: (searchId,page) => {
      if(searchId){
        return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=lastpost&ascdesc=desc&searchsubmit=yes&page=${page}`
      } else {
        return `${BASE_FORUM_URL}/search.php?srchfrom=86400&&orderby=lastpost&ascdesc=desc&searchsubmit=yes&page=${page}`
      }
    },
    latestPostNext: (searchId,page) => {
      if(searchId){
        return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=dateline&ascdesc=desc&searchsubmit=yes&page=${page}`
      } else {
        return `${BASE_FORUM_URL}/search.php?srchfrom=86400&&orderby=dateline&ascdesc=desc&searchsubmit=yes&page=${page}`
      }
    },
    search:() => {
      return `${BASE_FORUM_URL}/search.php`
    },
    searchNext: (searchId, page) => {
      return `${BASE_FORUM_URL}/search.php?searchid=${searchId}&orderby=lastpost&ascdesc=desc&searchsubmit=yes&page=${page}`
    },
    topics: (topicId,page,filter,orderby) => {
      return topicId == 'latest'
          ? `${BASE_FORUM_URL}/search.php?srchfrom=12000&searchsubmit=yes&page=${page}`
          : [
              `${BASE_FORUM_URL}/forumdisplay.php?fid=${topicId}`,
              `page=${page}`,
              `filter=${filter >= 0 ? `type&typeid=${filter}` : ''}`,
              `orderby=${orderby||''}`
            ].join("&")
    },
    posts: (topicId,postId,page,orderType,filterOnlyAuthorId) => `${BASE_FORUM_URL}/viewthread.php?fid=${topicId}&tid=${postId}&page=${page}&ordertype=${orderType}&authorid=${filterOnlyAuthorId}`,
    login: () => `${BASE_FORUM_URL}/logging.php?action=login&loginsubmit=yes&loginfield=username`,
    logout: (formhash) => `${BASE_FORUM_URL}/logging.php?action=logout&formhash=${formhash}`,
    news: (page) => `${BASE_URL}/moreNews/page/${page}`,
    replyPage:(reply) => {

      /**
       * reply :{
       *    id: Int,
       *    postId: Int,
       *    topicId: Int,
       *    type: Int ,  1 = None, 2 = Reply , 3 = Quote
       * }
       */

      const url = `${BASE_FORUM_URL}/post.php?action=reply&fid=${reply.topicId}&tid=${reply.postId}`

      switch(reply.type){
        case 1:
          return url
        case 2:
          return `${url}&reppost=${reply.id}`
        case 3:
          return `${url}&repquote=${reply.id}`
        default:
          return url
      }

    },
    reportPage:(topicId,postId,messageId) => `${BASE_FORUM_URL}/misc.php?action=report&fid=${topicId}&tid=${postId}&pid=${messageId}`,
    editMessage:(topicId,postId,messageId) => `${BASE_FORUM_URL}/post.php?action=edit&fid=${topicId}&tid=${postId}&pid=${messageId}`,
    pmList: (page) => `${BASE_FORUM_URL}/pm.php?filter=privatepm&page=${page}`,
    pm: (id) => `${BASE_FORUM_URL}/pm.php?uid=${id}&filter=privatepm&daterange=5#new`,
    notifications: (page) => `${BASE_FORUM_URL}/notice.php?page=${page}`,
    findMessage:(postId,messageId) => `${BASE_FORUM_URL}/redirect.php?goto=findpost&ptid=${postId}&pid=${messageId}`,
    newPost:(fid) => `${BASE_FORUM_URL}/post.php?action=newthread&fid=${fid}`,
    memberCenter: () => `${BASE_FORUM_URL}/memcp.php`,
    checkPM: () => `${BASE_FORUM_URL}/pm.php?checknewpm=0&inajax=1&ajaxtarget=myprompt_check`,
    settings:() => `${BASE_FORUM_URL}/memcp.php?action=profile&typeid=5`,
    subscribeNewReply: (postId) => `${BASE_FORUM_URL}/my.php?item=attention&action=add&tid=${postId}&inajax=1&ajaxtarget=favorite_msg`,
    space: (uid) => `${BASE_FORUM_URL}/space.php?uid=${uid}`,
    myPost: (page) => `${BASE_FORUM_URL}/my.php?item=threads&page=${page}`,
    myReply: (page) => `${BASE_FORUM_URL}/my.php?item=posts&page=${page}`,
    preSendPm: (uid) => `${BASE_FORUM_URL}/pm.php?action=new&uid=${uid}&infloat=yes&handlekey=sendpm&inajax=1&ajaxtarget=fwin_content_sendpm`,
  },
  auth:{
    id: 'cdb_sid',
    token: 'cdb_auth',
    expire: 'expires',
    formhash: 'formhash'
  },
  signature: (color) => {
    return `[size=1][color=Silver]via HKEPC IR Pro ${VERSION} - ${getMobileOperatingSystem()}[/color][/size]`
  },
  data:{
    gifs:[
      {
        "code": ":dev:",
        "url": "icon_dev.gif"
      },
      {
        "code": ":loveliness:",
        "url": "loveliness.gif"
      },
      {
        "code": ":wahaha:",
        "url": "icon_clap.gif"
      },
      {
        "code": ":xd:",
        "url": "icon77.gif"
      },
      {
        "code": ":?:",
        "url": "icon_confused.gif"
      },
      {
        "code": ":d:",
        "url": "icon_biggrin.gif"
      },
      {
        "code": ":p:",
        "url": "icon_tongue.gif"
      },
      {
        "code": ":redface:",
        "url": "icon22.gif"
      },
      {
        "code": ":dizzy:",
        "url": "dizzy.gif"
      },
      {
        "code": ":cry:",
        "url": "icon_cry.gif"
      },
      {
        "code": ":help:",
        "url": "icon_help.gif"
      },
      {
        "code": ":naug:",
        "url": "icon_naughty.gif"
      },
      {
        "code": ":good:",
        "url": "icon_good.gif"
      },
      {
        "code": ":discuss:",
        "url": "icon_discuss.gif"
      },
      {
        "code": ":hitwall:",
        "url": "icon_hitwall.gif"
      },
      {
        "code": ":goodjob:",
        "url": "icon_goodjob.gif"
      },
      {
        "code": ":kicking:",
        "url": "icon_kicking.gif"
      },
      {
        "code": ":giveup:",
        "url": "icon_giveup.gif"
      },
      {
        "code": ":shutup:",
        "url": "shutup.gif"
      },
      {
        "code": ":titter:",
        "url": "titter.gif"
      },
      {
        "code": ":cheers:",
        "url": "icon_cheers2.gif"
      },
      {
        "code": ":shifty:",
        "url": "VsX4_shifty_P31Twc0M1TeT.gif"
      },
      {
        "code": ":crybye:",
        "url": "icon_crybye.gif"
      },
      {
        "code": ":agree:",
        "url": "icon_agree.gif"
      },
      {
        "code": ":adore:",
        "url": "icon_adore.gif"
      },
      {
        "code": ":haha:",
        "url": "icon_haha.gif"
      },
      {
        "code": ":silent:",
        "url": "smile_44.gif"
      },
      {
        "code": ":crutch:",
        "url": "icon_crutch.gif"
      },
      {
        "code": ":faint:",
        "url": "smile_27.gif"
      },
      {
        "code": ":drool:",
        "url": "icon_drool.gif"
      },
      {
        "code": ":chair:",
        "url": "icon_chair.gif"
      },
      {
        "code": ":angry:",
        "url": "icon_angry2.gif"
      },
      {
        "code": ":sleep:",
        "url": "icon_sleep.gif"
      },
      {
        "code": ":noway:",
        "url": "noway.gif"
      },
      {
        "code": ":fight:",
        "url": "icon_fight.gif"
      },
      {
        "code": ":smoke:",
        "url": "icon_smoke.gif"
      },
      {
        "code": ":photo:",
        "url": "icon_photo.gif"
      },
      {
        "code": ":baby:",
        "url": "icon_baby.gif"
      },
      {
        "code": ":band:",
        "url": "icon_band.gif"
      },
      {
        "code": ":kiss:",
        "url": "icon_kiss.gif"
      },
      {
        "code": ":nono:",
        "url": "icon_nono.gif"
      },
      {
        "code": ":mad:",
        "url": "icon_mad.gif"
      },
      {
        "code": ":eek:",
        "url": "icon_eek.gif"
      },
      {
        "code": ":gun:",
        "url": "icon_gun2.gif"
      },
      {
        "code": ":ar:",
        "url": "smile_38.gif"
      },
      {
        "code": ":happybday:",
        "url": "icon_happybday.gif"
      }
    ]
  }
}<|endoftext|>


<commit_before>// var prompt = require('prompt');

module.exports = function(grunt) {
  var _ = grunt.utils._;
  var prompts = [
    {
      name: "name",
      message: "Add on Name",
      validator: /^[\w\-\.]+$/,
      default: "WickedCool"
    },
    {
      name: "path",
      message: "Location of add ons",
      default: "app/addons"
    }
  ];

  addonTemplates = [
    {
      name: 'base',
      filename: 'base.js',
      template: 'define([\n  "app",\n  "api",\n  "addons/<%= module.toLowerCase() %>/routes"\n],\n\nfunction(app, FauxtonAPI, <%= module %>) {\n\tvar <%= module %> = new FauxtonAPI.addon();\n\treturn <%= module %>;\n});\n'
    },
    {
      name: 'resources',
      filename: 'resources.js',
      template: 'define([\n  "app",\n  "backbone",\n  "modules/fauxton/base"\n],\n\nfunction (app, backbone, Fauxton) {\n\tvar <%= module %> = {};\n\treturn <%= module %>;\n});\n'
    },
    {
      name: 'routes',
      filename: 'routes.js',
      template: 'define([\n  "app",\n  "api",\n  "addons/<%= module.toLowerCase() %>/resources"\n],\n\nfunction(app, FauxtonAPI, <%= module %>) {\n\treturn <%= module %>;\n});\n'
    }
  ]

  // Create a new task.
  grunt.registerInitTask('addon', 'Generate a skeleton for an addon"', function() {
    var done = this.async()
    grunt.helper('prompt', {}, prompts, function (err, result) {
      if (err) { return onErr(err); }
      var module = result.name
      filepath = result.path + '/' + module.toLowerCase() + '/templates';
      grunt.file.mkdir(filepath);
      _.each(addonTemplates, function(file){
        file.module = module.charAt(0).toUpperCase() + module.substr(1);
        var content = grunt.template.process(file.template, file);
        grunt.file.write(filepath + '/' + file.filename, content)
      });
      grunt.log.writeln('Created addon ' + result.name + ' in ' + result.path);
      done();
    });
    function onErr(err) {
      grunt.log.writeln(err);
      done();
      return 1;
    }
  });

  grunt.registerMultiTask('template', 'generates an html file from a specified template', function(){
    var data = this.data;
    var _ = grunt.utils._;
    var tmpl = _.template(grunt.file.read(data.src), null, data.variables);
    grunt.file.write(data.dest, tmpl(data.variables));
  });

  grunt.registerMultiTask('get_deps', 'Fetch external dependencies', function() {
    grunt.log.writeln("Fetching external dependencies");

    var path = require('path');
    var done = this.async();
    var data = this.data;
    var target = data.target || "app/addons/";
    var settingsFile = path.existsSync(data.src) ? data.src : "settings.json.default";
    var settings = grunt.file.readJSON(settingsFile);
    var _ = grunt.utils._;

    // This should probably be a helper, though they seem to have been removed
    var fetch = function(deps, command){
      var child_process = require('child_process');
      var async = require('async');
      async.forEach(deps, function(dep, cb) {
        var path = target + dep.name;
        var location = dep.url || dep.path;
        grunt.log.writeln("Fetching: " + dep.name + " (" + location + ")");

        child_process.exec(command(dep, path), function(error, stdout, stderr) {
          grunt.log.writeln(stderr);
          grunt.log.writeln(stdout);
          cb(error);
        });
      }, function(error) {
        if (error) {
          grunt.log.writeln("ERROR: " + error.message);
          return false;
        } else {
          return true;
        }
      });
    };

    var remoteDeps = _.filter(settings.deps, function(dep) { return !! dep.url; });
    grunt.log.writeln(remoteDeps.length + " remote dependencies");
    var remote = fetch(remoteDeps, function(dep, destination){
      return "git clone " + dep.url + " " + destination;
    });

    var localDeps = _.filter(settings.deps, function(dep) { return !! dep.path; });
    grunt.log.writeln(localDeps.length + " local dependencies");
    var local = fetch(localDeps, function(dep, destination){
      // TODO: Windows
      var command = "cp -r " + dep.path + " " + destination;
      grunt.log.writeln(command);
      return command;
    });

    done(remote && local);

  });

  grunt.registerMultiTask('gen_load_addons', 'Generate the load_addons.js file', function() {
    var path = require('path');
    var data = this.data;
    var _ = grunt.utils._;
    var settingsFile = path.existsSync(data.src) ? data.src : "settings.json.default";
    var settings = grunt.file.readJSON(settingsFile);
    var template = "app/load_addons.js.underscore";
    var dest = "app/load_addons.js";
    var deps = _.map(settings.deps, function(dep) {
      return "addons/" + dep.name + "/base";
    });
    var tmpl = _.template(grunt.file.read(template));
    grunt.file.write(dest, tmpl({deps: deps}));
  });

};<commit_msg>fix addons task<commit_after>// var prompt = require('prompt');

module.exports = function(grunt) {
  var _ = grunt.utils._;
  var prompts = [
    {
      name: "name",
      message: "Add on Name",
      validator: /^[\w\-\.]+$/,
      default: "WickedCool"
    },
    {
      name: "path",
      message: "Location of add ons",
      default: "app/addons"
    }
  ];

  addonTemplates = [
    {
      name: 'base',
      filename: 'base.js',
      template: 'define([\n  "app",\n  "api",\n  "addons/<%= module.toLowerCase() %>/routes"\n],\n\nfunction(app, FauxtonAPI, <%= module %>Routes) {\n\tvar <%= module %> = new FauxtonAPI.addon();\n\treturn <%= module %>;\n});\n'
    },
    {
      name: 'resources',
      filename: 'resources.js',
      template: 'define([\n  "app",\n  "backbone",\n  "modules/fauxton/base"\n],\n\nfunction (app, backbone, Fauxton) {\n\tvar <%= module %> = {};\n\treturn <%= module %>;\n});\n'
    },
    {
      name: 'routes',
      filename: 'routes.js',
      template: 'define([\n  "app",\n  "api",\n  "addons/<%= module.toLowerCase() %>/resources"\n],\n\nfunction(app, FauxtonAPI, <%= module %>) {\n\treturn <%= module %>;\n});\n'
    }
  ]

  // Create a new task.
  grunt.registerInitTask('addon', 'Generate a skeleton for an addon"', function() {
    var done = this.async()
    grunt.helper('prompt', {}, prompts, function (err, result) {
      if (err) { return onErr(err); }
      var module = result.name
      filepath = result.path + '/' + module.toLowerCase() + '/templates';
      grunt.file.mkdir(filepath);
      filepath = result.path + '/' + module.toLowerCase();
      _.each(addonTemplates, function(file){
        file.module = module.charAt(0).toUpperCase() + module.substr(1);
        var content = grunt.template.process(file.template, file);
        grunt.file.write(filepath + '/' + file.filename, content)
      });
      grunt.log.writeln('Created addon ' + result.name + ' in ' + result.path);
      done();
    });
    function onErr(err) {
      grunt.log.writeln(err);
      done();
      return 1;
    }
  });

  grunt.registerMultiTask('template', 'generates an html file from a specified template', function(){
    var data = this.data;
    var _ = grunt.utils._;
    var tmpl = _.template(grunt.file.read(data.src), null, data.variables);
    grunt.file.write(data.dest, tmpl(data.variables));
  });

  grunt.registerMultiTask('get_deps', 'Fetch external dependencies', function() {
    grunt.log.writeln("Fetching external dependencies");

    var path = require('path');
    var done = this.async();
    var data = this.data;
    var target = data.target || "app/addons/";
    var settingsFile = path.existsSync(data.src) ? data.src : "settings.json.default";
    var settings = grunt.file.readJSON(settingsFile);
    var _ = grunt.utils._;

    // This should probably be a helper, though they seem to have been removed
    var fetch = function(deps, command){
      var child_process = require('child_process');
      var async = require('async');
      async.forEach(deps, function(dep, cb) {
        var path = target + dep.name;
        var location = dep.url || dep.path;
        grunt.log.writeln("Fetching: " + dep.name + " (" + location + ")");

        child_process.exec(command(dep, path), function(error, stdout, stderr) {
          grunt.log.writeln(stderr);
          grunt.log.writeln(stdout);
          cb(error);
        });
      }, function(error) {
        if (error) {
          grunt.log.writeln("ERROR: " + error.message);
          return false;
        } else {
          return true;
        }
      });
    };

    var remoteDeps = _.filter(settings.deps, function(dep) { return !! dep.url; });
    grunt.log.writeln(remoteDeps.length + " remote dependencies");
    var remote = fetch(remoteDeps, function(dep, destination){
      return "git clone " + dep.url + " " + destination;
    });

    var localDeps = _.filter(settings.deps, function(dep) { return !! dep.path; });
    grunt.log.writeln(localDeps.length + " local dependencies");
    var local = fetch(localDeps, function(dep, destination){
      // TODO: Windows
      var command = "cp -r " + dep.path + " " + destination;
      grunt.log.writeln(command);
      return command;
    });

    done(remote && local);

  });

  grunt.registerMultiTask('gen_load_addons', 'Generate the load_addons.js file', function() {
    var path = require('path');
    var data = this.data;
    var _ = grunt.utils._;
    var settingsFile = path.existsSync(data.src) ? data.src : "settings.json.default";
    var settings = grunt.file.readJSON(settingsFile);
    var template = "app/load_addons.js.underscore";
    var dest = "app/load_addons.js";
    var deps = _.map(settings.deps, function(dep) {
      return "addons/" + dep.name + "/base";
    });
    var tmpl = _.template(grunt.file.read(template));
    grunt.file.write(dest, tmpl({deps: deps}));
  });

};<|endoftext|>


<commit_before>var openBlockList = function () {
        $('document').ready( function () {
            $("#blocked_blogs > .accordion_trigger_wrapper > .accordion_trigger").click();
        });
}

var block = function (blog) {
    $("#blocked_blogs > .accordion_content > .block-input > .text > #block").val(blog);
    setTimeout(function () {
        $("#blocked_blogs > .accordion_content > .block-input > .block-button").click();
    }, 500);
}

var activate = function () {
    console.log ("activate");
	var usersToBeBlockedStr = window.prompt("Please input comma separated list of users to be blocked","");
	var usersToBeBlocked = usersToBeBlockedStr.split(",");

	openBlockList();

	// we will be watching the blockListContainer for changes
	var blockListContainer = $('#blocked_blogs > div.accordion_content');

	// i don't know if i need all this to do what i need to do
	// TODO: determine what to keep and what to trim
	var mutationObserverConfig = { attributes: true, childList: true, subtree: true };

	var mutationObserverCallback = function (mutationsList, observer) {
		for (var mutation of mutationsList) {
			if (mutation.type == 'childList') {
				if (mutation.target.classList[0] == "error_tag") {
					console.log("Error");
				}
				else if (mutation.addedNodes.length > 0) {
					var tumblelog = (mutation.addedNodes[0]).getAttribute('data-tumblelog');
					if (tumblelog !== null) {
						console.log("Added to blocklist: " + tumblelog);
					}
				}
			}
		}
	};

	var observer = new MutationObserver(mutationObserverCallback);

	// in the console you don't need [0], but in the extension you do... a frustrating adventure in troubleshooting
	observer.observe(blockListContainer[0], mutationObserverConfig);

    var i = 0;
    var inter = setInterval (function () {
        console.log (i + " -- " + usersToBeBlocked[i]);
        block(usersToBeBlocked[i++]);
        if (i >= usersToBeBlocked.length) {
            clearInterval(inter);
            console.log ("exit");
        }
    }, 1100);

	// observer.disconnect() // this is disabled because it triggers before any of the blocking happens
}

activate ();
<commit_msg>Convert to looping with MutationObserver<commit_after>var openBlockList = function () {
	$('document').ready( function () {
		$("#blocked_blogs > .accordion_trigger_wrapper > .accordion_trigger").click();
	});
}

var block = function (blog) {
    $("#blocked_blogs > .accordion_content > .block-input > .text > #block").val(blog);
    $("#blocked_blogs > .accordion_content > .block-input > .block-button").click();
}

/* activate
 * blocks an array of users
 * @usersToBeBlocked an array of usernames (should be prestripped of already blocked users)
 */
var activate = function (usersToBeBlocked) {
    console.log ("activate");

	// we will be watching the blockListContainer for changes
	var blockListContainer = $('#blocked_blogs > div.accordion_content.show');

	// i don't know if i need all this to do what i need to do
	// TODO: determine what to keep and what to trim
	var mutationObserverConfig = { attributes: true, childList: true, subtree: true };

	var i = 0;
	var mutationObserverCallback = function (mutationsList, observer) {
		for (var mutation of mutationsList) {
			if (mutation.type == 'childList') {
				if (mutation.target.classList[0] == "error_tag") {
					console.log("Error on " + usersToBeBlocked[i]);
					block(usersToBeBlocked[++i]);
				}
				else if (mutation.addedNodes.length > 0) {
					var tumblelog = (mutation.addedNodes[0]).getAttribute('data-tumblelog');
					if (tumblelog !== null) {
						if (i == 0 && tumblelog == usersToBeBlocked[0]) {
							console.log("Added to blocklist: " + tumblelog);
							block(usersToBeBlocked[++i]);
						} else if (i !== 0) {
							console.log("Added to blocklist: " + tumblelog);
							block(usersToBeBlocked[++i]);
						}
					}
				}
			}
		}

		// this seems like it listens for one element extra, but i'm not sure
		if (i > usersToBeBlocked.length) {
			observer.disconnect();
		}
	};

	var observer = new MutationObserver(mutationObserverCallback);

	// in the console you don't need [0], but in the extension you do... a frustrating adventure in troubleshooting
	observer.observe(blockListContainer[0], mutationObserverConfig);
	// trigger a cascade of MutationObserver events (starts iteration through the blocklist)
	block(usersToBeBlocked[0]);
}

// expandBlockList clicks the button which opens the blocklist
// Then it clicks the 'Show More' button until it is no longer visible
// The 'Show More' button still exists, and will loop through the block list if you continue to click it.
var expandBlockList = function (callback) {
    $('document').ready(function () {
		$("#blocked_blogs > .accordion_trigger_wrapper > .accordion_trigger").click();

		var expandInterval = setInterval(function() {
			if ($('#blocked_blogs > div.accordion_content.show > button').is(':visible')) {
				$('#blocked_blogs > div.accordion_content.show > button').click();
			} else {
				clearInterval(expandInterval);
				callback();
			}
		}, 500);
    });
}

// getBlockList gathers all the blog names in a user's block list
// It returns the list as an array
var getBlockList = function () {
    var i = 1;
    var blocklist = [];

    var blog = jQuery('#blocked_blogs > div.accordion_content.show > ul > li:nth-child(' + i++ + ') > div.blog-info > a.name');

    while (blog !== undefined && blog[0] !== undefined) {
        blocklist.push(blog[0].innerText);

        var blog = jQuery('#blocked_blogs > div.accordion_content.show > ul > li:nth-child(' + i++ + ') > div.blog-info > a.name');
    }

    return blocklist;
}

// get list of users who will be blocked
var usersToBeBlockedStr = window.prompt("Please input comma separated list of users to be blocked","");
// convert user input to array
var usersToBeBlocked = usersToBeBlockedStr.split(",");
// trim whitespace (necessary for filtering)
for (var index = 0; index < usersToBeBlocked.length; index++) {
	usersToBeBlocked[index] = usersToBeBlocked[index].trim();
}
expandBlockList(function() {
	// get list of users who are already blocked
    var blockedUsers = JSON.stringify(getBlockList());
	// remove already blocked users from user input
	usersToBeBlocked = usersToBeBlocked.filter(user => !(blockedUsers.includes(user)));

	activate(usersToBeBlocked);
});

<|endoftext|>


<commit_before>/************************************************************
 * jQuery plugin for rendering a spec object into HTML.
 * As we work through the passed-in spec object,
 * we need to be able to handle strings of the form tag[#id][.class],
 * fragments of valid HTML, and text content.
 * We need to traverse members of the object and recurse into
 * any members that are objects themselves. Becase we can
 * recurse, remember that any data type might be passed in as spec
 * in a given recursion.
 ************************************************************/
$.render = function (spec) {
	var div = $("<div/>");
	return { promise: div.render(spec).data("promise"), html: div.html() }
}

$.fn.render = function (spec) {
	var _this = this;

	// create a dfd to make sure we always have at least one promise.
	// make sure we're not waiting for it, though.
	// this is just for the syntax for $.when.apply()
	var default_dfd = $.Deferred();
	var element_load_promises = [default_dfd.promise()];
	default_dfd.resolve();

	if (spec instanceof jQuery) {
		return spec;
	}
	// test of whether we can apply a string to our function for creating tags.
	// string must be of the form tag[#id][.class]
	// optional conditions are so it will match either or both id and classnames.
	// 6/15 -- this will now also trap any attributes (to be parsed by a separate regexp).
	// Oof. Regex's are hard, in part because there's no room for comments.
	// Here is a breakdown of the capture groups:
	// (\w+)? == optional tag name (default is div).
	// (#\w[^\.\[]+)? == optional id, leading up to either a list of class names or a list of attributes
	// ((?:\.\w[^\[]+)*)? == optional list of class names -- not capturing individual class names, just the whole list.
	// ... note about above: you need both the * for matching 0 or more, and the ?, in order to get the whole thing & yet leave it optional.
	// (\[\S+=\S+\])* == 0 or more attributes. done. whew.
	var tag_id_class_regexp = /^(\w+)?(#\w[^\.\[]+)?((?:\.\w[^\[]+)*)?(\[\S+=\S+\])*$/;

	var valid_html_tags = ["A", "ABBR", "ACRONYM", "ADDRESS", "APPLET", "AREA", "B", "BASE", "BASEFONT", "BDO", "BIG", "BLOCKQUOTE", "BODY", "BR", "BUTTON", "CAPTION", "CENTER", "CITE", "CODE", "COL", "COLGROUP", "DD", "DEL", "DFN", "DIR", "DIV", "DL", "DT", "EM", "FIELDSET", "FONT", "FORM", "FRAME", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEAD", "HR", "HTML", "I", "IFRAME", "IMG", "INPUT", "INS", "ISINDEX", "KBD", "LABEL", "LEGEND", "LI", "LINK", "MAP", "MENU", "META", "NOFRAMES", "NOSCRIPT", "OBJECT", "OL", "OPTGROUP", "OPTION", "P", "PARAM", "PRE", "Q", "S", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRIKE", "STRONG", "STYLE", "SUB", "SUP", "TABLE", "TBODY", "TD", "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR", "TT", "U", "UL", "VAR"]

	// test whether str can be added to an HTML element.
	function is_valid_html (str) {
		var test_div = $('<div/>');
		test_div.html(str);
		return (test_div[0].childNodes.length) ? true : false;
	}

	// function to turn a descriptor into an empty HTML element.
	// successful matches are of the form: [<whole str>, <tag name>, <id>, <class names separated by .>]
	function createElement (str) {
		var matches = tag_id_class_regexp.exec(str);
		var tag_name, el, id, classnames;
		var dfd = $.Deferred();

		if (matches === null) {
			return str; // probably a space in the text.
		} else {
			tag_name = matches[1] || "div"; // so we can use descriptors that are just ids and/or class names.
			if (tag_name === "svg") {
				// make a div to hold the loaded svg.
				el = $(document.createElement("div"));
				el.addClass("svg");
			} else if (valid_html_tags.indexOf(tag_name.toUpperCase()) > -1) {
				el = $(document.createElement(tag_name));
			} else {
				return str;
			}

			if (id = matches[2]) {
				el.attr("id", id.replace("#", ""));
			}
			if (classnames = matches[3]) {
				el.addClass(classnames.split(".").join(" "));
			}
			var attributes = matches[4];
			if (attributes) {
				var attr_regexp = /(\[([^=]+)=([^\]]+)\])/g;
				var attr_spec;
				var attrs_obj = {};
				while (attr_spec = attr_regexp.exec(attributes)) {
					var attr_key = attr_spec[2];
					var attr_value = attr_spec[3];
					el.attr(attr_key, attr_value);
					attrs_obj[attr_key] = attr_value;

					// special cases: content that must be loaded after element is created.
					switch (tag_name) {
						case "svg":
							if (attr_key === "src") {
								var svg_dfd = $.Deferred();
								var svg_promise = svg_dfd.promise();
								element_load_promises.push(svg_promise);
								// we pull the contents of the src file
								// and use it to replace the <svg> element.
								$.ajax(attr_value, { crossDomain: true })
								.then(function (svg_file) {
									var svg_file_jQ = $(svg_file.documentElement);
									// put svg file root node into element.
									var svg_root_element = document.importNode(svg_file.documentElement,true);
									el.append(svg_root_element);
									el.data({ promise: svg_promise });
									// give added elements a chance to show up in the DOM.
									svg_dfd.resolve();
								})
								.fail(function () {
									// convert svg tag to an object tag w src as data attr...?
									// Does this make a good fallback? I guess it depends on the reason for the ajax failure.
									dfd.fail();
								})
							}
							break;

						case "img":
							if (attr_key === "src") {
								var img_dfd = $.Deferred();
								var img_promise = img_dfd.promise();
								element_load_promises.push(img_promise);
								el.attr(attr_key, attr_value);
								// resolve once the image has been loaded.
								el.get(0).onload = function (evt) {
									img_dfd.resolve();
								}
							}
							break;

						default:
							dfd.resolve();
							break;
					}
				}
			} else {
				dfd.resolve(); // no atrributes.
			}

			el.data({ promise: $.when.apply(element_load_promises) });
			return el;
		}
	}

	// processing the spec based on type.
	switch (typeof spec) {
		case "string":
			// is_valid_html will return true for vanilla strings (eg; "some text"),
			// which are, in fact, valid HTML.
			// we have to exclude our tag descriptors, though.
			if (is_valid_html(spec)) {
				if (tag_id_class_regexp.test(spec)) {
					var el = createElement(spec);
					$(this).append(el);
					return el;
				} else {
					return $(this).html(spec);
				}
			} else {
				console.warn("Invalid content passed to jQuery render()", spec);
			}
			break;

		case "object":
			if (spec instanceof Array) {
				for (var item in spec) {
					if (spec instanceof HTMLElement) {
						$(this).append(item);
					} else {
						var el = createElement(item);
						$(this).append(el);
					}
				}
			} else if (spec instanceof HTMLElement) {
				$(this).append(spec);
			} else {
				var keys = Object.keys(spec);
				var key;
				var promises = [];
				for (var i=0; i<keys.length; i++) {
					key = keys[i];
					// check if this is an Array or Array-like object.
					if (parseInt(key) === i) {
						// do nothing. the key is just the ordinal of the element.
						// el is the current this.
						var el = this;
					} else {
						var el = createElement(key);
					}
					// recurse into complex objects.
					if (typeof spec[key] === "string") {
						$(el).append(createElement(spec[key]));
					} else {
						$(el).render(spec[key]);
					}
					promises.push(el.data("promise"));
					$(this).append(el);
				}
			}

			// make a promise that encapsulates all the collected promises.
			this.data({ promise: $.when.apply($, promises) });
			break;

		case "number":
			return $(this).html(spec);
			break;
	}
	return this;
}<commit_msg>fix jquery.render() for arrays.<commit_after>/************************************************************
 * jQuery plugin for rendering a spec object into HTML.
 * As we work through the passed-in spec object,
 * we need to be able to handle strings of the form tag[#id][.class],
 * fragments of valid HTML, and text content.
 * We need to traverse members of the object and recurse into
 * any members that are objects themselves. Becase we can
 * recurse, remember that any data type might be passed in as spec
 * in a given recursion.
 ************************************************************/
$.render = function (spec) {
	var div = $("<div/>");
	return { promise: div.render(spec).data("promise"), html: div.html() }
}

$.fn.render = function (spec) {
	var _this = this;

	// create a dfd to make sure we always have at least one promise.
	// make sure we're not waiting for it, though.
	// this is just for the syntax for $.when.apply()
	var default_dfd = $.Deferred();
	var element_load_promises = [default_dfd.promise()];
	default_dfd.resolve();

	if (spec instanceof jQuery) {
		return spec;
	}
	// test of whether we can apply a string to our function for creating tags.
	// string must be of the form tag[#id][.class]
	// optional conditions are so it will match either or both id and classnames.
	// 6/15 -- this will now also trap any attributes (to be parsed by a separate regexp).
	// Oof. Regex's are hard, in part because there's no room for comments.
	// Here is a breakdown of the capture groups:
	// (\w+)? == optional tag name (default is div).
	// (#\w[^\.\[]+)? == optional id, leading up to either a list of class names or a list of attributes
	// ((?:\.\w[^\[]+)*)? == optional list of class names -- not capturing individual class names, just the whole list.
	// ... note about above: you need both the * for matching 0 or more, and the ?, in order to get the whole thing & yet leave it optional.
	// (\[\S+=\S+\])* == 0 or more attributes. done. whew.
	var tag_id_class_regexp = /^(\w+)?(#\w[^\.\[]+)?((?:\.\w[^\[]+)*)?(\[\S+=\S+\])*$/;

	var valid_html_tags = ["A", "ABBR", "ACRONYM", "ADDRESS", "APPLET", "AREA", "B", "BASE", "BASEFONT", "BDO", "BIG", "BLOCKQUOTE", "BODY", "BR", "BUTTON", "CAPTION", "CENTER", "CITE", "CODE", "COL", "COLGROUP", "DD", "DEL", "DFN", "DIR", "DIV", "DL", "DT", "EM", "FIELDSET", "FONT", "FORM", "FRAME", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEAD", "HR", "HTML", "I", "IFRAME", "IMG", "INPUT", "INS", "ISINDEX", "KBD", "LABEL", "LEGEND", "LI", "LINK", "MAP", "MENU", "META", "NOFRAMES", "NOSCRIPT", "OBJECT", "OL", "OPTGROUP", "OPTION", "P", "PARAM", "PRE", "Q", "S", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRIKE", "STRONG", "STYLE", "SUB", "SUP", "TABLE", "TBODY", "TD", "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR", "TT", "U", "UL", "VAR"]

	// test whether str can be added to an HTML element.
	function is_valid_html (str) {
		var test_div = $('<div/>');
		test_div.html(str);
		return (test_div[0].childNodes.length) ? true : false;
	}

	// function to turn a descriptor into an empty HTML element.
	// successful matches are of the form: [<whole str>, <tag name>, <id>, <class names separated by .>]
	function createElement (str) {
		var matches = tag_id_class_regexp.exec(str);
		var tag_name, el, id, classnames;
		var dfd = $.Deferred();

		if (matches === null) {
			return str; // probably a space in the text.
		} else {
			tag_name = matches[1] || "div"; // so we can use descriptors that are just ids and/or class names.
			if (tag_name === "svg") {
				// make a div to hold the loaded svg.
				el = $(document.createElement("div"));
				el.addClass("svg");
			} else if (valid_html_tags.indexOf(tag_name.toUpperCase()) > -1) {
				el = $(document.createElement(tag_name));
			} else {
				return str;
			}

			if (id = matches[2]) {
				el.attr("id", id.replace("#", ""));
			}
			if (classnames = matches[3]) {
				el.addClass(classnames.split(".").join(" "));
			}
			var attributes = matches[4];
			if (attributes) {
				var attr_regexp = /(\[([^=]+)=([^\]]+)\])/g;
				var attr_spec;
				var attrs_obj = {};
				while (attr_spec = attr_regexp.exec(attributes)) {
					var attr_key = attr_spec[2];
					var attr_value = attr_spec[3];
					el.attr(attr_key, attr_value);
					attrs_obj[attr_key] = attr_value;

					// special cases: content that must be loaded after element is created.
					switch (tag_name) {
						case "svg":
							if (attr_key === "src") {
								var svg_dfd = $.Deferred();
								var svg_promise = svg_dfd.promise();
								element_load_promises.push(svg_promise);
								// we pull the contents of the src file
								// and use it to replace the <svg> element.
								$.ajax(attr_value, { crossDomain: true })
								.then(function (svg_file) {
									var svg_file_jQ = $(svg_file.documentElement);
									// put svg file root node into element.
									var svg_root_element = document.importNode(svg_file.documentElement,true);
									el.append(svg_root_element);
									el.data({ promise: svg_promise });
									// give added elements a chance to show up in the DOM.
									svg_dfd.resolve();
								})
								.fail(function () {
									// convert svg tag to an object tag w src as data attr...?
									// Does this make a good fallback? I guess it depends on the reason for the ajax failure.
									dfd.fail();
								})
							}
							break;

						case "img":
							if (attr_key === "src") {
								var img_dfd = $.Deferred();
								var img_promise = img_dfd.promise();
								element_load_promises.push(img_promise);
								el.attr(attr_key, attr_value);
								// resolve once the image has been loaded.
								el.get(0).onload = function (evt) {
									img_dfd.resolve();
								}
							}
							break;

						default:
							dfd.resolve();
							break;
					}
				}
			} else {
				dfd.resolve(); // no atrributes.
			}

			el.data({ promise: $.when.apply(element_load_promises) });
			return el;
		}
	}

	// processing the spec based on type.
	switch (typeof spec) {
		case "string":
			// is_valid_html will return true for vanilla strings (eg; "some text"),
			// which are, in fact, valid HTML.
			// we have to exclude our tag descriptors, though.
			if (is_valid_html(spec)) {
				if (tag_id_class_regexp.test(spec)) {
					var el = createElement(spec);
					$(this).append(el);
					return el;
				} else {
					return $(this).html(spec);
				}
			} else {
				console.warn("Invalid content passed to jQuery render()", spec);
			}
			break;

		case "object":
			if (spec instanceof Array) {
				for (var i=0; i<spec.length; i++) {
					var item = spec[i];
					if (spec instanceof HTMLElement) {
						$(this).append(item);
					} else {
						var el = createElement(item);
						$(this).append(el);
					}
				}
			} else if (spec instanceof HTMLElement) {
				$(this).append(spec);
			} else {
				var keys = Object.keys(spec);
				var key;
				var promises = [];
				for (var i=0; i<keys.length; i++) {
					key = keys[i];
					// check if this is an Array or Array-like object.
					if (parseInt(key) === i) {
						// do nothing. the key is just the ordinal of the element.
						// el is the current this.
						var el = this;
					} else {
						var el = createElement(key);
					}
					// recurse into complex objects.
					if (typeof spec[key] === "string") {
						$(el).append(createElement(spec[key]));
					} else {
						$(el).render(spec[key]);
					}
					promises.push(el.data("promise"));
					$(this).append(el);
				}
			}

			// make a promise that encapsulates all the collected promises.
			this.data({ promise: $.when.apply($, promises) });
			break;

		case "number":
			return $(this).html(spec);
			break;
	}
	return this;
}<|endoftext|>