PageSourceSearch

https://www.mdmarchive.co.uk/js/jquery.siteFunctions_2023.php?v=1790938330

js mdmarchive.co.uk collected 2026-10-02 10:53:12 UTC 340,022 bytes, 7,856 lines download raw bytes

1
2/*global jQuery: true */
3
4/*!
5   --------------------------------
6   Infinite Scroll
7   --------------------------------
8   + https://github.com/paulirish/infinite-scroll
9   + version 2.1.0
10   + Copyright 2011/12 Paul Irish & Luke Shumard
11   + Licensed under the MIT license
12
13   + Documentation: http://infinite-scroll.com/
14*/
15
16// Uses AMD or browser globals to create a jQuery plugin.
17(function (factory) {
18    if (typeof define === 'function' && define.amd) {
19        // AMD. Register as an anonymous module.
20        define(['jquery'], factory);
21    } else {
22        // Browser globals
23        factory(jQuery);
24    }
25}(function ($, undefined) {
26    'use strict';
27
28    $.infinitescroll = function infscr(options, callback, element) {
29        this.element = $(element);
30
31        // Flag the object in the event of a failed creation
32        if (!this._create(options, callback)) {
33            this.failed = true;
34        }
35    };
36
37    $.infinitescroll.defaults = {
38        loading: {
39            finished: undefined,
40            finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",
41            img: 'data:image/gif;base64,R0lGODlh3AATAPQeAPDy+MnQ6LW/4N3h8MzT6rjC4sTM5r/I5NHX7N7j8c7U6tvg8OLl8uXo9Ojr9b3G5MfP6Ovu9tPZ7PT1+vX2+tbb7vf4+8/W69jd7rC73vn5/O/x+K243ai02////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgD/ACwAAAAA3AATAAAF/6AnjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEj0BAScpHLJbDqf0Kh0Sq1ar9isdioItAKGw+MAKYMFhbF63CW438f0mg1R2O8EuXj/aOPtaHx7fn96goR4hmuId4qDdX95c4+RBIGCB4yAjpmQhZN0YGYGXitdZBIVGAsLoq4BBKQDswm1CQRkcG6ytrYKubq8vbfAcMK9v7q7EMO1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQkCLBwHCgsMDQ4RDAYIqfYSFxDxEfz88/X38Onr16+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdFf9chIeBg7oA7gjaWUWTVQAGE3LqBDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKzggYBBB5y1acFNZmEvXAoN2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCbYMNFCzwLEqLgE4NsDWs/tvqdezZf13Hvk2A9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebd3A8vjf5QWfH6Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrA1ANoCDGrgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBFAJNv1DVV01MAdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJghQSwT40PgfAl4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA40AqVCIhG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAUKABwALAcABADOAAsAAAX/IPd0D2dyRCoUp/k8gpHOKtseR9yiSmGbuBykler9XLAhkbDavXTL5k2oqFqNOxzUZPU5YYZd1XsD72rZpBjbeh52mSNnMSC8lwblKZGwi+0QfIJ8CncnCoCDgoVnBHmKfByGJimPkIwtiAeBkH6ZHJaKmCeVnKKTHIihg5KNq4uoqmEtcRUtEREMBggtEr4QDrjCuRC8h7/BwxENeicSF8DKy82pyNLMOxzWygzFmdvD2L3P0dze4+Xh1Arkyepi7dfFvvTtLQkZBC0T/FX3CRgCMOBHsJ+EHYQY7OinAGECgQsB+Lu3AOK+CewcWjwxQeJBihtNGHSoQOE+iQ3//4XkwBBhRZMcUS6YSXOAwIL8PGqEaSJCiYt9SNoCmnJPAgUVLChdaoFBURN8MAzl2PQphwQLfDFd6lTowglHve6rKpbjhK7/pG5VinZP1qkiz1rl4+tr2LRwWU64cFEihwEtZgbgR1UiHaMVvxpOSwBA37kzGz9e8G+B5MIEKLutOGEsAH2ATQwYfTmuX8aETWdGPZmiZcccNSzeTCA1Sw0bdiitC7LBWgu8jQr8HRzqgpK6gX88QbrB14z/kF+ELpwB8eVQj/JkqdylAudji/+ts3039vEEfK8Vz2dlvxZKG0CmbkKDBvllRd6fCzDvBLKBDSCeffhRJEFebFk1k/Mv9jVIoIJZSeBggwUaNeB+Qk34IE0cXlihcfRxkOAJFFhwGmKlmWDiakZhUJtnLBpnWWcnKaAZcxI0piFGGLBm1mc90kajSCveeBVWKeYEoU2wqeaQi0PetoE+rr14EpVC7oAbAUHqhYExbn2XHHsVqbcVew9tx8+XJKk5AZsqqdlddGpqAKdbAYBn1pcczmSTdWvdmZ17c1b3FZ99vnTdCRFM8OEcAhLwm1NdXnWcBBSMRWmfkWZqVlsmLIiAp/o1gGV2vpS4lalGYsUOqXrddcKCmK61aZ8SjEpUpVFVoCpTj4r661Km7kBHjrDyc1RAIQAAIfkEBQoAGwAsBwAEAM4ACwAABf/gtmUCd4goQQgFKj6PYKi0yrrbc8i4ohQt12EHcal+MNSQiCP8gigdz7iCioaCIvUmZLp8QBzW0EN2vSlCuDtFKaq4RyHzQLEKZNdiQDhRDVooCwkbfm59EAmKi4SGIm+AjIsKjhsqB4mSjT2IOIOUnICeCaB/mZKFNTSRmqVpmJqklSqskq6PfYYCDwYHDC4REQwGCBLGxxIQDsHMwhAIX8bKzcENgSLGF9PU1j3Sy9zX2NrgzQziChLk1BHWxcjf7N046tvN82715czn9Pryz6Ilc4ACj4EBOCZM8KEnAYYADBRKnACAYUMFv1wotIhCEcaJCisqwJFgAUSQGyX/kCSVUUTIdKMwJlyo0oXHlhskwrTJciZHEXsgaqS4s6PJiCAr1uzYU8kBBSgnWFqpoMJMUjGtDmUwkmfVmVypakWhEKvXsS4nhLW5wNjVroJIoc05wSzTr0PtiigpYe4EC2vj4iWrFu5euWIMRBhacaVJhYQBEFjA9jHjyQ0xEABwGceGAZYjY0YBOrRLCxUp29QM+bRkx5s7ZyYgVbTqwwti2ybJ+vLtDYpycyZbYOlptxdx0kV+V7lC5iJAyyRrwYKxAdiz82ng0/jnAdMJFz0cPi104Ec1Vj9/M6F173vKL/feXv156dw11tlqeMMnv4V5Ap53GmjQQH97nFfg+IFiucfgRX5Z8KAgbUlQ4IULIlghhhdOSB6AgX0IVn8eReghen3NRIBsRgnH4l4LuEidZBjwRpt6NM5WGwoW0KSjCwX6yJSMab2GwwAPDXfaBCtWpluRTQqC5JM5oUZAjUNS+VeOLWpJEQ7VYQANW0INJSZVDFSnZphjSikfmzE5N4EEbQI1QJmnWXCmHulRp2edwDXF43txukenJwvI9xyg9Q26Z3MzGUcBYFEChZh6DVTq34AU8Iflh51Sd+CnKFYQ6mmZkhqfBKfSxZWqA9DZanWjxmhrWwi0qtCrt/43K6WqVjjpmhIqgEGvculaGKklKstAACEAACH5BAUKABwALAcABADOAAsAAAX/ICdyQmaMYyAUqPgIBiHPxNpy79kqRXH8wAPsRmDdXpAWgWdEIYm2llCHqjVHU+jjJkwqBTecwItShMXkEfNWSh8e1NGAcLgpDGlRgk7EJ/6Ae3VKfoF/fDuFh
41ohVeDeCfXkcCQqDVQcQhn+VNDOYmpSWaoqBlUSfmowjEA+iEAEGDRGztAwGCDcXEA60tXEiCrq8vREMEBLIyRLCxMWSHMzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/Cpk3ABwSLQkYAQwT/P309vcI7OvXr94jBQMJ/nskkGA/BQBRLNDncAIAiDcG6LsxAWOLiQzmeURBKWSLCQbv/1F0eDGinJUKR47YY1IEgQASKk7Yc7ACRwZm7mHweRJoz59BJUogisKCUaFMR0x4SlJBVBFTk8pZivTR0K73rN5wqlXEAq5Fy3IYgHbEzQ0nLy4QSoCjXLoom96VOJEeCosK5n4kkFfqXjl94wa+l1gvAcGICbewAOAxY8l/Ky/QhAGz4cUkGxu2HNozhwMGBnCUqUdBg9UuW9eUynqSwLHIBujePef1ZGQZXcM+OFuEBeBhi3OYgLyqcuaxbT9vLkf4SeqyWxSQpKGB2gQpm1KdWbu72rPRzR9Ne2Nu9Kzr/1Jqj0yD/fvqP4aXOt5sW/5qsXXVcv1Nsp8IBUAmgswGF3llGgeU1YVXXKTN1FlhWFXW3gIE+DVChApysACHHo7Q4A35lLichh+ROBmLKAzgYmYEYDAhCgxKGOOMn4WR4kkDaoBBOxJtdNKQxFmg5JIWIBnQc07GaORfUY4AEkdV6jHlCEISSZ5yTXpp1pbGZbkWmcuZmQCaE6iJ0FhjMaDjTMsgZaNEHFRAQVp3bqXnZED1qYcECOz5V6BhSWCoVJQIKuKQi2KFKEkEFAqoAo7uYSmO3jk61wUUMKmknJ4SGimBmAa0qVQBhAAAIfkEBQoAGwAsBwAEAM4ACwAABf/gJm5FmRlEqhJC+bywgK5pO4rHI0D3pii22+Mg6/0Ej96weCMAk7cDkXf7lZTTnrMl7eaYoy10JN0ZFdco0XAuvKI6qkgVFJXYNwjkIBcNBgR8TQoGfRsJCRuCYYQQiI+ICosiCoGOkIiKfSl8mJkHZ4U9kZMbKaI3pKGXmJKrngmug4WwkhA0lrCBWgYFCCMQFwoQDRHGxwwGCBLMzRLEx8iGzMMO0cYNeCMKzBDW19lnF9DXDIY/48Xg093f0Q3s1dcR8OLe8+Y91OTv5wrj7o7B+7VNQqABIoRVCMBggsOHE36kSoCBIcSH3EbFangxogJYFi8CkJhqQciLJEf/LDDJEeJIBT0GsOwYUYJGBS0fjpQAMidGmyVP6sx4Y6VQhzs9VUwkwqaCCh0tmKoFtSMDmBOf9phg4SrVrROuasRQAaxXpVUhdsU6IsECZlvX3kwLUWzRt0BHOLTbNlbZG3vZinArge5Dvn7wbqtQkSYAAgtKmnSsYKVKo2AfW048uaPmG386i4Q8EQMBAIAnfB7xBxBqvapJ9zX9WgRS2YMpnvYMGdPK3aMjt/3dUcNI4blpj7iwkMFWDXDvSmgAlijrt9RTR78+PS6z1uAJZIe93Q8g5zcsWCi/4Y+C8bah5zUv3vv89uft30QP23punGCx5954oBBwnwYaNCDY/wYrsYeggnM9B2Fpf8GG2CEUVWhbWAtGouEGDy7Y4IEJVrbSiXghqGKIo7z1IVcXIkKWWR361QOLWWnIhwERpLaaCCee5iMBGJQmJGyPFTnbkfHVZGRtIGrg5HALEJAZbu39BuUEUmq1JJQIPtZilY5hGeSWsSk52G9XqsmgljdIcABytq13HyIM6RcUA+r1qZ4EBF3WHWB29tBgAzRhEGhig8KmqKFv8SeCeo+mgsF7YFXa1qWSbkDpom/mqR1PmHCqJ3fwNRVXjC7S6CZhFVCQ2lWvZiirhQq42SACt25IK2hv8TprriUV1usGgeka7LFcNmCldMLi6qZMgFLgpw16Cipb7bC1knXsBiEAACH5BAUKABsALAcABADOAAsAAAX/4FZsJPkUmUGsLCEUTywXglFuSg7fW1xAvNWLF6sFFcPb42C8EZCj24EJdCp2yoegWsolS0Uu6fmamg8n8YYcLU2bXSiRaXMGvqV6/KAeJAh8VgZqCX+BexCFioWAYgqNi4qAR4ORhRuHY408jAeUhAmYYiuVlpiflqGZa5CWkzc5fKmbbhIpsAoQDRG8vQwQCBLCwxK6vb5qwhfGxxENahvCEA7NzskSy7vNzzzK09W/PNHF1NvX2dXcN8K55cfh69Luveol3vO8zwi4Yhj+AQwmCBw4IYclDAAJDlQggVOChAoLKkgFkSCAHDwWLKhIEOONARsDKryogFPIiAUb/95gJNIiw4wnI778GFPhzBKFOAq8qLJEhQpiNArjMcHCmlTCUDIouTKBhApELSxFWiGiVKY4E2CAekPgUphDu0742nRrVLJZnyrFSqKQ2ohoSYAMW6IoDpNJ4bLdILTnAj8KUF7UeENjAKuDyxIgOuGiOI0EBBMgLNew5AUrDTMGsFixwBIaNCQuAXJB57qNJ2OWm2Aj4skwCQCIyNkhhtMkdsIuodE0AN4LJDRgfLPtn5YDLdBlraAByuUbBgxQwICxMOnYpVOPej074OFdlfc0TqC62OIbcppHjV4o+LrieWhfT8JC/I/T6W8oCl29vQ0XjLdBaA3s1RcPBO7lFvpX8BVoG4O5jTXRQRDuJ6FDTzEWF1/BCZhgbyAKE9qICYLloQYOFtahVRsWYlZ4KQJHlwHS/IYaZ6sZd9tmu5HQm2xi1UaTbzxYwJk/wBF5g5EEYOBZeEfGZmNdFyFZmZIR4jikbLThlh5kUUVJGmRT7sekkziRWUIACABk3T4qCsedgO4xhgGcY7q5pHJ4klBBTQRJ0CeHcoYHHUh6wgfdn9uJdSdMiebGJ0zUPTcoS286FCkrZxnYoYYKWLkBowhQoBeaOlZAgVhLidrXqg2G
41iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/oGFw2WZuT5oZROsSQnGaKjRvilI893MItlNOJ5v5gDcFrHhKIWcEYu/xFEqNv6B1N62aclysF7fsZYe5aOx2yL5aAUGSaT1oTYMBwQ5VGCAJgYIJCnx1gIOBhXdwiIl7d0p2iYGQUAQBjoOFSQR/lIQHnZ+Ue6OagqYzSqSJi5eTpTxGcjcSChANEbu8DBAIEsHBChe5vL13G7fFuscRDcnKuM3H0La3EA7Oz8kKEsXazr7Cw9/Gztar5uHHvte47MjktznZ2w0G1+D3BgirAqJmJMAQgMGEgwgn5Ei0gKDBhBMALGRYEOJBb5QcWlQo4cbAihZz3GgIMqFEBSM1/4ZEOWPAgpIIJXYU+PIhRG8ja1qU6VHlzZknJNQ6UanCjQkWCIGSUGEjAwVLjc44+DTqUQtPPS5gejUrTa5TJ3g9sWCr1BNUWZI161StiQUDmLYdGfesibQ3XMq1OPYthrwuA2yU2LBs2cBHIypYQPPlYAKFD5cVvNPtW8eVGbdcQADATsiNO4cFAPkvHpedPzc8kUcPgNGgZ5RNDZG05reoE9s2vSEP79MEGiQGy1qP8LA4ZcdtsJE48ONoLTBtTV0B9LsTnPceoIDBDQvS7W7vfjVY3q3eZ4A339J4eaAmKqU/sV58HvJh2RcnIBsDUw0ABqhBA5aV5V9XUFGiHfVeAiWwoFgJJrIXRH1tEMiDFV4oHoAEGlaWhgIGSGBO2nFomYY3mKjVglidaNYJGJDkWW2xxTfbjCbVaOGNqoX2GloR8ZeTaECS9pthRGJH2g0b3Agbk6hNANtteHD2GJUucfajCQBy5OOTQ25ZgUPvaVVQmbKh9510/qQpwXx3SQdfk8tZJOd5b6JJFplT3ZnmmX3qd5l1eg5q00HrtUkUn0AKaiGjClSAgKLYZcgWXwocGRcCFGCKwSB6ceqphwmYRUFYT/1WKlOdUpipmxW0mlCqHjYkAaeoZlqrqZ4qd+upQKaapn/AmgAegZ8KUtYtFAQQAgAh+QQFCgAbACwHAAQAzgALAAAF/+C2PUcmiCiZGUTrEkKBis8jQEquKwU5HyXIbEPgyX7BYa5wTNmEMwWsSXsqFbEh8DYs9mrgGjdK6GkPY5GOeU6ryz7UFopSQEzygOGhJBjoIgMDBAcBM0V/CYqLCQqFOwobiYyKjn2TlI6GKC2YjJZknouaZAcQlJUHl6eooJwKooobqoewrJSEmyKdt59NhRKFMxLEEA4RyMkMEAjDEhfGycqAG8TQx9IRDRDE3d3R2ctD1RLg0ttKEnbY5wZD3+zJ6M7X2RHi9Oby7u/r9g38UFjTh2xZJBEBMDAboogAgwkQI07IMUORwocSJwCgWDFBAIwZOaJIsOBjRogKJP8wTODw5ESVHVtm3AhzpEeQElOuNDlTZ0ycEUWKWFASqEahGwYUPbnxoAgEdlYSqDBkgoUNClAlIHbSAoOsqCRQnQHxq1axVb06FWFxLIqyaze0Tft1JVqyE+pWXMD1pF6bYl3+HTqAWNW8cRUFzmih0ZAAB2oGKukSAAGGRHWJgLiR6AylBLpuHKKUMlMCngMpDSAa9QIUggZVVvDaJobLeC3XZpvgNgCmtPcuwP3WgmXSq4do0DC6o2/guzcseECtUoO0hmcsGKDgOt7ssBd07wqesAIGZC1YIBa7PQHvb1+SFo+++HrJSQfB33xfav3i5eX3Hnb4CTJgegEq8tH/YQEOcIJzbm2G2EoYRLgBXFpVmFYDcREV4HIcnmUhiGBRouEMJGJGzHIspqgdXxK0yCKHRNXoIX4uorCdTyjkyNtdPWrA4Up82EbAbzMRxxZRR54WXVLDIRmRcag5d2R6ugl3ZXzNhTecchpMhIGVAKAYpgJjjsSklBEd99maZoo535ZvdamjBEpusJyctg3h4X8XqodBMx0tiNeg/oGJaKGABpogS40KSqiaEgBqlQWLUtqoVQnytekEjzo0hHqhRorppOZt2p923M2AAV+oBtpAnnPNoB6HaU6mAAIU+IXmi3j2mtFXuUoHKwXpzVrsjcgGOauKEjQrwq157hitGq2NoWmjh7z6Wmxb0m5w66+2VRAuXN/yFUAIACH5BAUKABsALAcABADOAAsAAAX/4CZuRiaM45MZqBgIRbs9AqTcuFLE7VHLOh7KB5ERdjJaEaU4ClO/lgKWjKKcMiJQ8KgumcieVdQMD8cbBeuAkkC6LYLhOxoQ2PF5Ys9PKPBMen17f0CCg4VSh32JV4t8jSNqEIOEgJKPlkYBlJWRInKdiJdkmQlvKAsLBxdABA4RsbIMBggtEhcQsLKxDBC2TAS6vLENdJLDxMZAubu8vjIbzcQRtMzJz79S08oQEt/guNiyy7fcvMbh4OezdAvGrakLAQwyABsELQkY9BP+//ckyPDD4J9BfAMh1GsBoImMeQUN+lMgUJ9CiRMa5msxoB9Gh/o8GmxYMZXIgxtR/yQ46S/gQAURR0pDwYDfywoyLPip5AdnCwsMFPBU4BPFhKBDi444quCmDKZOfwZ9KEGpCKgcN1jdALSpPqIYsabS+nSqvqplvYqQYAeDPgwKwjaMtiDl0oaqUAyo+3TuWwUAMPpVCfee0cEjVBGQq2ABx7oTWmQk4FglZMGN9fGVDMCuiH2AOVOu/PmyxM630gwM0CCn6q8LjVJ8GXvpa5Uwn95OTC/nNxkda1/dLSK475IjCD6dHbK1ZOa4hXP9DXs5chJ00UpVm5xo2qRpoxptwF2E4/IbJpB/SDz9+q9b1aNfQH08+p4a8uvX8B53fLP+ycAfemjsRUBgp1H20K+BghHgVgt1GXZXZpZ5lt4ECjxYR4ScUWiShEtZqBiIInRGWnERNnjiBglw+JyGnxUmGowsyiiZg189lNtPGACjV2+S9UjbU0JWF6SPvEk3QZEqsZYTk3UAaRSUnznJI5LmESCdBVSyaOWUWLK4I5gDUYVeV1T9l+FZClCAUVA09uSmRHBCKAECFEhW51ht6rnmWBXkaR+NjuHpJ40D3DmnQXt2F+ihZxlqVKOfQRACACH5BAUKABwALAcABADOAAsAAAX/ICdyUCkUo/g8mUG8MCGkKgspeC6j6XEIEBpBUeCNfECaglBcOVfJFK7YQwZHQ6JRZBUqTrSuVEuD3nI45pYjFuWKvjjSkCoRaBUMWxkwBGgJCXspQ36Bh4EEB0oKhoiBgyNLjo8Ki4QElIiWfJqHnISNEI+Ql5J9o6SgkqKkgqYihamPkW6oNBgSfiMMDQkGCBLCwxIQDhHIyQwQCGMKxsnKVyPCF9DREQ3MxMPX0cu4wt7J2uHWx9jlKd3o39MiuefYEcvNkuLt5O8c1ePI2tyELXGQwoGDAQf+iEC2xByDCRAjTlAgIUWCBRgCPJQ4AQBFXAs0coT40WLIjRxL/47AcHLkxIomRXL0CHPERZkpa4q4iVKiyp0tR/7kwHMkTUBBJR5dOCEBAVcKKtCAyOHpowXCpk7goABqBZdcvWploACpBKkpIJI1q5OD2rIWE0R1uTZu1LFwbWL9OlKuWb4c6+o9i3dEgw0RCGDUG9KlRw56gDY2qmCByZBaASi+TACA0TucAaTteCcy0ZuOK3N2vJlx58+LRQyY3Xm0ZsgjZg+oPQLi7dUcNXi0LOJw1pgNtB7XG6CBy+U75SYfPTSQAgZTNUDnQHt67wnbZyvwLgKiMN3oCZB3C76tdewpLFgIP2C88rbi4Y+QT3+8S5USMICZXWj1pkEDeUU3lOYGB3alSoEiMIjgX4WlgNF2EibIwQIXauWXSRg2SAOHIU5IIIMoZkhhWiJaiFVbKo6AQEgQXrTAazO1JhkBrBG3Y2Y6EsUhaGn95hprSN0oWpFE7rhkeaQBchGOEWnwEmc0uKWZj0LeuNV3W4Y2lZHFlQCSRjTIl8uZ+kG5HU/3sRlnTG2ytyadytnD3HrmuRcSn+0h1dycexIK1KCjYaCnjCCVqOFFJTZ5GkUUjESWaUIKU2lgCmAKKQIUjHapXRKE+t2og1VgankNYnohqKJ2CmKplso6GKz7WYCgqxeuyoF8u9IQAgA7',
42            msg: null,
43            msgText: '<em>Loading the next set of posts...</em>',
44            selector: null,
45            speed: 'fast',
46            start: undefined
47        },
48        state: {
49            isDuringAjax: false,
50            isInvalidPage: false,
51            isDestroyed: false,
52            isDone: false, // For when it goes all the way through the archive.
53            isPaused: false,
54            isBeyondMaxPage: false,
55            currPage: 1
56        },
57        debug: false,
58        behavior: undefined,
59        binder: $(window), // used to cache the selector
60        nextSelector: 'div.navigation a:first',
61        navSelector: 'div.navigation',
62        contentSelector: null, // rename to pageFragment
63        extraScrollPx: 150,
64        itemSelector: 'div.post',
65        animate: false,
66        pathParse: undefined,
67        dataType: 'html',
68        appendCallback: true,
69        bufferPx: 40,
70        errorCallback: function () { },
71        infid: 0, //Instance ID
72        pixelsFromNavToBottom: undefined,
73        path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL
74        prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
75        maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
76    };
77
78    $.infinitescroll.prototype = {
79
80        /*
81            ----------------------------
82            Private methods
83            ----------------------------
84            */
85
86        // Bind or unbind from scroll
87        _binding: function infscr_binding(binding) {
88
89            var instance = this,
90            opts = instance.options;
91
92            opts.v = '2.0b2.120520';
93
94            // if behavior is defined and this function is extended, call that instead of default
95            if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) {
96                this['_binding_'+opts.behavior].call(this);
97                return;
98            }
99
100            if (binding !== 'bind' && binding !== 'unbind') {
101                this._debug('Binding value  ' + binding + ' not valid');
102                return false;
103            }
104
105            if (binding === 'unbind') {
106                (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);
107            } else {
108                (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {
109                    instance.scroll();
110                });
111            }
112
113            this._debug('Binding', binding);
114        },
115
116        // Fundamental aspects of the plugin are initialized
117        _create: function infscr_create(options, callback) {
118
119            // Add custom options to defaults
120            var opts = $.extend(true, {}, $.infinitescroll.defaults, options);
121            this.options = opts;
122            var $window = $(window);
123            var instance = this;
124
125            // Validate selectors
126            if (!instance._validate(options)) {
127                return false;
128            }
129
130            // Validate page fragment path
131            var path = $(opts.nextSelector).attr('href');
132            if (!path) {
133                this._debug('Navigation selector not found');
134                return false;
135            }
136
137            // Set the path to be a relative URL from root.
138            opts.path = opts.path || this._determinepath(path);
139
140            // contentSelector is 'page fragment' option for .load() / .ajax() calls
141            opts.contentSelector = opts.contentSelector || this.element;
142
143            // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector
144            opts.loading.selector = opts.loading.selector || opts.contentSelector;
145
146            // Define loading.msg
147            opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');
148
149            // Preload loading.img
150            (new Image()).src = opts.loading.img;
151
152            // distance from nav links to bottom
153            // computed as: height of the document + top offset of container - top offset of nav link
154            if(opts.pixelsFromNavToBottom === undefined) {
155                opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;
156                this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom);
157            }
158
159            var self = this;
160
161            // determine loading.start actions
162            opts.loading.start = opts.loading.start || function() {
163                $(opts.navSelector).hide();
164                opts.loading.msg
165                .appendTo(opts.loading.selector)
166                .show(opts.loading.speed, $.proxy(function() {
167                    this.beginAjax(opts);
168                }, self));
169            };
170
171            // determine loading.finished actions
172            opts.loading.finished = opts.loading.finished || function() {
173                if (!opts.state.isBeyondMaxPage)
174                    opts.loading.msg.fadeOut(opts.loading.speed);
175            };
176
177            // callback loading
178            opts.callback = function(instance, data, url) {
179                if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) {
180                    instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url);
181                }
182
183                if (callback) {
184                    callback.call($(opts.contentSelector)[0], data, opts, url);
185                }
186
187                if (opts.prefill) {
188                    $window.bind('resize.infinite-scroll', instance._prefill);
189                }
190            };
191
192            if (options.debug) {
193                // Tell IE9 to use its built-in console
194                if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') {
195                    ['log','info','warn','error','assert','dir','clear','profile','profileEnd']
196                        .forEach(function (method) {
197                            console[method] = this.call(console[method], console);
198                        }, Function.prototype.bind);
199                }
200            }
201
202            this._setup();
203
204            // Setups the prefill method for use
205            if (opts.prefill) {
206                this._prefill();
207            }
208
209            // Return true to indicate successful creation
210            return true;
211        },
212
213        _prefill: function infscr_prefill() {
214            var instance = this;
215            var $window = $(window);
216
217            function needsPrefill() {
218                return ( $(instance.options.contentSelector).height() <= $window.height() );
219            }
220
221            this._prefill = function() {
222                if (needsPrefill()) {
223                    instance.scroll();
224                }
225
226                $window.bind('resize.infinite-scroll', function() {
227                    if (needsPrefill()) {
228                        $window.unbind('resize.infinite-scroll');
229                        instance.scroll();
230                    }
231                });
232            };
233
234            // Call self after setting up the new function
235            this._prefill();
236        },
237
238        // Console log wrapper
239        _debug: function infscr_debug() {
240            if (true !== this.options.debug) {
241                return;
242            }
243
244            if (typeof console !== 'undefined' && typeof console.log === 'function') {
245                // Modern browsers
246                // Single argument, which is a string
247                if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
248                    console.log( (Array.prototype.slice.call(arguments)).toString() );
249                } else {
250                    console.log( Array.prototype.slice.call(arguments) );
251                }
252            } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {
253                // IE8
254                Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
255            }
256        },
257
258        // find the number to increment in the path.
259        _determinepath: function infscr_determinepath(path) {
260
261            var opts = this.options;
262
263            // if behavior is defined and this function is extended, call that instead of default
264            if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) {
265                return this['_determinepath_'+opts.behavior].call(this,path);
266            }
267
268            if (!!opts.pathParse) {
269
270                this._debug('pathParse manual');
271                return opts.pathParse(path, this.options.state.currPage+1);
272
273            } else if (path.match(/^(.*?)\b2\b(.*?$)/)) {
274                path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
275
276                // if there is any 2 in the url at all.
277            } else if (path.match(/^(.*?)2(.*?$)/)) {
278
279                // page= is used in django:
280                // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
281                if (path.match(/^(.*?page=)2(\/.*|$)/)) {
282                    path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
283                    return path;
284                }
285
286                path = path.match(/^(.*?)2(.*?$)/).slice(1);
287
288            } else {
289
290                // page= is used in drupal too but second page is page=1 not page=2:
291                // thx Jerod Fritz, vladikoff
292                if (path.match(/^(.*?page=)1(\/.*|$)/)) {
293                    path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
294                    return path;
295                } else {
296                    this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");
297                    // Get rid of isInvalidPage to allow permalink to state
298                    opts.state.isInvalidPage = true;  //prevent it from running on this page.
299                }
300            }
301            this._debug('determinePath', path);
302            return path;
303
304        },
305
306        // Custom error
307        _error: function infscr_error(xhr) {
308
309            var opts = this.options;
310
311            // if behavior is defined and this function is extended, call that instead of default
312            if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {
313                this['_error_'+opts.behavior].call(this,xhr);
314                return;
315            }
316
317            if (xhr !== 'destroy' && xhr !== 'end') {
318                xhr = 'unknown';
319            }
320
321            this._debug('Error', xhr);
322
323            if (xhr === 'end' || opts.state.isBeyondMaxPage) {
324                this._showdonemsg();
325            }
326
327            opts.state.isDone = true;
328            opts.state.currPage = 1; // if you need to go back to this instance
329            opts.state.isPaused = false;
330            opts.state.isBeyondMaxPage = false;
331            this._binding('unbind');
332
333        },
334
335        // Load Callback
336        _loadcallback: function infscr_loadcallback(box, data, url) {
337            var opts = this.options,
338            callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK
339            result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',
340            frag;
341
342            // if behavior is defined and this function is extended, call that instead of default
343            if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {
344                this['_loadcallback_'+opts.behavior].call(this,box,data,url);
345                return;
346            }
347
348            switch (result) {
349                case 'done':
350                    this._showdonemsg();
351                    return false;
352
353                case 'no-append':
354                    if (opts.dataType === 'html') {
355                        data = '<div>' + data + '</div>';
356                        data = $(data).find(opts.itemSelector);
357                    }
358
359                    // if it didn't return anything
360                    if (data.length === 0) {
361                        return this._error('end');
362                    }
363
364                    break;
365
366                case 'append':
367                    var children = box.children();
368                    // if it didn't return anything
369                    if (children.length === 0) {
370                        return this._error('end');
371                    }
372
373                    // use a documentFragment because it works when content is going into a table or UL
374                    frag = document.createDocumentFragment();
375                    while (box[0].firstChild) {
376                        frag.appendChild(box[0].firstChild);
377                    }
378
379                    this._debug('contentSelector', $(opts.contentSelector)[0]);
380                    $(opts.contentSelector)[0].appendChild(frag);
381                    // previously, we would pass in the new DOM element as context for the callback
382                    // however we're now using a documentfragment, which doesn't have parents or children,
383                    // so the context is the contentContainer guy, and we pass in an array
384                    // of the elements collected as the first argument.
385
386                    data = children.get();
387                    break;
388            }
389
390            // loadingEnd function
391            opts.loading.finished.call($(opts.contentSelector)[0],opts);
392
393            // smooth scroll to ease in the new content
394            if (opts.animate) {
395                var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';
396                $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });
397            }
398
399            if (!opts.animate) {
400                // once the call is done, we can allow it again.
401                opts.state.isDuringAjax = false;
402            }
403
404            callback(this, data, url);
405
406            if (opts.prefill) {
407                this._prefill();
408            }
409        },
410
411        _nearbottom: function infscr_nearbottom() {
412
413            var opts = this.options,
414            pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();
415
416            // if behavior is defined and this function is extended, call that instead of default
417            if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {
418                return this['_nearbottom_'+opts.behavior].call(this);
419            }
420
421            this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);
422
423            // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
424            return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);
425
426        },
427
428        // Pause / temporarily disable plugin from firing
429        _pausing: function infscr_pausing(pause) {
430
431            var opts = this.options;
432
433            // if behavior is defined and this function is extended, call that instead of default
434            if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {
435                this['_pausing_'+opts.behavior].call(this,pause);
436                return;
437            }
438
439            // If pause is not 'pause' or 'resume', toggle it's value
440            if (pause !== 'pause' && pause !== 'resume' && pause !== null) {
441                this._debug('Invalid argument. Toggling pause value instead');
442            }
443
444            pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';
445
446            switch (pause) {
447                case 'pause':
448                    opts.state.isPaused = true;
449                break;
450
451                case 'resume':
452                    opts.state.isPaused = false;
453                break;
454
455                case 'toggle':
456                    opts.state.isPaused = !opts.state.isPaused;
457                break;
458            }
459
460            this._debug('Paused', opts.state.isPaused);
461            return false;
462
463        },
464
465        // Behavior is determined
466        // If the behavior option is undefined, it will set to default and bind to scroll
467        _setup: function infscr_setup() {
468
469            var opts = this.options;
470
471            // if behavior is defined and this function is extended, call that instead of default
472            if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {
473                this['_setup_'+opts.behavior].call(this);
474                return;
475            }
476
477            this._binding('bind');
478
479            return false;
480
481        },
482
483        // Show done message
484        _showdonemsg: function infscr_showdonemsg() {
485
486            var opts = this.options;
487
488            // if behavior is defined and this function is extended, call that instead of default
489            if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {
490                this['_showdonemsg_'+opts.behavior].call(this);
491                return;
492            }
493
494            opts.loading.msg
495            .find('img')
496            .hide()
497            .parent()
498            .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {
499                $(this).parent().fadeOut(opts.loading.speed);
500            });
501
502            // user provided callback when done
503            opts.errorCallback.call($(opts.contentSelector)[0],'done');
504        },
505
506        // grab each selector option and see if any fail
507        _validate: function infscr_validate(opts) {
508            for (var key in opts) {
509                if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {
510                    this._debug('Your ' + key + ' found no elements.');
511                    return false;
512                }
513            }
514
515            return true;
516        },
517
518        /*
519            ----------------------------
520            Public methods
521            ----------------------------
522            */
523
524        // Bind to scroll
525        bind: function infscr_bind() {
526            this._binding('bind');
527        },
528
529        // Destroy current instance of plugin
530        destroy: function infscr_destroy() {
531            this.options.state.isDestroyed = true;
532            this.options.loading.finished();
533            return this._error('destroy');
534        },
535
536        // Set pause value to false
537        pause: function infscr_pause() {
538            this._pausing('pause');
539        },
540
541        // Set pause value to false
542        resume: function infscr_resume() {
543            this._pausing('resume');
544        },
545
546        beginAjax: function infscr_ajax(opts) {
547            var instance = this,
548                path = opts.path,
549                box, desturl, method, condition;
550
551            // increment the URL bit. e.g. /page/3/
552            opts.state.currPage++;
553
554            // Manually control maximum page
555            if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){
556                opts.state.isBeyondMaxPage = true;
557                this.destroy();
558                return;
559            }
560
561            // if we're dealing with a table we can't use DIVs
562            box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');
563
564            desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);
565            instance._debug('heading into ajax', desturl);
566
567            method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';
568            if (opts.appendCallback && opts.dataType === 'html') {
569                method += '+callback';
570            }
571
572            switch (method) {
573                case 'html+callback':
574                    instance._debug('Using HTML via .load() method');
575                    box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {
576                        instance._loadcallback(box, responseText, desturl);
577                    });
578
579                    break;
580
581                case 'html':
582                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
583                    $.ajax({
584                        // params
585                        url: desturl,
586                        dataType: opts.dataType,
587                        complete: function infscr_ajax_callback(jqXHR, textStatus) {
588                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
589                            if (condition) {
590                                instance._loadcallback(box, jqXHR.responseText, desturl);
591                            } else {
592                                instance._error('end');
593                            }
594                        }
595                    });
596
597                    break;
598                case 'json':
599                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
600                    $.ajax({
601                        dataType: 'json',
602                        type: 'GET',
603                        url: desturl,
604                        success: function (data, textStatus, jqXHR) {
605                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
606                            if (opts.appendCallback) {
607                                // if appendCallback is true, you must defined template in options.
608                                // note that data passed into _loadcallback is already an html (after processed in opts.template(data)).
609                                if (opts.template !== undefined) {
610                                    var theData = opts.template(data);
611                                    box.append(theData);
612                                    if (condition) {
613                                        instance._loadcallback(box, theData);
614                                    } else {
615                                        instance._error('end');
616                                    }
617                                } else {
618                                    instance._debug('template must be defined.');
619                                    instance._error('end');
620                                }
621                            } else {
622                                // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.
623                                if (condition) {
624                                    instance._loadcallback(box, data, desturl);
625                                } else {
626                                    instance._error('end');
627                                }
628                            }
629                        },
630                        error: function() {
631                            instance._debug('JSON ajax request failed.');
632                            instance._error('end');
633                        }
634                    });
635
636                    break;
637            }
638        },
639
640        // Retrieve next set of content items
641        retrieve: function infscr_retrieve(pageNum) {
642            pageNum = pageNum || null;
643
644            var instance = this,
645            opts = instance.options;
646
647            // if behavior is defined and this function is extended, call that instead of default
648            if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {
649                this['retrieve_'+opts.behavior].call(this,pageNum);
650                return;
651            }
652
653            // for manual triggers, if destroyed, get out of here
654            if (opts.state.isDestroyed) {
655                this._debug('Instance is destroyed');
656                return false;
657            }
658
659            // we dont want to fire the ajax multiple times
660            opts.state.isDuringAjax = true;
661
662            opts.loading.start.call($(opts.contentSelector)[0],opts);
663        },
664
665        // Check to see next page is needed
666        scroll: function infscr_scroll() {
667
668            var opts = this.options,
669            state = opts.state;
670
671            // if behavior is defined and this function is extended, call that instead of default
672            if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {
673                this['scroll_'+opts.behavior].call(this);
674                return;
675            }
676
677            if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {
678                return;
679            }
680
681            if (!this._nearbottom()) {
682                return;
683            }
684
685            this.retrieve();
686
687        },
688
689        // Toggle pause value
690        toggle: function infscr_toggle() {
691            this._pausing();
692        },
693
694        // Unbind from scroll
695        unbind: function infscr_unbind() {
696            this._binding('unbind');
697        },
698
699        // update options
700        update: function infscr_options(key) {
701            if ($.isPlainObject(key)) {
702                this.options = $.extend(true,this.options,key);
703            }
704        }
705    };
706
707
708    /*
709        ----------------------------
710        Infinite Scroll function
711        ----------------------------
712
713        Borrowed logic from the following...
714
715        jQuery UI
716        - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
717
718        jCarousel
719        - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
720
721        Masonry
722        - https://github.com/desandro/masonry/blob/master/jquery.masonry.js
723
724*/
725
726    $.fn.infinitescroll = function infscr_init(options, callback) {
727
728
729        var thisCall = typeof options;
730
731        switch (thisCall) {
732
733            // method
734            case 'string':
735                var args = Array.prototype.slice.call(arguments, 1);
736
737                this.each(function () {
738                    var instance = $.data(this, 'infinitescroll');
739
740                    if (!instance) {
741                        // not setup yet
742                        // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');
743                        return false;
744                    }
745
746                    if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {
747                        // return $.error('No such method ' + options + ' for Infinite Scroll');
748                        return false;
749                    }
750
751                    // no errors!
752                    instance[options].apply(instance, args);
753                });
754
755            break;
756
757            // creation
758            case 'object':
759
760                this.each(function () {
761
762                var instance = $.data(this, 'infinitescroll');
763
764                if (instance) {
765
766                    // update options of current instance
767                    instance.update(options);
768
769                } else {
770
771                    // initialize new instance
772                    instance = new $.infinitescroll(options, callback, this);
773
774                    // don't attach if instantiation failed
775                    if (!instance.failed) {
776                        $.data(this, 'infinitescroll', instance);
777                    }
778
779                }
780
781            });
782
783            break;
784
785        }
786
787        return this;
788    };
789
790
791
792    /*
793     * smartscroll: debounced scroll event for jQuery *
794     * https://github.com/lukeshumard/smartscroll
795     * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *
796     * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *
797     */
798
799    var event = $.event,
800    scrollTimeout;
801
802    event.special.smartscroll = {
803        setup: function () {
804            $(this).bind('scroll', event.special.smartscroll.handler);
805        },
806        teardown: function () {
807            $(this).unbind('scroll', event.special.smartscroll.handler);
808        },
809        handler: function (event, execAsap) {
810            // Save the context
811            var context = this,
812            args = arguments;
813
814            // set correct event type
815            event.type = 'smartscroll';
816
817            if (scrollTimeout) { clearTimeout(scrollTimeout); }
818            scrollTimeout = setTimeout(function () {
819                $(context).trigger('smartscroll', args);
820            }, execAsap === 'execAsap' ? 0 : 100);
821        }
822    };
823
824    $.fn.smartscroll = function (fn) {
vendor: 4,861 bytes, lines 825-838
825        return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']);
826    };
827
828}));/*!
829 * Isotope PACKAGED v3.0.1
830 *
831 * Licensed GPLv3 for open source use
832 * or Isotope Commercial License for commercial use
833 *
834 * http://isotope.metafizzy.co
835 * Copyright 2016 Metafizzy
836 */
837
838!function(t,e){"use strict";"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,s,a){function u(t,e,n){var o,s="$()."+i+'("'+e+'")';return t.each(function(t,u){var h=a.data(u,i);if(!h)return void r(i+" not initialized. Cannot call methods, i.e. "+s);var d=h[e];if(!d||"_"==e.charAt(0))return void r(s+" is not a valid method");var l=d.apply(h,n);o=void 0===o?l:o}),void 0!==o?o:t}function h(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new s(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(s.prototype.option||(s.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return u(this,t,e)}return h(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,s=t.console,r="undefined"==typeof s?function(){}:function(t){s.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var s=this._onceEvents&&this._onceEvents[t];o;){var r=s&&s[o];r&&(this.off(t,o),delete s[o]),o.apply(this,e),n+=r?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("get-size/get-size",[],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;h>e;e++){var i=u[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s.isBoxSizeOuter=r=200==t(o.width),i.removeChild(e)}}function s(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var s=n(e);if("none"==s.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==s.boxSizing,l=0;h>l;l++){var f=u[l],c=s[f],m=parseFloat(c);a[f]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,y=a.paddingTop+a.paddingBottom,g=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,I=a.borderTopWidth+a.borderBottomWidth,z=d&&r,x=t(s.width);x!==!1&&(a.width=x+(z?0:p+_));var S=t(s.height);return S!==!1&&(a.height=S+(z?0:y+I)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(y+I),a.outerWidth=a.width+g,a.outerHeight=a.height+v,a}}var r,a="undefined"==typeof console?e:function(t){console.error(t)},u=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],h=u.length,d=!1;return s}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["de
838sandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e},i.makeArray=function(t){var e=[];if(Array.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),s=0;s<i.length;s++)o.push(i[s])}}),o},i.debounceMethod=function(t,e,i){var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];t&&clearTimeout(t);var e=arguments,s=this;this[o]=setTimeout(function(){n.apply(s,e),delete s[o]},i||100)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?t():document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var n=t.console;return i.htmlInit=function(e,o){i.docReady(function(){var s=i.toDashed(o),r="data-"+s,a=document.querySelectorAll("["+r+"]"),u=document.querySelectorAll(".js-"+s),h=i.makeArray(a).concat(i.makeArray(u)),d=r+"-options",l=t.jQuery;h.forEach(function(t){var i,s=t.getAttribute(r)||t.getAttribute(d);try{i=s&&JSON.parse(s)}catch(a){return void(n&&n.error("Error parsing "+r+" on "+t.className+": "+a))}var u=new e(t,i);l&&l.data(t,o,u)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var s=document.documentElement.style,r="string"==typeof s.transition?"transition":"WebkitTransition",a="string"==typeof s.transform?"transform":"WebkitTransform",u={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[r],h={transform:a,transition:r,transitionDuration:r+"Duration",transitionProperty:r+"Property",transitionDelay:r+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=h[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],s=this.layout.size,r=-1!=n.indexOf("%")?parseFloat(n)/100*s.width:parseInt(n,10),a=-1!=o.indexOf("%")?parseFloat(o)/100*s.height:parseInt(o,10);r=isNaN(r)?0:r,a=isNaN(a)?0:a,r-=e?s.paddingLeft:s.paddingRight,a-=i?s.paddingTop:s.paddingBottom,this.position.x=r,this.position.y=a},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",s=i?"left":"right",r=i?"right":"left",a=this.position.x+t[o];e[s]=this.getXValue(a),e[r]="";var u=n?"paddingTop":"paddingBottom",h=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[u];e[h]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),s=parseInt(e,10),r=o===this.position.x&&s===this.position.y;if(this.setPosition(t,e),r&&!this.isTransitioning)return void this.layoutPosition();var a=t-i,u=e-n,h={};
vendor: 8,465 bytes, line 838
838h.transform=this.getTranslate(a,u),this.transition({to:h,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(u,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var f={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=f[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(u,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var c={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(c)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return r&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,s){return e(t,i,n,o,s)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function s(t,e){var i=n.getQueryElement(t);if(!i)return void(u&&u.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,h&&(this.$element=h(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,f[o]=this,this._create();var s=this._getOption("initLayout");s&&this.layout()}function r(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var u=t.console,h=t.jQuery,d=function(){},l=0,f={};s.namespace="outlayer",s.Item=o,s.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var c=s.prototype;n.extend(c,e.prototype),c.option=function(t){n.extend(this.options,t)},c._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},s.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},c._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},c.reloadItems=function(){this.items=this._itemize(this.element.children)},c._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var s=e[o],r=new i(s,this);n.push(r)}return n},c._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},c.getItemElements=function(){return this.items.map(function(t){return t.element})},c.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},c._init=c.layout,c._resetLayout=function(){this.getSize()},c.getSize=function(){this.size=i(this.element)},c._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},c.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},c._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},c._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},c._getItemLayoutPosition=function(){return{x:0,y:0}},c._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},c.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},c._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},c._postLayout=function(){this.resizeContainer()},c.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},c._getContainerSize=d,c._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},c._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){r++,r==s&&i()}var o=this,s=e.length;if(!e||!s)return void i();var r=0;e.forEach(function(e){e.once(t,n)})},c.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),h)if(this.$element=this.$element||h(this.element),e){var o=h.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},c.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},c.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},c.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.
vendor: 17,368 bytes, lines 838-861
838concat(t),t.forEach(this.ignore,this))},c.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},c._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},c._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},c._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},c._manageStamp=d,c._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),s={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return s},c.handleEvent=n.handleEvent,c.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},c.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},c.onresize=function(){this.resize()},n.debounceMethod(s,"onresize",100),c.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},c.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},c.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},c.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},c.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},c.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},c.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},c.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},c.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},c.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},c.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},c.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},c.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete f[e],delete this.element.outlayerGUID,h&&h.removeData(this.element,this.constructor.namespace)},s.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&f[e]},s.create=function(t,e){var i=r(s);return i.defaults=n.extend({},s.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},s.compatOptions),i.namespace=t,i.data=s.data,i.Item=r(o),n.htmlInit(i,t),h&&h.bridget&&h.bridget(t,i),i};var m={ms:1,s:1e3};return s.Item=o,s}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/item",["outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.Item=e(t.Outlayer))}(window,function(t){"use strict";function e(){t.Item.apply(this,arguments)}var i=e.prototype=Object.create(t.Item.prototype),n=i._create;i._create=function(){this.id=this.layout.itemGUID++,n.call(this),this.sortData={}},i.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var n=e[i];this.sortData[i]=n(this.element,this)}}};var o=i.destroy;return i.destroy=function(){o.apply(this,arguments),this.css({display:""})},e}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("get-size"),require("outlayer")):(t.Isotope=t.Isotope||{},t.Isotope.LayoutMode=e(t.getSize,t.Outlayer))}(window,function(t,e){"use strict";function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}var n=i.prototype,o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout","_getOption"];return o.forEach(function(t){n[t]=function(){return e.prototype[t].apply(this.isotope,arguments)}}),n.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;return i&&e.innerHeight!=this.isotope.size.innerHeight},n._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},n.getColumnWidth=function(){this.getSegmentSize("column","Width")},n.getRowHeight=function(){this.getSegmentSize("row","Height")},n.getSegmentSize=function(t,e){var i=t+e,n="outer"+e;if(this._getMeasurement(i,n),!this[i]){var o=this.getFirstItemSize();this[i]=o&&o[n]||this.isotope.size["inner"+e]}},n.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},n.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},n.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=Object.create(n),o.prototype.constructor=o,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}),function(t,e){"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");return i.compatOptions.fitWidth="isFitWidth",i.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0},i.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,s=o/n,r=n-o%n,a=r&&1>r?"round":"floor";s=Math[a](s),this.cols=Math.max(s,1)},i.prototype.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},i.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this._getColGroup(n),s=Math.min.apply(Math,o),r=o.indexOf(s),a={x:this.columnWidth*r,y:s},u=s+t.size.outerHeight,h=this.cols+1-o.length,d=0;h>d;d++)this.colYs[r+d]=u;return a},i.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},i.prototype._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),s=o?n.left:n.right,r=s+i.outerWidth,a=Math.floor(s/this.columnWidth);a=Math.max(0,a);var u=Math.floor(r/this.columnWidth);u-=r%this.columnWidth?0:1,u=Math.min(this.cols-1,u);for(var h=this._getOption("originTop"),d=(h?n.top:n.bottom)+i.outerHeight,l=a;u>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},i.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},i.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},i.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode"),require("masonry-layout")):e(t.Isotope.LayoutMode,t.Masonry)}(window,function(t,e){"use strict";var i=t.create("masonry"),n=i.prototype,o={_getElementOffset:!0,layout:!0,_getMeasurement:!0};for(var s in e.prototype)o[s]||(n[s]=e.prototype[s]);var r=n.measureColumns;n.measureColumns=function(){this.items=this.isotope.filteredItems,r.call(this)};var a=n._getOption;return n._getOption=function(t){return"fitWidth"==t?void 0!==this.options.isFitWidth?this.options.isFitWidth:this.options.fitWidth:a.apply(this.isotope,arguments)},i}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window,function(t){"use strict";var e=t.create("fitRows"),i=e.prototype;return i._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},i._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.isotope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var n={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,n},i._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){"function"==typeof define&&define.amd?define("isotope/js/layout-modes/vertical",["../layout-mode"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode")):e(t.Isotope.LayoutMode)}(window,function(t){"use strict";var e=t.create("vertical",{horizontalAlignment:0}),i=e.prototype;return i._resetLayout=function(){this.y=0},i._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},i._getContainerSize=function(){return{height:this.y}},e}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","desandro-matches-selector/matches-selector","fizzy-ui-utils/utils","isotope/js/item","isotope/js/layout-mode","isotope/js/layout-modes/masonry","isotope/js/layout-modes/fit-rows","isotope/js/layout-modes/vertical"],function(i,n,o,s,r,a){return e(t,i,n,o,s,r,a)}):"object"==typeof module&&module.exports?module.exports=e(t,require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("fizzy-ui-utils"),require("isotope/js/item"),require("isotope/js/layout-mode"),require("isotope/js/layout-modes/masonry"),require("isotope/js/layout-modes/fit-rows"),require("isotope/js/layout-modes/vertical")):t.Isotope=e(t,t.Outlayer,t.getSize,t.matchesSelector,t.fizzyUIUtils,t.Isotope.Item,t.Isotope.LayoutMode)}(window,function(t,e,i,n,o,s,r){function a(t,e){return function(i,n){for(var o=0;o<t.length;o++){var s=t[o],r=i.sortData[s],a=n.sortData[s];if(r>a||a>r){var u=void 0!==e[s]?e[s]:e,h=u?1:-1;return(r>a?1:-1)*h}}return 0}}var u=t.jQuery,h=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},d=e.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=s,d.LayoutMode=r;var l=d.prototype;l._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in r.modes)this._initLayoutMode(t)},l.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},l._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0;i<t.length;i++){var n=t[i];n.id=this.itemGUID++}return this._updateItemsSortData(t),t},l._initLayoutMode=function(t){var e=r.modes[t],i=this.options[t]||{};this.options[t]=e.options?o.extend(e.options,i):i,this.modes[t]=new e(this)},l.layout=function(){return!this._isLayoutInited&&this._getOption("initLayout")?void this.arrange():void this._layout()},l._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},l.arrange=function(t){this.option(t),this._getIsInstant();var e=this._filter(this.items);this.filteredItems=e.matches,this._bindArrangeComplete(),this._isInstant?this._noTransition(this._hideReveal,[e]):this._hideReveal(e),this._sort(),this._layout()},l._init=l.arrange,l._hideReveal=function(t){this.reveal(t.needReveal),this.hide(t.needHide)},l._getIsInstant=function(){var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;return this._isInstant=e,e},l._bindArrangeComplete=function(){function t(){e&&i&&n&&o.dispatchEvent("arrangeComplete",null,[o.filteredItems])}var e,i,n,o=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){n=!0,t()})},l._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],n=[],o=[],s=this._getFilterTest(e),r=0;r<t.length;r++){var a=t[r];if(!a.isIgnored){var u=s(a);u&&i.push(a),u&&a.isHidden?n.push(a):u||a.isHidden||o.push(a)}}return{matches:i,needReveal:n,needHide:o}},l._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return n(e.element,t)}},l.updateSortData=function(t){var e;t?(t=o.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},l._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=f(i)}},l._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.updateSortData()}};var f=function(){function t(t){if("string"!=typeof t)return t;var i=h(t).split(" "),n=i[0],o=n.match(/^\[(.+)\]$/),s=o&&o[1],r=e(s,n),a=d.sortDataParsers[i[1]];
839return t=a?function(t){return t&&a(r(t))}:function(t){return t&&r(t)}}function e(t,e){return t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&i.textContent}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},l._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=a(e,this.options.sortAscending);this.filteredItems.sort(i),t!=this.sortHistory[0]&&this.sortHistory.unshift(t)}},l._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw new Error("No layout mode: "+t);return e.options=this.options[t],e},l._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},l._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},l._manageStamp=function(t){this._mode()._manageStamp(t)},l._getContainerSize=function(){return this._mode()._getContainerSize()},l.needsResizeLayout=function(){return this._mode().needsResizeLayout()},l.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},l.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},l._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},l.insert=function(t){var e=this.addItems(t);if(e.length){var i,n,o=e.length;for(i=0;o>i;i++)n=e[i],this.element.appendChild(n.element);var s=this._filter(e).matches;for(i=0;o>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;o>i;i++)delete e[i].isLayoutInstant;this.reveal(s)}};var c=l.remove;return l.remove=function(t){t=o.makeArray(t);var e=this.getItems(t);c.call(this,t);for(var i=e&&e.length,n=0;i&&i>n;n++){var s=e[n];o.removeFrom(this.filteredItems,s)}},l.shuffle=function(){for(var t=0;t<this.items.length;t++){var e=this.items[t];e.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},l._noTransition=function(t,e){var i=this.options.transitionDuration;this.options.transitionDuration=0;var n=t.apply(this,e);return this.options.transitionDuration=i,n},l.getFilteredItemElements=function(){return this.filteredItems.map(function(t){return t.element})},d});$(document).ready(function() {
840
841	// this
842	
843	// calls isotope on the grid
844	
845	// sets up infinte scroll
846	
847	// watches the filter buttons to reload the bottom half of the page
848
849	$('.grid').isotope({
850    itemSelector: '.grid-item',
851    percentPosition: true,
852	  masonry: {
853	    columnWidth: '.grid-sizer'
854	  }
855  });
856
857	// https://github.com/infinite-scroll/infinite-scroll/wiki/Options
858
859  $('.grid').infinitescroll({
860    navSelector  : '#page_nav',    // selector for the paged navigation 
861    nextSelector : '#page_nav a',  // selector for the NEXT link (to page 2)
862    itemSelector : '.grid-item',     // selector for all items you'll retrieve
863    pixelsFromNavToBottom : 1000,
864    loading: {
865    	finishedMsg: "",
866    	msgText: "",
867    	img: ""
868    },
869    prefill : true,
870    debug : true,
871  },
872  // call Isotope as a callback
873  function( newElements ) {
874  	// console.log('infinite scroll callback');
875  	var $newElems = $(newElements).hide();
876  	$newElems.fadeIn();
877 		$('.grid').isotope('appended', $newElems); 
878  });
879
880
881	$(document).on('click touch', '.filter_button', function(e) {
882	  var $this = $(this);
883	  
884
885	  
886	  // get group key
887	  var $buttonGroup = $this.parents('.button-group');
888	  
889	  $buttonGroup.children('.filter_button').removeClass('active');
890	  $this.addClass('active');
891	  
892	  if ($this.hasClass('filter_button_format')) {
893	  	$('.filter_button_date').data('f', $this.data('f'));
894	  }
895	  
896		e.preventDefault();
897 		$.ajax({  
898	    type: 'GET',
899	    url: 'https://www.mdmarchive.co.uk/includes/inc_artefacts_items.php', 
900	    data: {
901	    	order : $(this).data('order'),
902	    	u : $(this).data('u'),
903	    	k : $(this).data('k'),
904	    	f : $(this).data('f'),
905	    	deep_search : $(this).data('deep_search'),
906	    },
907	    success: function(response) {
908	    
909	    
910	    	$('.grid').isotope('destroy');
911	    	
912			  $('.grid').infinitescroll('destroy');
913			  $('.grid').data('infinitescroll', null);
914			  $('.grid').infinitescroll({                      
915			    state: {                                              
916			    	isDestroyed: false,
917			      isDone: false                           
918					}
919				});
920
921	    	$('#products_response').html(response);
922	    	$('.grid').isotope({
923			    itemSelector: '.grid-item',
924			    percentPosition: true,
925				  masonry: {
926				    columnWidth: '.grid-sizer'
927				  }
928			  });
929			  
930			  
931			  $('.grid').infinitescroll({
932			    navSelector  : '#page_nav',    // selector for the paged navigation 
933			    nextSelector : '#page_nav a',  // selector for the NEXT link (to page 2)
934			    itemSelector : '.grid-item',     // selector for all items you'll retrieve
935			    pixelsFromNavToBottom : 500,
936			    loading: {
937			    	finishedMsg: "",
938			    	msgText: "",
939			    	img: ""
940			    },
941			    prefill : true,
942    			debug : true,
943			  },
944			  // call Isotope as a callback
945			  function( newElements ) {
946			  	// console.log('infinite scroll callback');
947			  	var $newElems = $(newElements).hide();
948			  	$newElems.fadeIn();
949			 		$('.grid').isotope('appended', $newElems); 
950			  });
951			  			  
952	  		// console.log('filter_response');
953			  
954			  if ($(window).width() < 768) {
955    			$('#filter_buttons').collapse('hide');
956				}
957    	
958	    }
959		});
960	});
961
962
963});/*! jQuery Validation Plugin - v1.16.0 - 12/2/2016
964 * http://jqueryvalidation.org/
965 * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */
966!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return!c.settings.submitHandler||(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element
vendor: 20,180 bytes, line 966
966(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&null!=j.form){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]);var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)a[b]&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);if("function"==typeof f.normalizer){if(i=f.normalizer.call(b,i),"string"!=typeof i)throw new TypeError("The normalizer should return a string value.");delete f.normalizer}for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=".  Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("val
966idate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});/* =============================================================
967 * bootstrap3-typeahead.js v4.0.2
968 * https://github.com/bassjobsen/Bootstrap-3-Typeahead
969 * =============================================================
970 * Original written by @mdo and @fat
971 * =============================================================
972 * Copyright 2014 Bass Jobsen @bassjobsen
973 *
974 * Licensed under the Apache License, Version 2.0 (the 'License');
975 * you may not use this file except in compliance with the License.
976 * You may obtain a copy of the License at
977 *
978 * http://www.apache.org/licenses/LICENSE-2.0
979 *
980 * Unless required by applicable law or agreed to in writing, software
981 * distributed under the License is distributed on an 'AS IS' BASIS,
982 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
983 * See the License for the specific language governing permissions and
984 * limitations under the License.
985 * ============================================================ */
986
987
988(function (root, factory) {
989
990  'use strict';
991
992  // CommonJS module is defined
993  if (typeof module !== 'undefined' && module.exports) {
994    module.exports = factory(require('jquery'));
995  }
996  // AMD module is defined
997  else if (typeof define === 'function' && define.amd) {
998    define(['jquery'], function ($) {
999      return factory ($);
1000    });
1001  } else {
1002    factory(root.jQuery);
1003  }
1004
1005}(this, function ($) {
1006
1007  'use strict';
1008  // jshint laxcomma: true
1009
1010
1011 /* TYPEAHEAD PUBLIC CLASS DEFINITION
1012  * ================================= */
1013
1014  var Typeahead = function (element, options) {
1015    this.$element = $(element);
1016    this.options = $.extend({}, Typeahead.defaults, options);
1017    this.matcher = this.options.matcher || this.matcher;
1018    this.sorter = this.options.sorter || this.sorter;
1019    this.select = this.options.select || this.select;
1020    this.autoSelect = typeof this.options.autoSelect == 'boolean' ? this.options.autoSelect : true;
1021    this.highlighter = this.options.highlighter || this.highlighter;
1022    this.render = this.options.render || this.render;
1023    this.updater = this.options.updater || this.updater;
1024    this.displayText = this.options.displayText || this.displayText;
1025    this.itemLink = this.options.itemLink || this.itemLink;
1026    this.itemTitle = this.options.itemTitle || this.itemTitle;
1027    this.followLinkOnSelect = this.options.followLinkOnSelect || this.followLinkOnSelect;
1028    this.source = this.options.source;
1029    this.delay = this.options.delay;
1030    this.theme = this.options.theme && this.options.themes && this.options.themes[this.options.theme] || Typeahead.defaults.themes[Typeahead.defaults.theme];
1031    this.$menu = $(this.options.menu || this.theme.menu);
1032    this.$appendTo = this.options.appendTo ? $(this.options.appendTo) : null;
1033    this.fitToElement = typeof this.options.fitToElement == 'boolean' ? this.options.fitToElement : false;
1034    this.shown = false;
1035    this.listen();
1036    this.showHintOnFocus = typeof this.options.showHintOnFocus == 'boolean' || this.options.showHintOnFocus === "all" ? this.options.showHintOnFocus : false;
1037    this.afterSelect = this.options.afterSelect;
1038    this.afterEmptySelect = this.options.afterEmptySelect;
1039    this.addItem = false;
1040    this.value = this.$element.val() || this.$element.text();
1041    this.keyPressed = false;
1042    this.focused = this.$element.is( ":focus" );
1043  };
1044
1045  Typeahead.prototype = {
1046
1047    constructor: Typeahead,
1048
1049
1050    setDefault: function (val) {
1051      // var val = this.$menu.find('.active').data('value');
1052      this.$element.data('active', val);
1053      if (this.autoSelect || val) {
1054        var newVal = this.updater(val);
1055        // Updater can be set to any random functions via "options" parameter in constructor above.
1056        // Add null check for cases when updater returns void or undefined.
1057        if (!newVal) {
1058          newVal = '';
1059        }
1060        this.$element
1061          .val(this.displayText(newVal) || newVal)
1062          .text(this.displayText(newVal) || newVal)
1063          .change();
1064        this.afterSelect(newVal);
1065      }
1066      return this.hide();
1067    },
1068
1069    select: function () {
1070        var val = this.$menu.find('.active').data('value');
1071
1072        this.$element.data('active', val);
1073        if (this.autoSelect || val) {
1074            var newVal = this.updater(val);
1075            // Updater can be set to any random functions via "options" parameter in constructor above.
1076            // Add null check for cases when updater returns void or undefined.
1077            if (!newVal) {
1078              newVal = '';
1079            }
1080            this.$element
1081              .val(this.displayText(newVal) || newVal)
1082              .text(this.displayText(newVal) || newVal)
1083              .change();
1084            this.afterSelect(newVal);
1085            if(this.followLinkOnSelect && this.itemLink(val)) {
1086                document.location = this.itemLink(val);
1087                this.afterSelect(newVal);
1088            } else if(this.followLinkOnSelect && !this.itemLink(val)) {
1089                this.afterEmptySelect(newVal);
1090            } else {
1091                this.afterSelect(newVal);
1092            }
1093        } else {
1094            this.afterEmptySelect(newVal);
1095        }
1096
1097        return this.hide();
1098    },
1099    
1100    
1101		/*
1102    select: function () {
1103        var newVal = '';
1104        var val = this.$menu.find('.active').data('value');
1105        if (val) {
1106            this.$element.data('active', val);
1107            newVal = this.updater(val);
1108            // Updater can be set to any random functions via "options" parameter in constructor above.
1109            // Add null check for cases when updater returns void or undefined.
1110            if (!newVal) {
1111                newVal = '';
1112            }
1113            this.$element
1114                .val(this.displayText(newVal) || newVal)
1115                .text(this.displayText(newVal) || newVal)
1116                .change();
1117        }
1118        else {
1119            newVal = this.$element.val();
1120        }
1121        this.afterSelect(newVal);
1122        return this.hide();
1123    },
1124    */
1125    
1126    
1127    
1128
1129    updater: function (item) {
1130      return item;
1131    },
1132
1133    setSource: function (source) {
1134      this.source = source;
1135    },
1136
1137    show: function () {
1138      var pos = $.extend({}, this.$element.position(), {
1139        height: this.$element[0].offsetHeight
1140      });
1141
1142      var scrollHeight = typeof this.options.scrollHeight == 'function' ?
1143          this.options.scrollHeight.call() :
1144          this.options.scrollHeight;
1145
1146      var element;
1147      if (this.shown) {
1148        element = this.$menu;
1149      } else if (this.$appendTo) {
1150        element = this.$menu.appendTo(this.$appendTo);
1151        this.hasSameParent = this.$appendTo.is(this.$element.parent());
1152      } else {
1153        element = this.$menu.insertAfter(this.$element);
1154        this.hasSameParent = true;
1155      }      
1156      
1157      if (!this.hasSameParent) {
1158          // We cannot rely on the element position, need to position relative to the window
1159          element.css("position", "fixed");
1160          var offset = this.$element.offset();
1161          pos.top =  offset.top;
1162          pos.left = offset.left;
1163      }
1164      // The rules for bootstrap are: 'dropup' in the parent and 'dropdown-menu-right' in the element.
1165      // Note that to get right alignment, you'll need to specify `menu` in the options to be:
1166      // '<ul class="typeahead dropdown-menu" role="listbox"></ul>'
1167      var dropup = $(element).parent().hasClass('dropup');
1168      var newTop = dropup ? 'auto' : (pos.top + pos.height + scrollHeight);
1169      var right = $(element).hasClass('dropdown-menu-right');
1170      var newLeft = right ? 'auto' : pos.left;
1171      // it seems like setting the css is a bad idea (just let Bootstrap do it), but I'll keep the old
1172      // logic in place except for the dropup/right-align cases.
1173      element.css({ top: newTop, left: newLeft }).show();
1174
1175      if (this.options.fitToElement === true) {
1176          element.css("width", this.$element.outerWidth() + "px");
1177      }
1178    
1179      this.shown = true;
1180      return this;
1181    },
1182
1183    hide: function () {
1184      this.$menu.hide();
1185      this.shown = false;
1186      return this;
1187    },
1188
1189    lookup: function (query) {
1190      var items;
1191      if (typeof(query) != 'undefined' && query !== null) {
1192        this.query = query;
1193      } else {
1194        this.query = this.$element.val();
1195      }
1196
1197      if (this.query.length < this.options.minLength && !this.options.showHintOnFocus) {
1198        return this.shown ? this.hide() : this;
1199      }
1200
1201      var worker = $.proxy(function () {
1202
1203        // Bloodhound (since 0.11) needs three arguments. 
1204        // Two of them are callback functions (sync and async) for local and remote data processing
1205        // see https://github.com/twitter/typeahead.js/blob/master/src/bloodhound/bloodhound.js#L132
1206        if ($.isFunction(this.source) && this.source.length === 3) {
1207          this.source(this.query, $.proxy(this.process, this), $.proxy(this.process, this));
1208        } else if ($.isFunction(this.source)) {
1209          this.source(this.query, $.proxy(this.process, this));
1210        } else if (this.source) {
1211          this.process(this.source);
1212        }
1213      }, this);
1214
1215      clearTimeout(this.lookupWorker);
1216      this.lookupWorker = setTimeout(worker, this.delay);
1217    },
1218
1219    process: function (items) {
1220      var that = this;
1221
1222      items = $.grep(items, function (item) {
1223        return that.matcher(item);
1224      });
1225
1226      items = this.sorter(items);
1227
1228      if (!items.length && !this.options.addItem) {
1229        return this.shown ? this.hide() : this;
1230      }
1231
1232      if (items.length > 0) {
1233        this.$element.data('active', items[0]);
1234      } else {
1235        this.$element.data('active', null);
1236      }
1237
1238      if (this.options.items != 'all') {
1239        items = items.slice(0, this.options.items);
1240      }
1241
1242      // Add item
1243      if (this.options.addItem){
1244        items.push(this.options.addItem);
1245      }
1246
1247      return this.render(items).show();
1248    },
1249
1250    matcher: function (item) {
1251      var it = this.displayText(item);
1252      return ~it.toLowerCase().indexOf(this.query.toLowerCase());
1253    },
1254
1255    sorter: function (items) {
1256      var beginswith = [];
1257      var caseSensitive = [];
1258      var caseInsensitive = [];
1259      var item;
1260
1261      while ((item = items.shift())) {
1262        var it = this.displayText(item);
1263        if (!it.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item);
1264        else if (~it.indexOf(this.query)) caseSensitive.push(item);
1265        else caseInsensitive.push(item);
1266      }
1267
1268      return beginswith.concat(caseSensitive, caseInsensitive);
1269    },
1270
1271    highlighter: function (item) {
1272      var text = this.query;
1273      if(text===""){
1274        return item;
1275      }
1276      var matches = item.match(/(>)([^<]*)(<)/g);
1277      var first = [];
1278      var second = [];
1279      var i;
1280      if(matches && matches.length){
1281        //html
1282        for (i = 0; i < matches.length; ++i) {
1283          if (matches[i].length > 2) {//escape '><'
1284            first.push(matches[i]);
1285          }
1286        }
1287      }else{
1288        //text
1289        first = [];
1290        first.push(item);
1291      }
1292      text = text.replace((/[\(\)\/\.\*\+\?\[\]]/g), function(mat) {
1293          return '\\' + mat;
1294      });
1295      var reg = new RegExp(text, "g");
1296      var m;
1297      for (i = 0; i < first.length; ++i) {
1298        m = first[i].match(reg);
1299        if(m && m.length>0){//find all text nodes matches
1300          second.push(first[i]);
1301        }
1302      }
1303      for (i = 0; i < second.length; ++i) {
1304        item = item.replace(second[i],second[i].replace(reg, '<strong>$&</strong>'));
1305      }
1306      return item;
1307    },
1308
1309    render: function (items) {
1310      var that = this;
1311      var self = this;
1312      var activeFound = false;
1313      var data = [];
1314      var _category = that.options.separator;
1315
1316      $.each(items, function (key,value) {
1317        // inject separator
1318        if (key > 0 && value[_category] !== items[key - 1][_category]){
1319          data.push({
1320            __type: 'divider'
1321          });
1322        }
1323
1324        // inject category header
1325        if (value[_category] && (key === 0 || value[_category] !== items[key - 1][_category])){
1326          data.push({
1327            __type: 'category',
1328            name: value[_category]
1329          });
1330        }
1331        data.push(value);
1332      });
1333
1334      items = $(data).map(function (i, item) {
1335        if ((item.__type || false) == 'category'){
1336          return $(that.options.headerHtml || that.theme.headerHtml).text(item.name)[0];
1337        }
1338
1339        if ((item.__type || false) == 'divider'){
1340          return $(that.options.headerDivider || that.theme.headerDivider)[0];
1341        }
1342
1343        var text = self.displayText(item);
1344        i = $(that.options.item || that.theme.item).data('value', item);
1345        i.find(that.options.itemContentSelector || that.theme.itemContentSelector)
1346         .addBack(that.options.itemContentSelector || that.theme.itemContentSelector)
1347         .html(that.highlighter(text, item));
1348        if(this.followLinkOnSelect) {
1349            i.find('a').attr('href', self.itemLink(item));
1350        }
1351        i.find('a').attr('title', self.itemTitle(item));
1352        if (text == self.$element.val()) {
1353          i.addClass('active');
1354          self.$element.data('active', item);
1355          activeFound = true;
1356        }
1357        return i[0];
1358      });
1359
1360      if (this.autoSelect && !activeFound) {
1361        items.filter(':not(.dropdown-header)').first().addClass('active');
1362        this.$element.data('active', items.first().data('value'));
1363      }
1364      this.$menu.html(items);
1365      return this;
1366    },
1367
1368    displayText: function (item) {
1369      return typeof item !== 'undefined' && typeof item.name != 'undefined' ? item.name : item;
1370    },
1371
1372    itemLink: function (item) {
1373      return null;
1374    },
1375
1376    itemTitle: function (item) {
1377      return null;
1378    },
1379
1380    next: function (event) {
1381      var active = this.$menu.find('.active').removeClass('active');
1382      var next = active.next();
1383
1384      if (!next.length) {
1385        next = $(this.$menu.find($(this.options.item || this.theme.item).prop('tagName'))[0]);
1386      }
1387
1388      next.addClass('active');
1389      // added for screen reader
1390      var newVal = this.updater(next.data('value'));
1391      this.$element.val(this.displayText(newVal) || newVal);
1392    },
1393
1394    prev: function (event) {
1395      var active = this.$menu.find('.active').removeClass('active');
1396      var prev = active.prev();
1397
1398      if (!prev.length) {
1399        prev = this.$menu.find($(this.options.item || this.theme.item).prop('tagName')).last();
1400      }
1401
1402      prev.addClass('active');
1403      // added for screen reader
1404      var newVal = this.updater(prev.data('value'));
1405      this.$element.val(this.displayText(newVal) || newVal);
1406    },
1407
1408    listen: function () {
1409      this.$element
1410        .on('focus.bootstrap3Typeahead',    $.proxy(this.focus, this))
1411        .on('blur.bootstrap3Typeahead',     $.proxy(this.blur, this))
1412        .on('keypress.bootstrap3Typeahead', $.proxy(this.keypress, this))
1413        .on('propertychange.bootstrap3Typeahead input.bootstrap3Typeahead',    $.proxy(this.input, this))
1414        .on('keyup.bootstrap3Typeahead',    $.proxy(this.keyup, this));
1415
1416      if (this.eventSupported('keydown')) {
1417        this.$element.on('keydown.bootstrap3Typeahead', $.proxy(this.keydown, this));
1418      }
1419
1420      var itemTagName = $(this.options.item || this.theme.item).prop('tagName')
1421      if ('ontouchstart' in document.documentElement) {
1422        this.$menu
1423          .on('touchstart', itemTagName, $.proxy(this.touchstart, this))
1424          .on('touchend', itemTagName, $.proxy(this.click, this));
1425      } else {
1426        this.$menu
1427          .on('click', $.proxy(this.click, this))
1428          .on('mouseenter', itemTagName, $.proxy(this.mouseenter, this))
1429          .on('mouseleave', itemTagName, $.proxy(this.mouseleave, this))
1430          .on('mousedown', $.proxy(this.mousedown,this));
1431      }
1432    },
1433
1434    destroy : function () {
1435      this.$element.data('typeahead',null);
1436      this.$element.data('active',null);
1437      this.$element
1438        .unbind('focus.bootstrap3Typeahead')
1439        .unbind('blur.bootstrap3Typeahead')
1440        .unbind('keypress.bootstrap3Typeahead')
1441        .unbind('propertychange.bootstrap3Typeahead input.bootstrap3Typeahead')
1442        .unbind('keyup.bootstrap3Typeahead');
1443
1444      if (this.eventSupported('keydown')) {
1445        this.$element.unbind('keydown.bootstrap3-typeahead');
1446      }
1447
1448      this.$menu.remove();
1449      this.destroyed = true;
1450    },
1451
1452    eventSupported: function (eventName) {
1453      var isSupported = eventName in this.$element;
1454      if (!isSupported) {
1455        this.$element.setAttribute(eventName, 'return;');
1456        isSupported = typeof this.$element[eventName] === 'function';
1457      }
1458      return isSupported;
1459    },
1460
1461    move: function (e) {
1462      if (!this.shown) return;
1463
1464      switch (e.keyCode) {
1465        case 9: // tab
1466        case 13: // enter
1467        case 27: // escape
1468          e.preventDefault();
1469          break;
1470
1471        case 38: // up arrow
1472          // with the shiftKey (this is actually the left parenthesis)
1473          if (e.shiftKey) return;
1474          e.preventDefault();
1475          this.prev();
1476          break;
1477
1478        case 40: // down arrow
1479          // with the shiftKey (this is actually the right parenthesis)
1480          if (e.shiftKey) return;
1481          e.preventDefault();
1482          this.next();
1483          break;
1484      }
1485    },
1486
1487    keydown: function (e) {
1488      /**
1489       * Prevent to make an ajax call while copying and pasting.
1490       *
1491       * @author Simone Sacchi
1492       * @version 2018/01/18
1493       */
1494      if (e.keyCode === 17) { // ctrl
1495        return;
1496      }
1497      this.keyPressed = true;
1498      this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]);
1499      if (!this.shown && e.keyCode == 40) {
1500        this.lookup();
1501      } else {
1502        this.move(e);
1503      }
1504    },
1505
1506    keypress: function (e) {
1507      if (this.suppressKeyPressRepeat) return;
1508      this.move(e);
1509    },
1510
1511    input: function (e) {
1512      // This is a fixed for IE10/11 that fires the input event when a placehoder is changed
1513      // (https://connect.microsoft.com/IE/feedback/details/810538/ie-11-fires-input-event-on-focus)
1514      var currentValue = this.$element.val() || this.$element.text();
1515      if (this.value !== currentValue) {
1516        this.value = currentValue;
1517        this.lookup();
1518      }
1519    },
1520
1521    keyup: function (e) {
1522      if (this.destroyed) {
1523        return;
1524      }
1525      switch (e.keyCode) {
1526        case 40: // down arrow
1527        case 38: // up arrow
1528        case 16: // shift
1529        case 17: // ctrl
1530        case 18: // alt
1531          break;
1532
1533        case 9: // tab
1534          if (!this.shown || (this.showHintOnFocus && !this.keyPressed)) return;
1535          this.select();
1536          break;
1537        case 13: // enter
1538          if (!this.shown) return;
1539          this.select();
1540          break;
1541
1542        case 27: // escape
1543          if (!this.shown) return;
1544          this.hide();
1545          break;
1546      }
1547
1548    },
1549
1550    focus: function (e) {
1551      if (!this.focused) {
1552        this.focused = true;
1553        this.keyPressed = false;
1554        if (this.options.showHintOnFocus && this.skipShowHintOnFocus !== true) {
1555          if(this.options.showHintOnFocus === "all") {
1556            this.lookup(""); 
1557          } else {
1558            this.lookup();
1559          }
1560        }
1561      }
1562      if (this.skipShowHintOnFocus) {
1563        this.skipShowHintOnFocus = false;
1564      }
1565    },
1566
1567    blur: function (e) {
1568      if (!this.mousedover && !this.mouseddown && this.shown) {
1569        this.select();
1570        this.hide();
1571        this.focused = false;
1572        this.keyPressed = false;
1573      } else if (this.mouseddown) {
1574        // This is for IE that blurs the input when user clicks on scroll.
1575        // We set the focus back on the input and prevent the lookup to occur again
1576        this.skipShowHintOnFocus = true;
1577        this.$element.focus();
1578        this.mouseddown = false;
1579      } 
1580    },
1581
1582    click: function (e) {
1583      e.preventDefault();
1584      this.skipShowHintOnFocus = true;
1585      this.select();
1586      this.$element.focus();
1587      this.hide();
1588    },
1589
1590    mouseenter: function (e) {
1591      this.mousedover = true;
1592      this.$menu.find('.active').removeClass('active');
1593      $(e.currentTarget).addClass('active');
1594    },
1595
1596    mouseleave: function (e) {
1597      this.mousedover = false;
1598      if (!this.focused && this.shown) this.hide();
1599    },
1600
1601   /**
1602     * We track the mousedown for IE. When clicking on the menu scrollbar, IE makes the input blur thus hiding the menu.
1603     */
1604    mousedown: function (e) {
1605      this.mouseddown = true;
1606      this.$menu.one("mouseup", function(e){
1607        // IE won't fire this, but FF and Chrome will so we reset our flag for them here
1608        this.mouseddown = false;
1609      }.bind(this));
1610    },
1611
1612    touchstart: function (e) {
1613      e.preventDefault();
1614      this.$menu.find('.active').removeClass('active');
1615      $(e.currentTarget).addClass('active');
1616    },
1617
1618    touchend: function (e) {
1619      e.preventDefault();
1620      this.select();
1621      this.$element.focus();
1622    }
1623
1624  };
1625
1626
1627  /* TYPEAHEAD PLUGIN DEFINITION
1628   * =========================== */
1629
1630  var old = $.fn.typeahead;
1631
1632  $.fn.typeahead = function (option) {
1633    var arg = arguments;
1634    if (typeof option == 'string' && option == 'getActive') {
1635      return this.data('active');
1636    }
1637    return this.each(function () {
1638      var $this = $(this);
1639      var data = $this.data('typeahead');
1640      var options = typeof option == 'object' && option;
1641      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)));
1642      if (typeof option == 'string' && data[option]) {
1643        if (arg.length > 1) {
1644          data[option].apply(data, Array.prototype.slice.call(arg, 1));
1645        } else {
1646          data[option]();
1647        }
1648      }
1649    });
1650  };
1651
1652  Typeahead.defaults = {
1653    source: [],
1654    items: 8,
1655    minLength: 1,
1656    scrollHeight: 0,
1657    autoSelect: true,
1658    afterSelect: $.noop,
1659    afterEmptySelect: $.noop,
1660    addItem: false,
1661    followLinkOnSelect: false,
1662    delay: 0,
1663    separator: 'category',
1664    theme: "bootstrap3",
1665    themes: {
1666      bootstrap3: {
1667        menu: '<ul class="typeahead dropdown-menu" role="listbox"></ul>',
1668        item: '<li><a class="dropdown-item" href="#" role="option"></a></li>',
1669        itemContentSelector: "a",
1670        headerHtml: '<li class="dropdown-header"></li>',
1671        headerDivider: '<li class="divider" role="separator"></li>'
1672      },     
1673      bootstrap4: {
1674        menu: '<div class="typeahead dropdown-menu" role="listbox"></div>',
1675        item: '<button class="dropdown-item" role="option"></button>',
1676        itemContentSelector: '.dropdown-item',
1677        headerHtml: '<h6 class="dropdown-header"></h6>',
1678        headerDivider: '<div class="dropdown-divider"></div>'
1679      } 
1680    }
1681  };
1682
1683  $.fn.typeahead.Constructor = Typeahead;
1684
1685 /* TYPEAHEAD NO CONFLICT
1686  * =================== */
1687
1688  $.fn.typeahead.noConflict = function () {
1689    $.fn.typeahead = old;
1690    return this;
1691  };
1692
1693
1694 /* TYPEAHEAD DATA-API
1695  * ================== */
1696
1697  $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
1698    var $this = $(this);
1699    if ($this.data('typeahead')) return;
1700    $this.typeahead($this.data());
1701  });
1702
1703}));$(document).ready(function() {
1704
1705	$(".typeahead_keywords_nav").typeahead({
1706		autoSelect: false,
1707		fitToElement: true,
1708		source:  function (query, process) {
1709			return $.get('https://www.mdmarchive.co.uk/proc/proc_keyword_lookup_nav.php', { query: query }, function (data) {
1710				console.log(data);
1711				data = $.parseJSON(data);
1712				return process(data);
1713			});
1714		},
1715		updater : function(item) {
1716			console.log(item);
1717			$(".typeahead_keywords_nav").val(item['name']);
1718			$("#header_search_id").val(item['id']);
1719			$("#header_search_type").val(item['type']);
1720			$(".typeahead_keywords_nav").closest("form").submit();
1721		},
1722	  matcher: function (item) {
1723	    return true;
1724	  }
1725	});
1726
1727});/*!
1728 * Cropper.js v1.0.0
1729 * https://github.com/fengyuanchen/cropperjs
1730 *
1731 * Copyright (c) 2017 Fengyuan Chen
1732 * Released under the MIT license
1733 *
1734 * Date: 2017-09-03T12:52:44.102Z
1735 */
1736
1737!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Cropper=e()}(this,function(){"use strict";function t(t){return ot.call(t).slice(8,-1).toLowerCase()}function e(t){return"number"==typeof t&&!isNaN(t)}function a(t){return void 0===t}function i(t){return"object"===(void 0===t?"undefined":Z(t))&&null!==t}function o(t){if(!i(t))return!1;try{var e=t.constructor,a=e.prototype;return e&&a&&nt.call(a,"isPrototypeOf")}catch(t){return!1}}function n(e){return"function"===t(e)}function r(e){return Array.isArray?Array.isArray(e):"array"===t(e)}function h(t){return"string"==typeof t&&(t=t.trim?t.trim():t.replace(_,"$1")),t}function c(t,a){if(t&&n(a)){var o=void 0;if(r(t)||e(t.length)){var h=t.length;for(o=0;o<h&&!1!==a.call(t,t[o],o,t);o+=1);}else i(t)&&Object.keys(t).forEach(function(e){a.call(t,t[e],e,t)})}return t}function s(t){for(var e=arguments.length,a=Array(e>1?e-1:0),o=1;o<e;o++)a[o-1]=arguments[o];if(i(t)&&a.length>0){if(Object.assign)return Object.assign.apply(Object,[t].concat(a));a.forEach(function(e){i(e)&&Object.keys(e).forEach(function(a){t[a]=e[a]})})}return t}function l(t,e){for(var a=arguments.length,i=Array(a>2?a-2:0),o=2;o<a;o++)i[o-2]=arguments[o];return function(){for(var a=arguments.length,o=Array(a),n=0;n<a;n++)o[n]=arguments[n];return t.apply(e,i.concat(o))}}function d(t,a){var i=t.style;c(a,function(t,a){J.test(a)&&e(t)&&(t+="px"),i[a]=t})}function p(t,e){return t.classList?t.classList.contains(e):t.className.indexOf(e)>-1}function u(t,a){if(a)if(e(t.length))c(t,function(t){u(t,a)});else if(t.classList)t.classList.add(a);else{var i=h(t.className);i?i.indexOf(a)<0&&(t.className=i+" "+a):t.className=a}}function m(t,a){a&&(e(t.length)?c(t,function(t){m(t,a)}):t.classList?t.classList.remove(a):t.className.indexOf(a)>=0&&(t.className=t.className.replace(a,"")))}function g(t,a,i){a&&(e(t.length)?c(t,function(t){g(t,a,i)}):i?u(t,a):m(t,a))}function f(t){return t.replace(V,"$1-$2").toLowerCase()}function v(t,e){return i(t[e])?t[e]:t.dataset?t.dataset[e]:t.getAttribute("data-"+f(e))}function w(t,e,a){i(a)?t[e]=a:t.dataset?t.dataset[e]=a:t.setAttribute("data-"+f(e),a)}function b(t,e){if(i(t[e]))delete t[e];else if(t.dataset)try{delete t.dataset[e]}catch(a){t.dataset[e]=null}else t.removeAttribute("data-"+f(e))}function x(t,e,a){var i=h(e).split(G);i.length>1?c(i,function(e){x(t,e,a)}):t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent&&t.detachEvent("on"+e,a)}function y(t,e,a,i){var o=h(e).split(G),n=a;o.length>1?c(o,function(e){y(t,e,a)}):(i&&(a=function(){for(var i=arguments.length,o=Array(i),r=0;r<i;r++)o[r]=arguments[r];return x(t,e,a),n.apply(t,o)}),t.addEventListener?t.addEventListener(e,a,!1):t.attachEvent&&t.attachEvent("on"+e,a))}function M(t,e,i){if(t.dispatchEvent){var o=void 0;return n(Event)&&n(CustomEvent)?o=a(i)?new Event(e,{bubbles:!0,cancelable:!0}):new CustomEvent(e,{detail:i,bubbles:!0,cancelable:!0}):a(i)?(o=document.createEvent("Event")).initEvent(e,!0,!0):(o=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i),t.dispatchEvent(o)}return!t.fireEvent||t.fireEvent("on"+e)}function C(t){var a=t||window.event;if(a.target||(a.target=a.srcElement||document),!e(a.pageX)&&e(a.clientX)){var i=t.target.ownerDocument||document,o=i.documentElement,n=i.body;a.pageX=a.clientX+((o&&o.scrollLeft||n&&n.scrollLeft||0)-(o&&o.clientLeft||n&&n.clientLeft||0)),a.pageY=a.clientY+((o&&o.scrollTop||n&&n.scrollTop||0)-(o&&o.clientTop||n&&n.clientTop||0))}return a}function D(t){var e=document.documentElement,a=t.getBoundingClientRect();return{left:a.left+((window.scrollX||e&&e.scrollLeft||0)-(e&&e.clientLeft||0)),top:a.top+((window.scrollY||e&&e.scrollTop||0)-(e&&e.clientTop||0))}}function B(t,e){return t.getElementsByTagName(e)}function k(t,e){return t.getElementsByClassName?t.getElementsByClassName(e):t.querySelectorAll("."+e)}function T(t){return document.createElement(t)}function L(t,e){t.appendChild(e)}function W(t){t.parentNode&&t.parentNode.removeChild(t)}function E(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function H(t){var e=t.match(F);return e&&(e[1]!==location.protocol||e[2]!==location.hostname||e[3]!==location.port)}function X(t){var e="timestamp="+(new Date).getTime();return t+(-1===t.indexOf("?")?"?":"&")+e}
1737function Y(t,e){if(!t.naturalWidth||at){var a=T("img");a.onload=function(){e(this.width,this.height)},a.src=t.src}else e(t.naturalWidth,t.naturalHeight)}function N(t){var a=[],i=t.translateX,o=t.translateY,n=t.rotate,r=t.scaleX,h=t.scaleY;e(i)&&0!==i&&a.push("translateX("+i+"px)"),e(o)&&0!==o&&a.push("translateY("+o+"px)"),e(n)&&0!==n&&a.push("rotate("+n+"deg)"),e(r)&&1!==r&&a.push("scaleX("+r+")"),e(h)&&1!==h&&a.push("scaleY("+h+")");var c=a.length?a.join(" "):"none";return{WebkitTransform:c,msTransform:c,transform:c}}function O(t,e){var a=Math.abs(t.degree)%180,i=(a>90?180-a:a)*Math.PI/180,o=Math.sin(i),n=Math.cos(i),r=t.width,h=t.height,c=t.aspectRatio,s=void 0,l=void 0;return e?l=(s=r/(n+o/c))/c:(s=r*n+h*o,l=r*o+h*n),{width:s,height:l}}function S(t,a,i){var o=T("canvas"),n=o.getContext("2d"),r=0,h=0,c=a.naturalWidth,s=a.naturalHeight,l=a.rotate,d=a.scaleX,p=a.scaleY,u=e(d)&&e(p)&&(1!==d||1!==p),m=e(l)&&0!==l,g=m||u,f=c*Math.abs(d||1),v=s*Math.abs(p||1),w=void 0,b=void 0,x=void 0;return u&&(w=f/2,b=v/2),m&&(w=(f=(x=O({width:f,height:v,degree:l})).width)/2,b=(v=x.height)/2),o.width=f,o.height=v,i.fillColor&&(n.fillStyle=i.fillColor,n.fillRect(0,0,f,v)),g&&(r=-c/2,h=-s/2,n.save(),n.translate(w,b)),m&&n.rotate(l*Math.PI/180),u&&n.scale(d,p),n.imageSmoothingEnabled=!!i.imageSmoothingEnabled,i.imageSmoothingQuality&&(n.imageSmoothingQuality=i.imageSmoothingQuality),n.drawImage(t,Math.floor(r),Math.floor(h),Math.floor(c),Math.floor(s)),g&&n.restore(),o}function z(t,e,a){var i="",o=e;for(a+=e;o<a;o+=1)i+=rt(t.getUint8(o));return i}function R(t){var e=new DataView(t),a=e.byteLength,i=void 0,o=void 0,n=void 0,r=void 0,h=void 0,c=void 0,s=void 0,l=void 0,d=void 0;if(255===e.getUint8(0)&&216===e.getUint8(1))for(l=2;l<a;){if(255===e.getUint8(l)&&225===e.getUint8(l+1)){c=l;break}l+=1}if(c&&(o=c+10,"Exif"===z(e,c+4,4)&&((r=18761===(h=e.getUint16(o)))||19789===h)&&42===e.getUint16(o+2,r)&&(n=e.getUint32(o+4,r))>=8&&(s=o+n)),s)for(a=e.getUint16(s,r),d=0;d<a;d+=1)if(l=s+12*d+2,274===e.getUint16(l,r)){l+=8,i=e.getUint16(l,r),at&&e.setUint16(l,1,r);break}return i}function A(t){var e=t.replace(K,""),a=atob(e),i=a.length,o=new ArrayBuffer(i),n=new Uint8Array(o),r=void 0;for(r=0;r<i;r+=1)n[r]=a.charCodeAt(r);return o}function I(t){var e=new Uint8Array(t),a=e.length,i="",o=void 0;for(o=0;o<a;o+=1)i+=rt(e[o]);return"data:image/jpeg;base64,"+btoa(i)}function U(t,e){var a=t.pageX,i=t.pageY,o={endX:a,endY:i};return e?o:s({startX:a,startY:i},o)}function j(t){var e=s({},t),a=[];return c(t,function(t,i){delete e[i],c(e,function(e){var i=Math.abs(t.startX-e.startX),o=Math.abs(t.startY-e.startY),n=Math.abs(t.endX-e.endX),r=Math.abs(t.endY-e.endY),h=Math.sqrt(i*i+o*o),c=(Math.sqrt(n*n+r*r)-h)/h;a.push(c)})}),a.sort(function(t,e){return Math.abs(t)<Math.abs(e)}),a[0]}function P(t){if(Array.isArray(t)){for(var e=0,a=Array(t.length);e<t.length;e++)a[e]=t[e];return a}return Array.from(t)}function q(t){var e=0,a=0,i=0;return c(t,function(t){var o=t.startX,n=t.startY;e+=o,a+=n,i+=1}),e/=i,a/=i,{pageX:e,pageY:a}}function Q(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var $={viewMode:0,dragMode:"crop",aspectRatio:NaN,data:null,preview:"",responsive:!0,restore:!0,checkCrossOrigin:!0,checkOrientation:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,wheelZoomRatio:.1,cropBoxMovable:!0,cropBoxResizable:!0,toggleDragModeOnDblclick:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,ready:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},Z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},K=/^data:.*,/,V=/([a-z\d])([A-Z])/g,F=/^(https?:)\/\/([^:/?#]+):?(\d*)/i,G=/\s+/,J=/^(width|height|left|top|marginLeft|marginTop)$/,_=/^\s+(.*)\s+$/,tt=/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i,et="undefined"!=typeof window?window.navigator:null,at=et&&tt.test(et.userAgent),it=Object.prototype,ot=it.toString,nt=it.hasOwnProperty,rt=String.fromCharCode,ht={render:function(){var t=this;t.initContainer(),t.initCanvas(),t.initCropBox(),t.renderCanvas(),t.cropped&&t.renderCropBox()},initContainer:function(){var t=this,e=t.options,a=t.element,i=t.container,o=t.cropper,n="cropper-hidden";u(o,n),m(a,n);var r={width:Math.max(i.offsetWidth,Number(e.minContainerWidth)||200),height:Math.max(i.offsetHeight,Number(e.minContainerHeight)||100)};t.containerData=r,d(o,{width:r.width,height:r.height}),u(a,n),m(o,n)}
1737,initCanvas:function(){var t=this,e=t.options.viewMode,a=t.containerData,i=t.imageData,o=Math.abs(i.rotate)%180==90,n=o?i.naturalHeight:i.naturalWidth,r=o?i.naturalWidth:i.naturalHeight,h=n/r,c=a.width,l=a.height;a.height*h>a.width?3===e?c=a.height*h:l=a.width/h:3===e?l=a.width/h:c=a.height*h;var d={naturalWidth:n,naturalHeight:r,aspectRatio:h,width:c,height:l};d.left=(a.width-c)/2,d.top=(a.height-l)/2,d.oldLeft=d.left,d.oldTop=d.top,t.canvasData=d,t.limited=1===e||2===e,t.limitCanvas(!0,!0),t.initialImageData=s({},i),t.initialCanvasData=s({},d)},limitCanvas:function(t,e){var a=this,i=a.options,o=i.viewMode,n=a.containerData,r=a.canvasData,h=r.aspectRatio,c=a.cropBoxData,s=a.cropped&&c;if(t){var l=Number(i.minCanvasWidth)||0,d=Number(i.minCanvasHeight)||0;o>1?(l=Math.max(l,n.width),d=Math.max(d,n.height),3===o&&(d*h>l?l=d*h:d=l/h)):o>0&&(l?l=Math.max(l,s?c.width:0):d?d=Math.max(d,s?c.height:0):s&&(l=c.width,(d=c.height)*h>l?l=d*h:d=l/h)),l&&d?d*h>l?d=l/h:l=d*h:l?d=l/h:d&&(l=d*h),r.minWidth=l,r.minHeight=d,r.maxWidth=1/0,r.maxHeight=1/0}if(e)if(o){var p=n.width-r.width,u=n.height-r.height;r.minLeft=Math.min(0,p),r.minTop=Math.min(0,u),r.maxLeft=Math.max(0,p),r.maxTop=Math.max(0,u),s&&a.limited&&(r.minLeft=Math.min(c.left,c.left+(c.width-r.width)),r.minTop=Math.min(c.top,c.top+(c.height-r.height)),r.maxLeft=c.left,r.maxTop=c.top,2===o&&(r.width>=n.width&&(r.minLeft=Math.min(0,p),r.maxLeft=Math.max(0,p)),r.height>=n.height&&(r.minTop=Math.min(0,u),r.maxTop=Math.max(0,u))))}else r.minLeft=-r.width,r.minTop=-r.height,r.maxLeft=n.width,r.maxTop=n.height},renderCanvas:function(t){var e=this,a=e.canvasData,i=e.imageData,o=i.rotate;if(e.rotated){e.rotated=!1;var n=O({width:i.width,height:i.height,degree:o}),r=n.width/n.height,h=1===i.aspectRatio;if(h||r!==a.aspectRatio){if(a.left-=(n.width-a.width)/2,a.top-=(n.height-a.height)/2,a.width=n.width,a.height=n.height,a.aspectRatio=r,a.naturalWidth=i.naturalWidth,a.naturalHeight=i.naturalHeight,h&&o%90||o%180){var c=O({width:i.naturalWidth,height:i.naturalHeight,degree:o});a.naturalWidth=c.width,a.naturalHeight=c.height}e.limitCanvas(!0,!1)}}(a.width>a.maxWidth||a.width<a.minWidth)&&(a.left=a.oldLeft),(a.height>a.maxHeight||a.height<a.minHeight)&&(a.top=a.oldTop),a.width=Math.min(Math.max(a.width,a.minWidth),a.maxWidth),a.height=Math.min(Math.max(a.height,a.minHeight),a.maxHeight),e.limitCanvas(!1,!0),a.left=Math.min(Math.max(a.left,a.minLeft),a.maxLeft),a.top=Math.min(Math.max(a.top,a.minTop),a.maxTop),a.oldLeft=a.left,a.oldTop=a.top,d(e.canvas,s({width:a.width,height:a.height},N({translateX:a.left,translateY:a.top}))),e.renderImage(),e.cropped&&e.limited&&e.limitCropBox(!0,!0),t&&e.output()},renderImage:function(t){var e=this,a=e.canvasData,i=e.imageData,o=void 0,n=void 0,r=void 0,h=void 0;i.rotate&&(o={width:r=(n=O({width:a.width,height:a.height,degree:i.rotate,aspectRatio:i.aspectRatio},!0)).width,height:h=n.height,left:(a.width-r)/2,top:(a.height-h)/2}),s(i,o||{width:a.width,height:a.height,left:0,top:0}),d(e.image,s({width:i.width,height:i.height},N(s({translateX:i.left,translateY:i.top},i)))),t&&e.output()},initCropBox:function(){var t=this,e=t.options,a=e.aspectRatio,i=Number(e.autoCropArea)||.8,o=t.canvasData,n={width:o.width,height:o.height};a&&(o.height*a>o.width?n.height=n.width/a:n.width=n.height*a),t.cropBoxData=n,t.limitCropBox(!0,!0),n.width=Math.min(Math.max(n.width,n.minWidth),n.maxWidth),n.height=Math.min(Math.max(n.height,n.minHeight),n.maxHeight),n.width=Math.max(n.minWidth,n.width*i),n.height=Math.max(n.minHeight,n.height*i),n.left=o.left+(o.width-n.width)/2,n.top=o.top+(o.height-n.height)/2,n.oldLeft=n.left,n.oldTop=n.top,t.initialCropBoxData=s({},n)},limitCropBox:function(t,e){var a=this,i=a.options,o=i.aspectRatio,n=a.containerData,r=a.canvasData,h=a.cropBoxData,c=a.limited;if(t){var s=Number(i.minCropBoxWidth)||0,l=Number(i.minCropBoxHeight)||0,d=Math.min(n.width,c?r.width:n.width),p=Math.min(n.height,c?r.height:n.height);s=Math.min(s,n.width),l=Math.min(l,n.height),o&&(s&&l?l*o>s?l=s/o:s=l*o:s?l=s/o:l&&(s=l*o),p*o>d?p=d/o:d=p*o),h.minWidth=Math.min(s,d),h.minHeight=Math.min(l,p),h.maxWidth=d,h.maxHeight=p}e&&(c?(h.minLeft=Math.max(0,r.left),h.minTop=Math.max(0,r.top),h.maxLeft=Math.min(n.width,r.left+r.
1737width)-h.width,h.maxTop=Math.min(n.height,r.top+r.height)-h.height):(h.minLeft=0,h.minTop=0,h.maxLeft=n.width-h.width,h.maxTop=n.height-h.height))},renderCropBox:function(){var t=this,e=t.options,a=t.containerData,i=t.cropBoxData;(i.width>i.maxWidth||i.width<i.minWidth)&&(i.left=i.oldLeft),(i.height>i.maxHeight||i.height<i.minHeight)&&(i.top=i.oldTop),i.width=Math.min(Math.max(i.width,i.minWidth),i.maxWidth),i.height=Math.min(Math.max(i.height,i.minHeight),i.maxHeight),t.limitCropBox(!1,!0),i.left=Math.min(Math.max(i.left,i.minLeft),i.maxLeft),i.top=Math.min(Math.max(i.top,i.minTop),i.maxTop),i.oldLeft=i.left,i.oldTop=i.top,e.movable&&e.cropBoxMovable&&w(t.face,"action",i.width===a.width&&i.height===a.height?"move":"all"),d(t.cropBox,s({width:i.width,height:i.height},N({translateX:i.left,translateY:i.top}))),t.cropped&&t.limited&&t.limitCanvas(!0,!0),t.disabled||t.output()},output:function(){var t=this;t.preview(),t.complete&&M(t.element,"crop",t.getData())}},ct={initPreview:function(){var t=this,e=t.options.preview,a=T("img"),i=t.crossOrigin,o=i?t.crossOriginUrl:t.url;if(i&&(a.crossOrigin=i),a.src=o,L(t.viewBox,a),t.image2=a,e){var n=e.querySelector?[e]:document.querySelectorAll(e);t.previews=n,c(n,function(t){var e=T("img");w(t,"preview",{width:t.offsetWidth,height:t.offsetHeight,html:t.innerHTML}),i&&(e.crossOrigin=i),e.src=o,e.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',E(t),L(t,e)})}},resetPreview:function(){c(this.previews,function(t){var e=v(t,"preview");d(t,{width:e.width,height:e.height}),t.innerHTML=e.html,b(t,"preview")})},preview:function(){var t=this,e=t.imageData,a=t.canvasData,i=t.cropBoxData,o=i.width,n=i.height,r=e.width,h=e.height,l=i.left-a.left-e.left,p=i.top-a.top-e.top;t.cropped&&!t.disabled&&(d(t.image2,s({width:r,height:h},N(s({translateX:-l,translateY:-p},e)))),c(t.previews,function(t){var a=v(t,"preview"),i=a.width,c=a.height,u=i,m=c,g=1;o&&(m=n*(g=i/o)),n&&m>c&&(u=o*(g=c/n),m=c),d(t,{width:u,height:m}),d(B(t,"img")[0],s({width:r*g,height:h*g},N(s({translateX:-l*g,translateY:-p*g},e))))}))}},st="undefined"!=typeof window?window.PointerEvent:null,lt=st?"pointerdown":"touchstart mousedown",dt=st?"pointermove":"touchmove mousemove",pt=st?" pointerup pointercancel":"touchend touchcancel mouseup",ut={bind:function(){var t=this,e=t.options,a=t.element,i=t.cropper;n(e.cropstart)&&y(a,"cropstart",e.cropstart),n(e.cropmove)&&y(a,"cropmove",e.cropmove),n(e.cropend)&&y(a,"cropend",e.cropend),n(e.crop)&&y(a,"crop",e.crop),n(e.zoom)&&y(a,"zoom",e.zoom),y(i,lt,t.onCropStart=l(t.cropStart,t)),e.zoomable&&e.zoomOnWheel&&y(i,"wheel mousewheel DOMMouseScroll",t.onWheel=l(t.wheel,t)),e.toggleDragModeOnDblclick&&y(i,"dblclick",t.onDblclick=l(t.dblclick,t)),y(document,dt,t.onCropMove=l(t.cropMove,t)),y(document,pt,t.onCropEnd=l(t.cropEnd,t)),e.responsive&&y(window,"resize",t.onResize=l(t.resize,t))},unbind:function(){var t=this,e=t.options,a=t.element,i=t.cropper;n(e.cropstart)&&x(a,"cropstart",e.cropstart),n(e.cropmove)&&x(a,"cropmove",e.cropmove),n(e.cropend)&&x(a,"cropend",e.cropend),n(e.crop)&&x(a,"crop",e.crop),n(e.zoom)&&x(a,"zoom",e.zoom),x(i,lt,t.onCropStart),e.zoomable&&e.zoomOnWheel&&x(i,"wheel mousewheel DOMMouseScroll",t.onWheel),e.toggleDragModeOnDblclick&&x(i,"dblclick",t.onDblclick),x(document,dt,t.onCropMove),x(document,pt,t.onCropEnd),e.responsive&&x(window,"resize",t.onResize)}},mt=/^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/,gt={resize:function(){var t=this,e=t.options,a=t.container,i=t.containerData,o=Number(e.minContainerWidth)||200,n=Number(e.minContainerHeight)||100;if(!t.disabled&&i.width!==o&&i.height!==n){var r=a.offsetWidth/i.width;if(1!==r||a.offsetHeight!==i.height){var h=void 0,s=void 0;e.restore&&(h=t.getCanvasData(),s=t.getCropBoxData()),t.render(),e.restore&&(t.setCanvasData(c(h,function(t,e){h[e]=t*r})),t.setCropBoxData(c(s,function(t,e){s[e]=t*r})))}}},dblclick:function(){var t=this;t.disabled||"none"===t.options.dragMode||t.setDragMode(p(t.dragBox,"cropper-crop")?"move":"crop")},wheel:function(t){var e=this,a=C(t),i=Number(e.options.wheelZoomRatio)||.1,o=1;e.disabled||(a.preventDefault(),e.wheeling||(e.wheeling=!0,setTimeout(function(){e.wheeling=!1},50),a.deltaY?o=a.deltaY>0?1:-1:a.wheelDelta?o=-a.wheelDelta/120:a.detail&&(o=a.detail>0?1:-1),e.zoom(-o*i,a)))},cropStart:function(t){var e=this;if(!e.disabled){var a=e.options,i=e.pointers,o=C(t),n=void 0;o.changedTouches?c(o.changedTouches,function(t){i[t.identifier]=U(t)}):i[o.pointerId||0]=U(o),n=Object.keys(i).length>1&&a.zoomable&&a.zoomOnTouch?"zoom":v(o.target,"action"),mt.test(n)&&!1!==M(e.element,"cropstart",{originalEvent:o,action:n})&&(o.preventDefault(),e.action=n,e.cropping=!1,"crop"===n&&(e.cropping=!0,u(e.dragBox,"cropper-modal")))}},cropMove:function(t){var e=this,a=e.action;if(!e.disabled&&a){var i=e.pointers,o=C(t);o.preventDefault(),!1!==M(e.element,"cropmove",{originalEvent:o,action:a})&&(o.changedTouches?c(o.changedTouches,function(t){s(i[t.identifier],U(t,!0))}):s(i[o.pointerId||0],U(o,!0)),e.change(o))}},cropEnd:function(t){var e=this;if(!e.disabled){var a=e.action,i=e.pointers,o=C(t);o.changedTouches?c(o.changedTouches,function(t){delete i[t.identifier]}):delete i[o.pointerId||0],a&&(o.preventDefault(),Object.keys(i).length||(e.action=""),e.cropping&&(e.cropping=!1,g(e.dragBox,"cropper-modal",e.cropped&&this.options.modal)),M(e.element,"cropend",{originalEvent:o,action:a}))}}},ft={change:function(t){var e=this,a=e.options,i=e.containerData,o=e.canvasData,n=e.cropBoxData,r=a.aspectRatio,h=e.action,s=n.width,l=n.height,d=n.left,p=n.top,u=d+s,g=p+l,f=0,v=0,w=i.width,b=i.height,x=!0,y=void 0;!r&&t.shiftKey&&(r=s&&l?s/l:1),e.limited&&(f=n.minLeft,v=n.minTop,w=f+Math.min(i.width,o.width,o.left+o.width),b=v+Math.min(i.height,o.height,o.top+o.height));var M=e.pointers,C=M[Object.keys(M)[0]],B={x:C.endX-C.startX,y:C.endY-C.startY};switch(h){case"all":d+=B.x,p+=B.y;break;case"e":if(B.x>=0&&(u>=w||r&&(p<=v||g>=b))){x=!1;break}u+B.x>w&&(B.x=w-u),s+=B.x,r&&(l=s/r,p-=B.x/r/2),s<0&&(h="w",s=0);break;case"n":if(B.y<=0&&(p<=v||r&&(d<=f||u>=w))){x=!1;break}p+B.y<v&&(B.y=v-p),l-=B.y,p+=B.y,r&&(s=l*r,d+=B.y*r/2),l<0&&(h="s",l=0);break;case"w":if(B.x<=0&&(d<=f||r&&(p<=v||g>=b))){x=!1;break}d+B.x<f&&(B.x=f-d),s-=B.x,d+=B.x,r&&(l=s/r,p+=B.x/r/2),s<0&&(h="e",s=0);break;case"s":if(B.y>=0&&(g>=b||r&&(d<=f||u>=w))){x=!1;break}g+B.y>b&&(B.y=b-g),l+=B.y,r&&(s=l*r,d-=B.y*r/2),l<0&&(h="n",l=0);break;case"ne":if(r){if(B.y<=0&&(p<=v||u>=w)){x=!1;break}l-=B.y,p+=B.y,s=l*r}else B.x>=0?u<w?s+=B.x:B.y<=0&&p<=v&&(x=!1):s+=B.x,B.y<=0?p>v&&(l-=B.y,p+=B.y):(l-=B.y,p+=B.y);s<0&&l<0?(h="sw",l=0,s=0):s<0?(h="nw",s=0):l<0&&(h="se",l=0);break;case"nw":if(r){if(B.y<=0&&(p<=v||d<=f)){x=!1;break}l-=B.y,p+=B.y,s=l*r,d+=B.y*r}else B.x<=0?d>f?(s-=B.x,d+=B.x):B.y<=0&&p<=v&&(x=!1):(s-=B.x,d+=B.x),B.y<=0?p>v&&(l-=B.y,p+=B.y):(l-=B.y,p+=B.y);s<0&&l<0?(h="se",l=0,s=0):s<0?(h="ne",s=0):l<0&&(h="sw",l=0);break;case"sw":if(r){if(B.x<=0&&(d<=f||g>=b)){x=!1;break}s-=B.x,d+=B.x,l=s/r}else B.x<=0?d>f?(s-=B.x,d+=B.x):B.y>=0&&g>=b&&(x=!1):(s-=B.x,d+=B.x),B.y>=0?g<b&&(l+=B.y):l+=B.y;s<0&&l<0?(h="ne",l=0,s=0):s<0?(h="se",s=0):l<0&&(h="nw",l=0);break;case"se":if(r){if(B.x>=0&&(u>=w||g>=b)){x=!1;break}l=(s+=B.x)/r}else B.x>=0?u<w?s+=B.x:B.y>=0&&g>=b&&(x=!1):s+=B.x,B.y>=0?g<b&&(l+=B.y):l+=B.y;s<0&&l<0?(h="nw",l=0,s=0):s<0?(h="sw",s=0):l<0&&(h="ne",l=0);break;case"move":e.move(B.x,B.y),x=!1;break;case"zoom":e.zoom(j(M),t),x=!1;break;case"crop":if(!B.x||!B.y){x=!1;break}y=D(e.cropper),d=C.startX-y.left,p=C.startY-y.top,s=n.minWidth,l=n.minHeight,B.x>0?h=B.y>0?"se":"ne":B.x<0&&(d-=s,h=B.y>0?"sw":"nw"),B.y<0&&(p-=l),e.cropped||(m(e.cropBox,"cropper-hidden"),e.cropped=!0,e.limited&&e.limitCropBox(!0,!0))}x&&(n.width=s,n.height=l,n.left=d,n.top=p,e.action=h,e.renderCropBox()),c(M,function(t){t.startX=t.endX,t.startY=t.endY})}},vt={crop:function(){var t=this;return t.ready&&!t.disabled&&(t.cropped||(t.cropped=!0,t.limitCropBox(!0,!0),t.options.modal&&u(t.dragBox,"cropper-modal"),m(t.cropBox,"cropper-hidden")),t.setCropBoxData(t.initialCropBoxData)),t},reset:function(){var t=this;return t.ready&&!t.disabled&&(t.imageData=s({},t.initialImageData),t.canvasData=s({},t.initialCanvasData),t.cropBoxData=s({},t.initialCropBoxData),t.renderCanvas(),t.cropped&&t.renderCropBox()),t},clear:function(){var t=this;return t.cropped&&!t.disabled&&(s(t.cropBoxData,{left:0,top:0,width:0,height:0}),t.cropped=!1,t.renderCropBox(),t.limitCanvas(!0,!0),t.renderCanvas(),m(t.dragBox,"cropper-modal"),u(t.cropBox,"cropper-hidden")),t},replace:function(t,e){var a=this;return!a.disabled&&t&&(a.isImg&&(a.element.src=t),e?(a.url=t,a.image.src=t,a.ready&&(a.image2.src=t,c(a.previews,function(e){B(e,"img")[0].src=t}))):(a.isImg&&(a.replaced=!0),a.options.data=null,a.load(t))),a},enable:function(){var t=this;return t.ready&&(t.disabled=!1,m(t.cropper,"cropper-disabled")),t},disable:function(){var t=this;return t.ready&&(t.disabled=!0,u(t.cropper,"cropper-disabled")),t},destroy:function(){var t=this,e=t.element,a=t.image;return t.loaded?(t.isImg&&t.replaced&&(e.src=t.originalUrl),t.unbuild(),m(e,"cropper-hidden")):t.isImg?x(e,"load",t.onStart):a&&W(a),b(e,"cropper"),t},move:function(t,e){var i=this,o=i.canvasData;return i.moveTo(a(t)?t:o.left+Number(t),a(e)?e:o.top+Number(e))},moveTo:function(t,i){var o=this,n=o.canvasData,r=!1;return a(i)&&(i=t),t=Number(t),i=Number(i),o.ready&&!o.disabled&&o.options.movable&&(e(t)&&(n.left
1737=t,r=!0),e(i)&&(n.top=i,r=!0),r&&o.renderCanvas(!0)),o},zoom:function(t,e){var a=this,i=a.canvasData;return t=Number(t),t=t<0?1/(1-t):1+t,a.zoomTo(i.width*t/i.naturalWidth,e)},zoomTo:function(t,e){var a=this,i=a.options,o=a.canvasData,n=o.width,r=o.height,h=o.naturalWidth,c=o.naturalHeight;if((t=Number(t))>=0&&a.ready&&!a.disabled&&i.zoomable){var s=h*t,l=c*t;if(!1===M(a.element,"zoom",{originalEvent:e,oldRatio:n/h,ratio:s/h}))return a;if(e){var d=a.pointers,p=D(a.cropper),u=d&&Object.keys(d).length?q(d):{pageX:e.pageX,pageY:e.pageY};o.left-=(s-n)*((u.pageX-p.left-o.left)/n),o.top-=(l-r)*((u.pageY-p.top-o.top)/r)}else o.left-=(s-n)/2,o.top-=(l-r)/2;o.width=s,o.height=l,a.renderCanvas(!0)}return a},rotate:function(t){var e=this;return e.rotateTo((e.imageData.rotate||0)+Number(t))},rotateTo:function(t){var a=this;return t=Number(t),e(t)&&a.ready&&!a.disabled&&a.options.rotatable&&(a.imageData.rotate=t%360,a.rotated=!0,a.renderCanvas(!0)),a},scale:function(t,i){var o=this,n=o.imageData,r=!1;return a(i)&&(i=t),t=Number(t),i=Number(i),o.ready&&!o.disabled&&o.options.scalable&&(e(t)&&(n.scaleX=t,r=!0),e(i)&&(n.scaleY=i,r=!0),r&&o.renderImage(!0)),o},scaleX:function(t){var a=this,i=a.imageData.scaleY;return a.scale(t,e(i)?i:1)},scaleY:function(t){var a=this,i=a.imageData.scaleX;return a.scale(e(i)?i:1,t)},getData:function(t){var e=this,a=e.options,i=e.imageData,o=e.canvasData,n=e.cropBoxData,r=void 0,h=void 0;return e.ready&&e.cropped?(h={x:n.left-o.left,y:n.top-o.top,width:n.width,height:n.height},r=i.width/i.naturalWidth,c(h,function(e,a){e/=r,h[a]=t?Math.round(e):e})):h={x:0,y:0,width:0,height:0},a.rotatable&&(h.rotate=i.rotate||0),a.scalable&&(h.scaleX=i.scaleX||1,h.scaleY=i.scaleY||1),h},setData:function(t){var a=this,i=a.options,r=a.imageData,h=a.canvasData,c={},s=void 0,l=void 0,d=void 0;return n(t)&&(t=t.call(a.element)),a.ready&&!a.disabled&&o(t)&&(i.rotatable&&e(t.rotate)&&t.rotate!==r.rotate&&(r.rotate=t.rotate,s=!0,a.rotated=s),i.scalable&&(e(t.scaleX)&&t.scaleX!==r.scaleX&&(r.scaleX=t.scaleX,l=!0),e(t.scaleY)&&t.scaleY!==r.scaleY&&(r.scaleY=t.scaleY,l=!0)),s?a.renderCanvas():l&&a.renderImage(),d=r.width/r.naturalWidth,e(t.x)&&(c.left=t.x*d+h.left),e(t.y)&&(c.top=t.y*d+h.top),e(t.width)&&(c.width=t.width*d),e(t.height)&&(c.height=t.height*d),a.setCropBoxData(c)),a},getContainerData:function(){var t=this;return t.ready?t.containerData:{}},getImageData:function(){var t=this;return t.loaded?t.imageData:{}},getCanvasData:function(){var t=this,e=t.canvasData,a={};return t.ready&&c(["left","top","width","height","naturalWidth","naturalHeight"],function(t){a[t]=e[t]}),a},setCanvasData:function(t){var a=this,i=a.canvasData,r=i.aspectRatio;return n(t)&&(t=t.call(a.element)),a.ready&&!a.disabled&&o(t)&&(e(t.left)&&(i.left
1737=t.left),e(t.top)&&(i.top=t.top),e(t.width)?(i.width=t.width,i.height=t.width/r):e(t.height)&&(i.height=t.height,i.width=t.height*r),a.renderCanvas(!0)),a},getCropBoxData:function(){var t=this,e=t.cropBoxData,a=void 0;return t.ready&&t.cropped&&(a={left:e.left,top:e.top,width:e.width,height:e.height}),a||{}},setCropBoxData:function(t){var a=this,i=a.cropBoxData,r=a.options.aspectRatio,h=void 0,c=void 0;return n(t)&&(t=t.call(a.element)),a.ready&&a.cropped&&!a.disabled&&o(t)&&(e(t.left)&&(i.left=t.left),e(t.top)&&(i.top=t.top),e(t.width)&&t.width!==i.width&&(h=!0,i.width=t.width),e(t.height)&&t.height!==i.height&&(c=!0,i.height=t.height),r&&(h?i.height=i.width/r:c&&(i.width=i.height*r)),a.renderCropBox()),a},getCroppedCanvas:function(t){var e=this;if(!e.ready||!window.HTMLCanvasElement)return null;if(o(t)||(t={}),!e.cropped)return S(e.image,e.imageData,t);var a=e.getData(),i=a.width,n=a.height,r=i/n,h=void 0,c=void 0,s=void 0;o(t)&&(h=t.width,c=t.height,h?(c=h/r,s=h/i):c&&(h=c*r,s=c/n));var l=Math.floor(h||i),d=Math.floor(c||n),p=T("canvas"),u=p.getContext("2d");p.width=l,p.height=d,t.fillColor&&(u.fillStyle=t.fillColor,u.fillRect(0,0,l,d));var m=function(){var o=S(e.image,e.imageData,t),r=o.width,h=o.height,c=e.canvasData,l=[o],d=a.x+c.naturalWidth*(Math.abs(a.scaleX||1)-1)/2,p=a.y+c.naturalHeight*(Math.abs(a.scaleY||1)-1)/2,u=void 0,m=void 0,g=void 0,f=void 0,v=void 0,w=void 0;return d<=-i||d>r?(d=0,u=0,g=0,v=0):d<=0?(g=-d,d=0,v=u=Math.min(r,i+d)):d<=r&&(g=0,v=u=Math.min(i,r-d)),u<=0||p<=-n||p>h?(p=0,m=0,f=0,w=0):p<=0?(f=-p,p=0,w=m=Math.min(h,n+p)):p<=h&&(f=0,w=m=Math.min(n,h-p)),l.push(Math.floor(d),Math.floor(p),Math.floor(u),Math.floor(m)),s&&(g*=s,f*=s,v*=s,w*=s),v>0&&w>0&&l.push(Math.floor(g),Math.floor(f),Math.floor(v),Math.floor(w)),l}();return u.imageSmoothingEnabled=!!t.imageSmoothingEnabled,t.imageSmoothingQuality&&(u.imageSmoothingQuality=t.imageSmoothingQuality),u.drawImage.apply(u,P(m)),p},setAspectRatio:function(t){var e=this,i=e.options;return e.disabled||a(t)||(i.aspectRatio=Math.max(0,t)||NaN,e.ready&&(e.initCropBox(),e.cropped&&e.renderCropBox())),e},setDragMode:function(t){var e=this,a=e.options,i=e.dragBox,o=e.face,n=void 0,r=void 0;return e.loaded&&!e.disabled&&(n="crop"===t,r=a.movable&&"move"===t,w(i,"action",t=n||r?t:"none"),g(i,"cropper-crop",n),g(i,"cropper-move",r),a.cropBoxMovable||(w(o,"action",t),g(o,"cropper-crop",n),g(o,"cropper-move",r))),e}},wt=function(){function t(t,e){for(var a=0;a<e.length;a++){var i=e[a];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,a,i){return a&&t(e.prototype,a),i&&t(e,i),e}}(),bt=/^data:/,xt=/^data:image\/jpeg;base64,/,yt=void 0,Mt=function(){function t(e,a){Q(this,t);var i=this;i.element=e,i.options=s({},$,o(a)&&a),i.loaded=!1,i.ready=!1,i.complete=!1,i.rotated=!1,i.cropped=!1,i.disabled=!1,i.replaced=!1,i.limited=!1,i.wheeling=!1,i.isImg=!1,i.originalUrl="",i.canvasData=null,i.cropBoxData=null,i.previews=null,i.pointers={},i.init()}return wt(t,[{key:"init",value:function(){var t=this,e=t.element,a=e.tagName.toLowerCase(),i=void 0;if(!v(e,"cropper")){if(w(e,"cropper",t),"img"===a){if(t.isImg=!0,i=e.getAttribute("src"),t.originalUrl=i,!i)return;i=e.src}else"canvas"===a&&window.HTMLCanvasElement&&(i=e.toDataURL());t.load(i)}}},{key:"load",value:function(t){var e=this,a=e.options,i=e.element;if(t)if(e.url=t,e.imageData={},a.checkOrientation&&window.ArrayBuffer)if(bt.test(t))xt.test(t)?e.read(A(t)):e.clone();else{var o=new XMLHttpRequest;o.onerror=function(){e.clone()},o.onload=function(){e.read(o.response)},a.checkCrossOrigin&&H(t)&&i.crossOrigin&&(t=X(t)),o.open("get",t),o.responseType="arraybuffer",o.withCredentials="use-credentials"===i.crossOrigin,o.send()}else e.clone()}},{key:"read",value:function(t){var e=this,a=e.options,i=R(t),o=e.imageData,n=0,r=1,h=1;if(i>1)switch(e.url=I(t),i){case 2:r=-1;break;case 3:n=-180;break;case 4:h=-1;break;case 5:n=90,h=-1;break;case 6:n=90;break;case 7:n=90,r=-1;break;case 8:n=-90}a.rotatable&&(o.rotate=n),a.scalable&&(o.scaleX=r,o.scaleY=h),e.clone()}},{key:"clone",value:function(){var t=this,e=t.element,a=t.url,i=void 0,o=void 0;t.options.checkCrossOrigin&&H(a)&&((i=e.crossOrigin)?o=a:(i="anonymous",o=X(a))),t.crossOrigin=i,t.crossOriginUrl=o;var n=T("img");i&&(n.crossOrigin=i),n.src=o||a;var r=l(t.start,t),h=l(t.stop,t);t.image=n,t.onStart=r,t.onStop=h,t.isImg?e.complete?t.start():y(e,"load",r):(y(n,"load",r),y(n,"error",h),u(n,"cropper-hide"),e.parentNode.insertBefore(n,e.nextSibling))}},{key:"start",value:function(t){var e=this,a=e.isImg?e.element:e.image;t&&(x(a,"load",e.onStart),x(a,"error",e.onStop)),Y(a,function(t,a){s(e.imageData,{naturalWi
1737dth:t,naturalHeight:a,aspectRatio:t/a}),e.loaded=!0,e.build()})}},{key:"stop",value:function(){var t=this,e=t.image;x(e,"load",t.onStart),x(e,"error",t.onStop),W(e),t.image=null}},{key:"build",value:function(){var t=this,e=t.options,a=t.element,i=t.image;if(t.loaded){t.ready&&t.unbuild();var o=a.parentNode,r=T("div");r.innerHTML='<div class="cropper-container"><div class="cropper-wrap-box"><div class="cropper-canvas"></div></div><div class="cropper-drag-box"></div><div class="cropper-crop-box"><span class="cropper-view-box"></span><span class="cropper-dashed dashed-h"></span><span class="cropper-dashed dashed-v"></span><span class="cropper-center"></span><span class="cropper-face"></span><span class="cropper-line line-e" data-action="e"></span><span class="cropper-line line-n" data-action="n"></span><span class="cropper-line line-w" data-action="w"></span><span class="cropper-line line-s" data-action="s"></span><span class="cropper-point point-e" data-action="e"></span><span class="cropper-point point-n" data-action="n"></span><span class="cropper-point point-w" data-action="w"></span><span class="cropper-point point-s" data-action="s"></span><span class="cropper-point point-ne" data-action="ne"></span><span class="cropper-point point-nw" data-action="nw"></span><span class="cropper-point point-sw" data-action="sw"></span><span class="cropper-point point-se" data-action="se"></span></div></div>';var h=k(r,"cropper-container")[0],c=k(h,"cropper-canvas")[0],s=k(h,"cropper-drag-box")[0],l=k(h,"cropper-crop-box")[0],d=k(l,"cropper-face")[0];t.container=o,t.cropper=h,t.canvas=c,t.dragBox=s,t.cropBox=l,t.viewBox=k(h,"cropper-view-box")[0],t.face=d,L(c,i),u(a,"cropper-hidden"),o.insertBefore(h,a.nextSibling),t.isImg||m(i,"cropper-hide"),t.initPreview(),t.bind(),e.aspectRatio=Math.max(0,e.aspectRatio)||NaN,e.viewMode=Math.max(0,Math.min(3,Math.round(e.viewMode)))||0,t.cropped=e.autoCrop,e.autoCrop?e.modal&&u(s,"cropper-modal"):u(l,"cropper-hidden"),e.guides||u(k(l,"cropper-dashed"),"cropper-hidden"),e.center||u(k(l,"cropper-center"),"cropper-hidden"),e.background&&u(h,"cropper-bg"),e.highlight||u(d,"cropper-invisible"),e.cropBoxMovable&&(u(d,"cropper-move"),w(d,"action","all")),e.cropBoxResizable||(u(k(l,"cropper-line"),"cropper-hidden"),u(k(l,"cropper-point"),"cropper-hidden")),t.setDragMode(e.dragMode),t.render(),t.ready=!0,t.setData(e.data),t.completing=setTimeout(function(){n(e.ready)&&y(a,"ready",e.ready,!0),M(a,"ready"),M(a,"crop",t.getData()),t.complete=!0},0)}}},{key:"unbuild",value:function(){var t=this;t.ready&&(t.complete||clearTimeout(t.completing),t.ready=!1,t.complete=!1,t.initialImageData=null,t.initialCanvasData=null,t.initialCropBoxData=null,t.containerData=null,t.canvasData=null,t.cropBoxData=null,t.unbind(),t.resetPreview(),t.previews=null,t.viewBox=null,t.cropBox=null,t.dragBox=null,t.canvas=null,t.container=null,W(t.cropper),t.cropper=null)}}],[{key:"noConflict",value:function(){return window.Cropper=yt,t}},{key:"setDefaults",value:function(t){s($,o(t)&&t)}}]),t}();return s(Mt.prototype,ht),s(Mt.prototype,ct),s(Mt.prototype,ut),s(Mt.prototype,gt),s(Mt.prototype,ft),s(Mt.prototype,vt),"undefined"!=typeof window&&(yt=window.Cropper,window.Cropper=Mt),Mt});(function() {
1738
1739    var debug = false;
1740
1741    var root = this;
1742
1743    var EXIF = function(obj) {
1744        if (obj instanceof EXIF) return obj;
1745        if (!(this instanceof EXIF)) return new EXIF(obj);
1746        this.EXIFwrapped = obj;
1747    };
1748
1749    if (typeof exports !== 'undefined') {
1750        if (typeof module !== 'undefined' && module.exports) {
1751            exports = module.exports = EXIF;
1752        }
1753        exports.EXIF = EXIF;
1754    } else {
1755        root.EXIF = EXIF;
1756    }
1757
1758    var ExifTags = EXIF.Tags = {
1759
1760        // version tags
1761        0x9000 : "ExifVersion",             // EXIF version
1762        0xA000 : "FlashpixVersion",         // Flashpix format version
1763
1764        // colorspace tags
1765        0xA001 : "ColorSpace",              // Color space information tag
1766
1767        // image configuration
1768        0xA002 : "PixelXDimension",         // Valid width of meaningful image
1769        0xA003 : "PixelYDimension",         // Valid height of meaningful image
1770        0x9101 : "ComponentsConfiguration", // Information about channels
1771        0x9102 : "CompressedBitsPerPixel",  // Compressed bits per pixel
1772
1773        // user information
1774        0x927C : "MakerNote",               // Any desired information written by the manufacturer
1775        0x9286 : "UserComment",             // Comments by user
1776
1777        // related file
1778        0xA004 : "RelatedSoundFile",        // Name of related sound file
1779
1780        // date and time
1781        0x9003 : "DateTimeOriginal",        // Date and time when the original image was generated
1782        0x9004 : "DateTimeDigitized",       // Date and time when the image was stored digitally
1783        0x9290 : "SubsecTime",              // Fractions of seconds for DateTime
vendor: 12,277 bytes, lines 1784-2086
1784        0x9291 : "SubsecTimeOriginal",      // Fractions of seconds for DateTimeOriginal
1785        0x9292 : "SubsecTimeDigitized",     // Fractions of seconds for DateTimeDigitized
1786
1787        // picture-taking conditions
1788        0x829A : "ExposureTime",            // Exposure time (in seconds)
1789        0x829D : "FNumber",                 // F number
1790        0x8822 : "ExposureProgram",         // Exposure program
1791        0x8824 : "SpectralSensitivity",     // Spectral sensitivity
1792        0x8827 : "ISOSpeedRatings",         // ISO speed rating
1793        0x8828 : "OECF",                    // Optoelectric conversion factor
1794        0x9201 : "ShutterSpeedValue",       // Shutter speed
1795        0x9202 : "ApertureValue",           // Lens aperture
1796        0x9203 : "BrightnessValue",         // Value of brightness
1797        0x9204 : "ExposureBias",            // Exposure bias
1798        0x9205 : "MaxApertureValue",        // Smallest F number of lens
1799        0x9206 : "SubjectDistance",         // Distance to subject in meters
1800        0x9207 : "MeteringMode",            // Metering mode
1801        0x9208 : "LightSource",             // Kind of light source
1802        0x9209 : "Flash",                   // Flash status
1803        0x9214 : "SubjectArea",             // Location and area of main subject
1804        0x920A : "FocalLength",             // Focal length of the lens in mm
1805        0xA20B : "FlashEnergy",             // Strobe energy in BCPS
1806        0xA20C : "SpatialFrequencyResponse",    //
1807        0xA20E : "FocalPlaneXResolution",   // Number of pixels in width direction per FocalPlaneResolutionUnit
1808        0xA20F : "FocalPlaneYResolution",   // Number of pixels in height direction per FocalPlaneResolutionUnit
1809        0xA210 : "FocalPlaneResolutionUnit",    // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
1810        0xA214 : "SubjectLocation",         // Location of subject in image
1811        0xA215 : "ExposureIndex",           // Exposure index selected on camera
1812        0xA217 : "SensingMethod",           // Image sensor type
1813        0xA300 : "FileSource",              // Image source (3 == DSC)
1814        0xA301 : "SceneType",               // Scene type (1 == directly photographed)
1815        0xA302 : "CFAPattern",              // Color filter array geometric pattern
1816        0xA401 : "CustomRendered",          // Special processing
1817        0xA402 : "ExposureMode",            // Exposure mode
1818        0xA403 : "WhiteBalance",            // 1 = auto white balance, 2 = manual
1819        0xA404 : "DigitalZoomRation",       // Digital zoom ratio
1820        0xA405 : "FocalLengthIn35mmFilm",   // Equivalent foacl length assuming 35mm film camera (in mm)
1821        0xA406 : "SceneCaptureType",        // Type of scene
1822        0xA407 : "GainControl",             // Degree of overall image gain adjustment
1823        0xA408 : "Contrast",                // Direction of contrast processing applied by camera
1824        0xA409 : "Saturation",              // Direction of saturation processing applied by camera
1825        0xA40A : "Sharpness",               // Direction of sharpness processing applied by camera
1826        0xA40B : "DeviceSettingDescription",    //
1827        0xA40C : "SubjectDistanceRange",    // Distance to subject
1828
1829        // other tags
1830        0xA005 : "InteroperabilityIFDPointer",
1831        0xA420 : "ImageUniqueID"            // Identifier assigned uniquely to each image
1832    };
1833
1834    var TiffTags = EXIF.TiffTags = {
1835        0x0100 : "ImageWidth",
1836        0x0101 : "ImageHeight",
1837        0x8769 : "ExifIFDPointer",
1838        0x8825 : "GPSInfoIFDPointer",
1839        0xA005 : "InteroperabilityIFDPointer",
1840        0x0102 : "BitsPerSample",
1841        0x0103 : "Compression",
1842        0x0106 : "PhotometricInterpretation",
1843        0x0112 : "Orientation",
1844        0x0115 : "SamplesPerPixel",
1845        0x011C : "PlanarConfiguration",
1846        0x0212 : "YCbCrSubSampling",
1847        0x0213 : "YCbCrPositioning",
1848        0x011A : "XResolution",
1849        0x011B : "YResolution",
1850        0x0128 : "ResolutionUnit",
1851        0x0111 : "StripOffsets",
1852        0x0116 : "RowsPerStrip",
1853        0x0117 : "StripByteCounts",
1854        0x0201 : "JPEGInterchangeFormat",
1855        0x0202 : "JPEGInterchangeFormatLength",
1856        0x012D : "TransferFunction",
1857        0x013E : "WhitePoint",
1858        0x013F : "PrimaryChromaticities",
1859        0x0211 : "YCbCrCoefficients",
1860        0x0214 : "ReferenceBlackWhite",
1861        0x0132 : "DateTime",
1862        0x010E : "ImageDescription",
1863        0x010F : "Make",
1864        0x0110 : "Model",
1865        0x0131 : "Software",
1866        0x013B : "Artist",
1867        0x8298 : "Copyright"
1868    };
1869
1870    var GPSTags = EXIF.GPSTags = {
1871        0x0000 : "GPSVersionID",
1872        0x0001 : "GPSLatitudeRef",
1873        0x0002 : "GPSLatitude",
1874        0x0003 : "GPSLongitudeRef",
1875        0x0004 : "GPSLongitude",
1876        0x0005 : "GPSAltitudeRef",
1877        0x0006 : "GPSAltitude",
1878        0x0007 : "GPSTimeStamp",
1879        0x0008 : "GPSSatellites",
1880        0x0009 : "GPSStatus",
1881        0x000A : "GPSMeasureMode",
1882        0x000B : "GPSDOP",
1883        0x000C : "GPSSpeedRef",
1884        0x000D : "GPSSpeed",
1885        0x000E : "GPSTrackRef",
1886        0x000F : "GPSTrack",
1887        0x0010 : "GPSImgDirectionRef",
1888        0x0011 : "GPSImgDirection",
1889        0x0012 : "GPSMapDatum",
1890        0x0013 : "GPSDestLatitudeRef",
1891        0x0014 : "GPSDestLatitude",
1892        0x0015 : "GPSDestLongitudeRef",
1893        0x0016 : "GPSDestLongitude",
1894        0x0017 : "GPSDestBearingRef",
1895        0x0018 : "GPSDestBearing",
1896        0x0019 : "GPSDestDistanceRef",
1897        0x001A : "GPSDestDistance",
1898        0x001B : "GPSProcessingMethod",
1899        0x001C : "GPSAreaInformation",
1900        0x001D : "GPSDateStamp",
1901        0x001E : "GPSDifferential"
1902    };
1903
1904     // EXIF 2.3 Spec
1905    var IFD1Tags = EXIF.IFD1Tags = {
1906        0x0100: "ImageWidth",
1907        0x0101: "ImageHeight",
1908        0x0102: "BitsPerSample",
1909        0x0103: "Compression",
1910        0x0106: "PhotometricInterpretation",
1911        0x0111: "StripOffsets",
1912        0x0112: "Orientation",
1913        0x0115: "SamplesPerPixel",
1914        0x0116: "RowsPerStrip",
1915        0x0117: "StripByteCounts",
1916        0x011A: "XResolution",
1917        0x011B: "YResolution",
1918        0x011C: "PlanarConfiguration",
1919        0x0128: "ResolutionUnit",
1920        0x0201: "JpegIFOffset",    // When image format is JPEG, this value show offset to JPEG data stored.(aka "ThumbnailOffset" or "JPEGInterchangeFormat")
1921        0x0202: "JpegIFByteCount", // When image format is JPEG, this value shows data size of JPEG image (aka "ThumbnailLength" or "JPEGInterchangeFormatLength")
1922        0x0211: "YCbCrCoefficients",
1923        0x0212: "YCbCrSubSampling",
1924        0x0213: "YCbCrPositioning",
1925        0x0214: "ReferenceBlackWhite"
1926    };
1927
1928    var StringValues = EXIF.StringValues = {
1929        ExposureProgram : {
1930            0 : "Not defined",
1931            1 : "Manual",
1932            2 : "Normal program",
1933            3 : "Aperture priority",
1934            4 : "Shutter priority",
1935            5 : "Creative program",
1936            6 : "Action program",
1937            7 : "Portrait mode",
1938            8 : "Landscape mode"
1939        },
1940        MeteringMode : {
1941            0 : "Unknown",
1942            1 : "Average",
1943            2 : "CenterWeightedAverage",
1944            3 : "Spot",
1945            4 : "MultiSpot",
1946            5 : "Pattern",
1947            6 : "Partial",
1948            255 : "Other"
1949        },
1950        LightSource : {
1951            0 : "Unknown",
1952            1 : "Daylight",
1953            2 : "Fluorescent",
1954            3 : "Tungsten (incandescent light)",
1955            4 : "Flash",
1956            9 : "Fine weather",
1957            10 : "Cloudy weather",
1958            11 : "Shade",
1959            12 : "Daylight fluorescent (D 5700 - 7100K)",
1960            13 : "Day white fluorescent (N 4600 - 5400K)",
1961            14 : "Cool white fluorescent (W 3900 - 4500K)",
1962            15 : "White fluorescent (WW 3200 - 3700K)",
1963            17 : "Standard light A",
1964            18 : "Standard light B",
1965            19 : "Standard light C",
1966            20 : "D55",
1967            21 : "D65",
1968            22 : "D75",
1969            23 : "D50",
1970            24 : "ISO studio tungsten",
1971            255 : "Other"
1972        },
1973        Flash : {
1974            0x0000 : "Flash did not fire",
1975            0x0001 : "Flash fired",
1976            0x0005 : "Strobe return light not detected",
1977            0x0007 : "Strobe return light detected",
1978            0x0009 : "Flash fired, compulsory flash mode",
1979            0x000D : "Flash fired, compulsory flash mode, return light not detected",
1980            0x000F : "Flash fired, compulsory flash mode, return light detected",
1981            0x0010 : "Flash did not fire, compulsory flash mode",
1982            0x0018 : "Flash did not fire, auto mode",
1983            0x0019 : "Flash fired, auto mode",
1984            0x001D : "Flash fired, auto mode, return light not detected",
1985            0x001F : "Flash fired, auto mode, return light detected",
1986            0x0020 : "No flash function",
1987            0x0041 : "Flash fired, red-eye reduction mode",
1988            0x0045 : "Flash fired, red-eye reduction mode, return light not detected",
1989            0x0047 : "Flash fired, red-eye reduction mode, return light detected",
1990            0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",
1991            0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
1992            0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
1993            0x0059 : "Flash fired, auto mode, red-eye reduction mode",
1994            0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",
1995            0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode"
1996        },
1997        SensingMethod : {
1998            1 : "Not defined",
1999            2 : "One-chip color area sensor",
2000            3 : "Two-chip color area sensor",
2001            4 : "Three-chip color area sensor",
2002            5 : "Color sequential area sensor",
2003            7 : "Trilinear sensor",
2004            8 : "Color sequential linear sensor"
2005        },
2006        SceneCaptureType : {
2007            0 : "Standard",
2008            1 : "Landscape",
2009            2 : "Portrait",
2010            3 : "Night scene"
2011        },
2012        SceneType : {
2013            1 : "Directly photographed"
2014        },
2015        CustomRendered : {
2016            0 : "Normal process",
2017            1 : "Custom process"
2018        },
2019        WhiteBalance : {
2020            0 : "Auto white balance",
2021            1 : "Manual white balance"
2022        },
2023        GainControl : {
2024            0 : "None",
2025            1 : "Low gain up",
2026            2 : "High gain up",
2027            3 : "Low gain down",
2028            4 : "High gain down"
2029        },
2030        Contrast : {
2031            0 : "Normal",
2032            1 : "Soft",
2033            2 : "Hard"
2034        },
2035        Saturation : {
2036            0 : "Normal",
2037            1 : "Low saturation",
2038            2 : "High saturation"
2039        },
2040        Sharpness : {
2041            0 : "Normal",
2042            1 : "Soft",
2043            2 : "Hard"
2044        },
2045        SubjectDistanceRange : {
2046            0 : "Unknown",
2047            1 : "Macro",
2048            2 : "Close view",
2049            3 : "Distant view"
2050        },
2051        FileSource : {
2052            3 : "DSC"
2053        },
2054
2055        Components : {
2056            0 : "",
2057            1 : "Y",
2058            2 : "Cb",
2059            3 : "Cr",
2060            4 : "R",
2061            5 : "G",
2062            6 : "B"
2063        }
2064    };
2065
2066    function addEvent(element, event, handler) {
2067        if (element.addEventListener) {
2068            element.addEventListener(event, handler, false);
2069        } else if (element.attachEvent) {
2070            element.attachEvent("on" + event, handler);
2071        }
2072    }
2073
2074    function imageHasData(img) {
2075        return !!(img.exifdata);
2076    }
2077
2078
2079    function base64ToArrayBuffer(base64, contentType) {
2080        contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
2081        base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
2082        var binary = atob(base64);
2083        var len = binary.length;
2084        var buffer = new ArrayBuffer(len);
2085        var view = new Uint8Array(buffer);
2086        for (var i = 0; i < len; i++) {
2087            view[i] = binary.charCodeAt(i);
2088        }
2089        return buffer;
2090    }
2091
2092    function objectURLToBlob(url, callback) {
2093        var http = new XMLHttpRequest();
2094        http.open("GET", url, true);
2095        http.responseType = "blob";
2096        http.onload = function(e) {
2097            if (this.status == 200 || this.status === 0) {
2098                callback(this.response);
2099            }
2100        };
2101        http.send();
2102    }
2103
2104    function getImageData(img, callback) {
2105        function handleBinaryFile(binFile) {
2106            var data = findEXIFinJPEG(binFile);
2107            var iptcdata = findIPTCinJPEG(binFile);
2108            var xmpdata= findXMPinJPEG(binFile);
2109            img.exifdata = data || {};
2110            img.iptcdata = iptcdata || {};
2111            img.xmpdata = xmpdata || {};
vendor: 20,746 bytes, lines 2111-2627
2111
2112            if (callback) {
2113                callback.call(img);
2114            }
2115        }
2116
2117        if (img.src) {
2118            if (/^data\:/i.test(img.src)) { // Data URI
2119                var arrayBuffer = base64ToArrayBuffer(img.src);
2120                handleBinaryFile(arrayBuffer);
2121
2122            } else if (/^blob\:/i.test(img.src)) { // Object URL
2123                var fileReader = new FileReader();
2124                fileReader.onload = function(e) {
2125                    handleBinaryFile(e.target.result);
2126                };
2127                objectURLToBlob(img.src, function (blob) {
2128                    fileReader.readAsArrayBuffer(blob);
2129                });
2130            } else {
2131                var http = new XMLHttpRequest();
2132                http.onload = function() {
2133                    if (this.status == 200 || this.status === 0) {
2134                        handleBinaryFile(http.response);
2135                    } else {
2136                        throw "Could not load image";
2137                    }
2138                    http = null;
2139                };
2140                http.open("GET", img.src, true);
2141                http.responseType = "arraybuffer";
2142                http.send(null);
2143            }
2144        } else if (self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
2145            var fileReader = new FileReader();
2146            fileReader.onload = function(e) {
2147                if (debug) console.log("Got file of length " + e.target.result.byteLength);
2148                handleBinaryFile(e.target.result);
2149            };
2150
2151            fileReader.readAsArrayBuffer(img);
2152        }
2153    }
2154
2155    function findEXIFinJPEG(file) {
2156        var dataView = new DataView(file);
2157
2158        if (debug) console.log("Got file of length " + file.byteLength);
2159        if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
2160            if (debug) console.log("Not a valid JPEG");
2161            return false; // not a valid jpeg
2162        }
2163
2164        var offset = 2,
2165            length = file.byteLength,
2166            marker;
2167
2168        while (offset < length) {
2169            if (dataView.getUint8(offset) != 0xFF) {
2170                if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset));
2171                return false; // not a valid marker, something is wrong
2172            }
2173
2174            marker = dataView.getUint8(offset + 1);
2175            if (debug) console.log(marker);
2176
2177            // we could implement handling for other markers here,
2178            // but we're only looking for 0xFFE1 for EXIF data
2179
2180            if (marker == 225) {
2181                if (debug) console.log("Found 0xFFE1 marker");
2182
2183                return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
2184
2185                // offset += 2 + file.getShortAt(offset+2, true);
2186
2187            } else {
2188                offset += 2 + dataView.getUint16(offset+2);
2189            }
2190
2191        }
2192
2193    }
2194
2195    function findIPTCinJPEG(file) {
2196        var dataView = new DataView(file);
2197
2198        if (debug) console.log("Got file of length " + file.byteLength);
2199        if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
2200            if (debug) console.log("Not a valid JPEG");
2201            return false; // not a valid jpeg
2202        }
2203
2204        var offset = 2,
2205            length = file.byteLength;
2206
2207
2208        var isFieldSegmentStart = function(dataView, offset){
2209            return (
2210                dataView.getUint8(offset) === 0x38 &&
2211                dataView.getUint8(offset+1) === 0x42 &&
2212                dataView.getUint8(offset+2) === 0x49 &&
2213                dataView.getUint8(offset+3) === 0x4D &&
2214                dataView.getUint8(offset+4) === 0x04 &&
2215                dataView.getUint8(offset+5) === 0x04
2216            );
2217        };
2218
2219        while (offset < length) {
2220
2221            if ( isFieldSegmentStart(dataView, offset )){
2222
2223                // Get the length of the name header (which is padded to an even number of bytes)
2224                var nameHeaderLength = dataView.getUint8(offset+7);
2225                if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1;
2226                // Check for pre photoshop 6 format
2227                if(nameHeaderLength === 0) {
2228                    // Always 4
2229                    nameHeaderLength = 4;
2230                }
2231
2232                var startOffset = offset + 8 + nameHeaderLength;
2233                var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);
2234
2235                return readIPTCData(file, startOffset, sectionLength);
2236
2237                break;
2238
2239            }
2240
2241
2242            // Not the marker, continue searching
2243            offset++;
2244
2245        }
2246
2247    }
2248    var IptcFieldMap = {
2249        0x78 : 'caption',
2250        0x6E : 'credit',
2251        0x19 : 'keywords',
2252        0x37 : 'dateCreated',
2253        0x50 : 'byline',
2254        0x55 : 'bylineTitle',
2255        0x7A : 'captionWriter',
2256        0x69 : 'headline',
2257        0x74 : 'copyright',
2258        0x0F : 'category'
2259    };
2260    function readIPTCData(file, startOffset, sectionLength){
2261        var dataView = new DataView(file);
2262        var data = {};
2263        var fieldValue, fieldName, dataSize, segmentType, segmentSize;
2264        var segmentStartPos = startOffset;
2265        while(segmentStartPos < startOffset+sectionLength) {
2266            if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){
2267                segmentType = dataView.getUint8(segmentStartPos+2);
2268                if(segmentType in IptcFieldMap) {
2269                    dataSize = dataView.getInt16(segmentStartPos+3);
2270                    segmentSize = dataSize + 5;
2271                    fieldName = IptcFieldMap[segmentType];
2272                    fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize);
2273                    // Check if we already stored a value with this name
2274                    if(data.hasOwnProperty(fieldName)) {
2275                        // Value already stored with this name, create multivalue field
2276                        if(data[fieldName] instanceof Array) {
2277                            data[fieldName].push(fieldValue);
2278                        }
2279                        else {
2280                            data[fieldName] = [data[fieldName], fieldValue];
2281                        }
2282                    }
2283                    else {
2284                        data[fieldName] = fieldValue;
2285                    }
2286                }
2287
2288            }
2289            segmentStartPos++;
2290        }
2291        return data;
2292    }
2293
2294
2295
2296    function readTags(file, tiffStart, dirStart, strings, bigEnd) {
2297        var entries = file.getUint16(dirStart, !bigEnd),
2298            tags = {},
2299            entryOffset, tag,
2300            i;
2301
2302        for (i=0;i<entries;i++) {
2303            entryOffset = dirStart + i*12 + 2;
2304            tag = strings[file.getUint16(entryOffset, !bigEnd)];
2305            if (!tag && debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd));
2306            tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
2307        }
2308        return tags;
2309    }
2310
2311
2312    function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) {
2313        var type = file.getUint16(entryOffset+2, !bigEnd),
2314            numValues = file.getUint32(entryOffset+4, !bigEnd),
2315            valueOffset = file.getUint32(entryOffset+8, !bigEnd) + tiffStart,
2316            offset,
2317            vals, val, n,
2318            numerator, denominator;
2319
2320        switch (type) {
2321            case 1: // byte, 8-bit unsigned int
2322            case 7: // undefined, 8-bit byte, value depending on field
2323                if (numValues == 1) {
2324                    return file.getUint8(entryOffset + 8, !bigEnd);
2325                } else {
2326                    offset = numValues > 4 ? valueOffset : (entryOffset + 8);
2327                    vals = [];
2328                    for (n=0;n<numValues;n++) {
2329                        vals[n] = file.getUint8(offset + n);
2330                    }
2331                    return vals;
2332                }
2333
2334            case 2: // ascii, 8-bit byte
2335                offset = numValues > 4 ? valueOffset : (entryOffset + 8);
2336                return getStringFromDB(file, offset, numValues-1);
2337
2338            case 3: // short, 16 bit int
2339                if (numValues == 1) {
2340                    return file.getUint16(entryOffset + 8, !bigEnd);
2341                } else {
2342                    offset = numValues > 2 ? valueOffset : (entryOffset + 8);
2343                    vals = [];
2344                    for (n=0;n<numValues;n++) {
2345                        vals[n] = file.getUint16(offset + 2*n, !bigEnd);
2346                    }
2347                    return vals;
2348                }
2349
2350            case 4: // long, 32 bit int
2351                if (numValues == 1) {
2352                    return file.getUint32(entryOffset + 8, !bigEnd);
2353                } else {
2354                    vals = [];
2355                    for (n=0;n<numValues;n++) {
2356                        vals[n] = file.getUint32(valueOffset + 4*n, !bigEnd);
2357                    }
2358                    return vals;
2359                }
2360
2361            case 5:    // rational = two long values, first is numerator, second is denominator
2362                if (numValues == 1) {
2363                    numerator = file.getUint32(valueOffset, !bigEnd);
2364                    denominator = file.getUint32(valueOffset+4, !bigEnd);
2365                    val = new Number(numerator / denominator);
2366                    val.numerator = numerator;
2367                    val.denominator = denominator;
2368                    return val;
2369                } else {
2370                    vals = [];
2371                    for (n=0;n<numValues;n++) {
2372                        numerator = file.getUint32(valueOffset + 8*n, !bigEnd);
2373                        denominator = file.getUint32(valueOffset+4 + 8*n, !bigEnd);
2374                        vals[n] = new Number(numerator / denominator);
2375                        vals[n].numerator = numerator;
2376                        vals[n].denominator = denominator;
2377                    }
2378                    return vals;
2379                }
2380
2381            case 9: // slong, 32 bit signed int
2382                if (numValues == 1) {
2383                    return file.getInt32(entryOffset + 8, !bigEnd);
2384                } else {
2385                    vals = [];
2386                    for (n=0;n<numValues;n++) {
2387                        vals[n] = file.getInt32(valueOffset + 4*n, !bigEnd);
2388                    }
2389                    return vals;
2390                }
2391
2392            case 10: // signed rational, two slongs, first is numerator, second is denominator
2393                if (numValues == 1) {
2394                    return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset+4, !bigEnd);
2395                } else {
2396                    vals = [];
2397                    for (n=0;n<numValues;n++) {
2398                        vals[n] = file.getInt32(valueOffset + 8*n, !bigEnd) / file.getInt32(valueOffset+4 + 8*n, !bigEnd);
2399                    }
2400                    return vals;
2401                }
2402        }
2403    }
2404
2405    /**
2406    * Given an IFD (Image File Directory) start offset
2407    * returns an offset to next IFD or 0 if it's the last IFD.
2408    */
2409    function getNextIFDOffset(dataView, dirStart, bigEnd){
2410        //the first 2bytes means the number of directory entries contains in this IFD
2411        var entries = dataView.getUint16(dirStart, !bigEnd);
2412
2413        // After last directory entry, there is a 4bytes of data,
2414        // it means an offset to next IFD.
2415        // If its value is '0x00000000', it means this is the last IFD and there is no linked IFD.
2416
2417        return dataView.getUint32(dirStart + 2 + entries * 12, !bigEnd); // each entry is 12 bytes long
2418    }
2419
2420    function readThumbnailImage(dataView, tiffStart, firstIFDOffset, bigEnd){
2421        // get the IFD1 offset
2422        var IFD1OffsetPointer = getNextIFDOffset(dataView, tiffStart+firstIFDOffset, bigEnd);
2423
2424        if (!IFD1OffsetPointer) {
2425            // console.log('******** IFD1Offset is empty, image thumb not found ********');
2426            return {};
2427        }
2428        else if (IFD1OffsetPointer > dataView.byteLength) { // this should not happen
2429            // console.log('******** IFD1Offset is outside the bounds of the DataView ********');
2430            return {};
2431        }
2432        // console.log('*******  thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer);
2433
2434        var thumbTags = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd)
2435
2436        // EXIF 2.3 specification for JPEG format thumbnail
2437
2438        // If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG.
2439        // Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail
2440        // by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag.
2441        // Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that
2442        // JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later.
2443
2444        if (thumbTags['Compression']) {
2445            // console.log('Thumbnail image found!');
2446
2447            switch (thumbTags['Compression']) {
2448                case 6:
2449                    // console.log('Thumbnail image format is JPEG');
2450                    if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) {
2451                    // extract the thumbnail
2452                        var tOffset = tiffStart + thumbTags.JpegIFOffset;
2453                        var tLength = thumbTags.JpegIFByteCount;
2454                        thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], {
2455                            type: 'image/jpeg'
2456                        });
2457                    }
2458                break;
2459
2460            case 1:
2461                console.log("Thumbnail image format is TIFF, which is not implemented.");
2462                break;
2463            default:
2464                console.log("Unknown thumbnail image format '%s'", thumbTags['Compression']);
2465            }
2466        }
2467        else if (thumbTags['PhotometricInterpretation'] == 2) {
2468            console.log("Thumbnail image format is RGB, which is not implemented.");
2469        }
2470        return thumbTags;
2471    }
2472
2473    function getStringFromDB(buffer, start, length) {
2474        var outstr = "";
2475        for (n = start; n < start+length; n++) {
2476            outstr += String.fromCharCode(buffer.getUint8(n));
2477        }
2478        return outstr;
2479    }
2480
2481    function readEXIFData(file, start) {
2482        if (getStringFromDB(file, start, 4) != "Exif") {
2483            if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));
2484            return false;
2485        }
2486
2487        var bigEnd,
2488            tags, tag,
2489            exifData, gpsData,
2490            tiffOffset = start + 6;
2491
2492        // test for TIFF validity and endianness
2493        if (file.getUint16(tiffOffset) == 0x4949) {
2494            bigEnd = false;
2495        } else if (file.getUint16(tiffOffset) == 0x4D4D) {
2496            bigEnd = true;
2497        } else {
2498            if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
2499            return false;
2500        }
2501
2502        if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A) {
2503            if (debug) console.log("Not valid TIFF data! (no 0x002A)");
2504            return false;
2505        }
2506
2507        var firstIFDOffset = file.getUint32(tiffOffset+4, !bigEnd);
2508
2509        if (firstIFDOffset < 0x00000008) {
2510            if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset+4, !bigEnd));
2511            return false;
2512        }
2513
2514        tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);
2515
2516        if (tags.ExifIFDPointer) {
2517            exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);
2518            for (tag in exifData) {
2519                switch (tag) {
2520                    case "LightSource" :
2521                    case "Flash" :
2522                    case "MeteringMode" :
2523                    case "ExposureProgram" :
2524                    case "SensingMethod" :
2525                    case "SceneCaptureType" :
2526                    case "SceneType" :
2527                    case "CustomRendered" :
2528                    case "WhiteBalance" :
2529                    case "GainControl" :
2530                    case "Contrast" :
2531                    case "Saturation" :
2532                    case "Sharpness" :
2533                    case "SubjectDistanceRange" :
2534                    case "FileSource" :
2535                        exifData[tag] = StringValues[tag][exifData[tag]];
2536                        break;
2537
2538                    case "ExifVersion" :
2539                    case "FlashpixVersion" :
2540                        exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);
2541                        break;
2542
2543                    case "ComponentsConfiguration" :
2544                        exifData[tag] =
2545                            StringValues.Components[exifData[tag][0]] +
2546                            StringValues.Components[exifData[tag][1]] +
2547                            StringValues.Components[exifData[tag][2]] +
2548                            StringValues.Components[exifData[tag][3]];
2549                        break;
2550                }
2551                tags[tag] = exifData[tag];
2552            }
2553        }
2554
2555        if (tags.GPSInfoIFDPointer) {
2556            gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
2557            for (tag in gpsData) {
2558                switch (tag) {
2559                    case "GPSVersionID" :
2560                        gpsData[tag] = gpsData[tag][0] +
2561                            "." + gpsData[tag][1] +
2562                            "." + gpsData[tag][2] +
2563                            "." + gpsData[tag][3];
2564                        break;
2565                }
2566                tags[tag] = gpsData[tag];
2567            }
2568        }
2569
2570        // extract thumbnail
2571        tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd);
2572
2573        return tags;
2574    }
2575
2576   function findXMPinJPEG(file) {
2577
2578        if (!('DOMParser' in self)) {
2579            // console.warn('XML parsing not supported without DOMParser');
2580            return;
2581        }
2582        var dataView = new DataView(file);
2583
2584        if (debug) console.log("Got file of length " + file.byteLength);
2585        if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
2586           if (debug) console.log("Not a valid JPEG");
2587           return false; // not a valid jpeg
2588        }
2589
2590        var offset = 2,
2591            length = file.byteLength,
2592            dom = new DOMParser();
2593
2594        while (offset < (length-4)) {
2595            if (getStringFromDB(dataView, offset, 4) == "http") {
2596                var startOffset = offset - 1;
2597                var sectionLength = dataView.getUint16(offset - 2) - 1;
2598                var xmpString = getStringFromDB(dataView, startOffset, sectionLength)
2599                var xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8;
2600                xmpString = xmpString.substring( xmpString.indexOf( '<x:xmpmeta' ), xmpEndIndex );
2601
2602                var indexOfXmp = xmpString.indexOf('x:xmpmeta') + 10
2603                //Many custom written programs embed xmp/xml without any namespace. Following are some of them.
2604                //Without these namespaces, XML is thought to be invalid by parsers
2605                xmpString = xmpString.slice(0, indexOfXmp)
2606                            + 'xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" '
2607                            + 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
2608                            + 'xmlns:tiff="http://ns.adobe.com/tiff/1.0/" '
2609                            + 'xmlns:plus="http://schemas.android.com/apk/lib/com.google.android.gms.plus" '
2610                            + 'xmlns:ext="http://www.gettyimages.com/xsltExtension/1.0" '
2611                            + 'xmlns:exif="http://ns.adobe.com/exif/1.0/" '
2612                            + 'xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" '
2613                            + 'xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" '
2614                            + 'xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" '
2615                            + 'xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/" '
2616                            + 'xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" '
2617                            + xmpString.slice(indexOfXmp)
2618
2619                var domDocument = dom.parseFromString( xmpString, 'text/xml' );
2620                return xml2Object(domDocument);
2621            } else{
2622             offset++;
2623            }
2624        }
2625    }
2626
2627    function xml2
vendor: 1,501 bytes, lines 2627-2670
2627Object(xml) {
2628        try {
2629            var obj = {};
2630            if (xml.children.length > 0) {
2631              for (var i = 0; i < xml.children.length; i++) {
2632                var item = xml.children.item(i);
2633                var attributes = item.attributes;
2634                for(var idx in attributes) {
2635                    var itemAtt = attributes[idx];
2636                    var dataKey = itemAtt.nodeName;
2637                    var dataValue = itemAtt.nodeValue;
2638
2639                    if(dataKey !== undefined) {
2640                        obj[dataKey] = dataValue;
2641                    }
2642                }
2643                var nodeName = item.nodeName;
2644
2645                if (typeof (obj[nodeName]) == "undefined") {
2646                  obj[nodeName] = xml2json(item);
2647                } else {
2648                  if (typeof (obj[nodeName].push) == "undefined") {
2649                    var old = obj[nodeName];
2650
2651                    obj[nodeName] = [];
2652                    obj[nodeName].push(old);
2653                  }
2654                  obj[nodeName].push(xml2json(item));
2655                }
2656              }
2657            } else {
2658              obj = xml.textContent;
2659            }
2660            return obj;
2661          } catch (e) {
2662              console.log(e.message);
2663          }
2664    }
2665
2666    EXIF.getData = function(img, callback) {
2667        if ((self.Image && img instanceof self.Image)
2668            || (self.HTMLImageElement && img instanceof self.HTMLImageElement)
2669            && !img.complete)
2670            return false;
2671
2672        if (!imageHasData(img)) {
2673            getImageData(img, callback);
2674        } else {
2675            if (callback) {
2676                callback.call(img);
2677            }
2678        }
2679        return true;
2680    }
2681
2682    EXIF.getTag = function(img, tag) {
2683        if (!imageHasData(img)) return;
2684        return img.exifdata[tag];
2685    }
2686    
2687    EXIF.getIptcTag = function(img, tag) {
2688        if (!imageHasData(img)) return;
2689        return img.iptcdata[tag];
2690    }
2691
2692    EXIF.getAllTags = function(img) {
2693        if (!imageHasData(img)) return {};
2694        var a,
2695            data = img.exifdata,
2696            tags = {};
2697        for (a in data) {
2698            if (data.hasOwnProperty(a)) {
2699                tags[a] = data[a];
2700            }
2701        }
2702        return tags;
2703    }
2704    
2705    EXIF.getAllIptcTags = function(img) {
2706        if (!imageHasData(img)) return {};
2707        var a,
2708            data = img.iptcdata,
2709            tags = {};
2710        for (a in data) {
2711            if (data.hasOwnProperty(a)) {
2712                tags[a] = data[a];
2713            }
2714        }
2715        return tags;
2716    }
2717
2718    EXIF.pretty = function(img) {
2719        if (!imageHasData(img)) return "";
2720        var a,
2721            data = img.exifdata,
2722            strPretty = "";
2723        for (a in data) {
2724            if (data.hasOwnProperty(a)) {
2725                if (typeof data[a] == "object") {
2726                    if (data[a] instanceof Number) {
2727                        strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n";
2728                    } else {
2729                        strPretty += a + " : [" + data[a].length + " values]\r\n";
2730                    }
2731                } else {
2732                    strPretty += a + " : " + data[a] + "\r\n";
2733                }
2734            }
2735        }
2736        return strPretty;
2737    }
2738
2739    EXIF.readFromBinaryFile = function(file) {
2740        return findEXIFinJPEG(file);
2741    }
2742
2743    if (typeof define === 'function' && define.amd) {
2744        define('exif-js', [], function() {
2745            return EXIF;
2746        });
2747    }
2748}.call(this));
2749
2750
2751/*
2752 *
2753 * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
2754 *
2755 * Copyright (c) 2012, Matias Meno
2756 *
2757 * Permission is hereby granted, free of charge, to any person obtaining a copy
2758 * of this software and associated documentation files (the "Software"), to deal
2759 * in the Software without restriction, including without limitation the rights
2760 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2761 * copies of the Software, and to permit persons to whom the Software is
2762 * furnished to do so, subject to the following conditions:
2763 *
2764 * The above copyright notice and this permission notice shall be included in
2765 * all copies or substantial portions of the Software.
2766 *
2767 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2768 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2769 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2770 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2771 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2772 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2773 * THE SOFTWARE.
2774 *
2775 */
2776
2777(function() {
2778  var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,
2779    __slice = [].slice,
2780    __hasProp = {}.hasOwnProperty,
2781    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
2782
2783  noop = function() {};
2784
2785  Emitter = (function() {
2786    function Emitter() {}
2787
2788    Emitter.prototype.addEventListener = Emitter.prototype.on;
2789
2790    Emitter.prototype.on = function(event, fn) {
2791      this._callbacks = this._callbacks || {};
2792      if (!this._callbacks[event]) {
2793        this._callbacks[event] = [];
2794      }
2795      this._callbacks[event].push(fn);
2796      return this;
2797    };
2798
2799    Emitter.prototype.emit = function() {
2800      var args, callback, callbacks, event, _i, _len;
2801      event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
2802      this._callbacks = this._callbacks || {};
2803      callbacks = this._callbacks[event];
2804      if (callbacks) {
2805        for (_i = 0, _len = callbacks.length; _i < _len; _i++) {
2806          callback = callbacks[_i];
2807          callback.apply(this, args);
2808        }
2809      }
2810      return this;
2811    };
2812
2813    Emitter.prototype.removeListener = Emitter.prototype.off;
2814
2815    Emitter.prototype.removeAllListeners = Emitter.prototype.off;
2816
2817    Emitter.prototype.removeEventListener = Emitter.prototype.off;
2818
2819    Emitter.prototype.off = function(event, fn) {
2820      var callback, callbacks, i, _i, _len;
2821      if (!this._callbacks || arguments.length === 0) {
2822        this._callbacks = {};
2823        return this;
2824      }
2825      callbacks = this._callbacks[event];
2826      if (!callbacks) {
2827        return this;
2828      }
2829      if (arguments.length === 1) {
2830        delete this._callbacks[event];
2831        return this;
2832      }
2833      for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) {
2834        callback = callbacks[i];
2835        if (callback === fn) {
2836          callbacks.splice(i, 1);
2837          break;
2838        }
2839      }
2840      return this;
2841    };
2842
2843    return Emitter;
2844
2845  })();
2846
2847  Dropzone = (function(_super) {
2848    var extend, resolveOption;
2849
2850    __extends(Dropzone, _super);
2851
2852    Dropzone.prototype.Emitter = Emitter;
2853
2854
2855    /*
2856    This is a list of all available events you can register on a dropzone object.
2857    
2858    You can register an event handler like this:
2859    
2860        dropzone.on("dragEnter", function() { });
2861     */
2862
2863    Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];
2864
2865    Dropzone.prototype.defaultOptions = {
2866      url: null,
2867      method: "post",
2868      withCredentials: false,
2869      parallelUploads: 2,
2870      uploadMultiple: false,
2871      maxFilesize: 256,
2872      paramName: "file",
2873      createImageThumbnails: true,
2874      maxThumbnailFilesize: 10,
2875      thumbnailWidth: 120,
2876      thumbnailHeight: 120,
2877      filesizeBase: 1000,
2878      maxFiles: null,
2879      params: {},
2880      clickable: true,
2881      ignoreHiddenFiles: true,
2882      acceptedFiles: null,
2883      acceptedMimeTypes: null,
2884      autoProcessQueue: true,
2885      autoQueue: true,
2886      addRemoveLinks: false,
2887      previewsContainer: null,
2888      hiddenInputContainer: "body",
2889      capture: null,
2890      renameFilename: null,
2891      dictDefaultMessage: "Drop files here to upload",
2892      dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
2893      dictFallbackText: "Please use the fallback form below to upload your files like in the olde
2893n days.",
2894      dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
2895      dictInvalidFileType: "You can't upload files of this type.",
2896      dictResponseError: "Server responded with {{statusCode}} code.",
2897      dictCancelUpload: "Cancel upload",
2898      dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
2899      dictRemoveFile: "Remove file",
2900      dictRemoveFileConfirmation: null,
2901      dictMaxFilesExceeded: "You can not upload any more files.",
2902      accept: function(file, done) {
2903        return done();
2904      },
2905      init: function() {
2906        return noop;
2907      },
2908      forceFallback: false,
2909      fallback: function() {
2910        var child, messageElement, span, _i, _len, _ref;
2911        this.element.className = "" + this.element.className + " dz-browser-not-supported";
2912        _ref = this.element.getElementsByTagName("div");
2913        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2914          child = _ref[_i];
2915          if (/(^| )dz-message($| )/.test(child.className)) {
2916            messageElement = child;
2917            child.className = "dz-message";
2918            continue;
2919          }
2920        }
2921        if (!messageElement) {
2922          messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
2923          this.element.appendChild(messageElement);
2924        }
2925        span = messageElement.getElementsByTagName("span")[0];
2926        if (span) {
2927          if (span.textContent != null) {
2928            span.textContent = this.options.dictFallbackMessage;
2929          } else if (span.innerText != null) {
2930            span.innerText = this.options.dictFallbackMessage;
2931          }
2932        }
2933        return this.element.appendChild(this.getFallbackForm());
2934      },
2935      resize: function(file) {
2936        var info, srcRatio, trgRatio;
2937        info = {
2938          srcX: 0,
2939          srcY: 0,
2940          srcWidth: file.width,
2941          srcHeight: file.height
2942        };
2943        srcRatio = file.width / file.height;
2944        info.optWidth = this.options.thumbnailWidth;
2945        info.optHeight = this.options.thumbnailHeight;
2946        if ((info.optWidth == null) && (info.optHeight == null)) {
2947          info.optWidth = info.srcWidth;
2948          info.optHeight = info.srcHeight;
2949        } else if (info.optWidth == null) {
2950          info.optWidth = srcRatio * info.optHeight;
2951        } else if (info.optHeight == null) {
2952          info.optHeight = (1 / srcRatio) * info.optWidth;
2953        }
2954        trgRatio = info.optWidth / info.optHeight;
2955        if (file.height < info.optHeight || file.width < info.optWidth) {
2956          info.trgHeight = info.srcHeight;
2957          info.trgWidth = info.srcWidth;
2958        } else {
2959          if (srcRatio > trgRatio) {
2960            info.srcHeight = file.height;
2961            info.srcWidth = info.srcHeight * trgRatio;
2962          } else {
2963            info.srcWidth = file.width;
2964            info.srcHeight = info.srcWidth / trgRatio;
2965          }
2966        }
2967        info.srcX = (file.width - info.srcWidth) / 2;
2968        info.srcY = (file.height - info.srcHeight) / 2;
2969        return info;
2970      },
2971
2972      /*
2973      Those functions register themselves to the events on init and handle all
2974      the user interface specific stuff. Overwriting them won't break the upload
2975      but can break the way it's displayed.
2976      You can overwrite them if you don't like the default behavior. If you just
2977      want to add an additional event handler, register it on the dropzone object
2978      and don't overwrite those options.
2979       */
2980      drop: function(e) {
2981        return this.element.classList.remove("dz-drag-hover");
2982      },
2983      dragstart: noop,
2984      dragend: function(e) {
2985        return this.element.classList.remove("dz-drag-hover");
2986      },
2987      dragenter: function(e) {
2988        return this.element.classList.add("dz-drag-hover");
2989      },
2990      dragover: function(e) {
2991        return this.element.classList.add("dz-drag-hover");
2992      },
2993      dragleave: function(e) {
2994        return this.element.classList.remove("dz-drag-hover");
2995      },
2996      paste: noop,
2997      reset: function() {
2998        return this.element.classList.remove("dz-started");
2999      },
3000      addedfile: function(file) {
3001        var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
3002        if (this.element === this.previewsContainer) {
3003          this.element.classList.add("dz-started");
3004        }
3005        if (this.previewsContainer) {
3006          file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
3007          file.previewTemplate = file.previewElement;
3008          this.previewsContainer.appendChild(file.previewElement);
3009          _ref = file.previewElement.querySelectorAll("[data-dz-name]");
3010          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3011            node = _ref[_i];
3012            node.textContent = this._renameFilename(file.name);
3013          }
3014          _ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
3015          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
3016            node = _ref1[_j];
3017            node.innerHTML = this.filesize(file.size);
3018          }
3019          if (this.options.addRemoveLinks) {
3020            file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
3021            file.previewElement.appendChild(file._removeLink);
3022          }
3023          removeFileEvent = (function(_this) {
3024            return function(e) {
3025              e.preventDefault();
3026              e.stopPropagation();
3027              if (file.status === Dropzone.UPLOADING) {
3028                return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
3029                  return _this.removeFile(file);
3030                });
3031              } else {
3032                if (_this.options.dictRemoveFileConfirmation) {
3033                  return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
3034                    return _this.removeFile(file);
3035                  });
3036                } else {
3037                  return _this.removeFile(file);
3038                }
3039              }
3040            };
3041          })(this);
3042          _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
3043          _results = [];
3044          for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
3045            removeLink = _ref2[_k];
3046            _results.push(removeLink.addEventListener("click", removeFileEvent));
3047          }
3048          return _results;
3049        }
3050      },
3051      removedfile: function(file) {
3052        var _ref;
3053        if (file.previewElement) {
3054          if ((_ref = file.previewElement) != null) {
3055            _ref.parentNode.removeChild(file.previewElement);
3056          }
3057        }
3058        return this._updateMaxFilesReachedClass();
3059      },
3060      thumbnail: function(file, dataUrl) {
3061        var thumbnailElement, _i, _len, _ref;
3062        if (file.previewElement) {
3063          file.previewElement.classList.remove("dz-file-preview");
3064          _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
3065          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3066            thumbnailElement = _ref[_i];
3067            thumbnailElement.alt = file.name;
3068            thumbnailElement.src = dataUrl;
3069          }
3070          return setTimeout(((function(_this) {
3071            return function() {
3072              return file.previewElement.classList.add("dz-image-preview");
3073            };
3074          })(this)), 1);
3075        }
3076      },
3077      error: function(file, message) {
3078        var node, _i, _len, _ref, _results;
3079        if (file.previewElement) {
3080          file.previewElement.classList.add("dz-error");
3081          if (typeof message !== "String" && message.error) {
3082            message = message.error;
3083          }
3084          _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
3085          _results = [];
3086          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3087            node = _ref[_i];
3088            _results.push(node.textContent = message);
3089          }
3090          return _results;
3091        }
3092      },
3093      errormultiple: noop,
3094      processing: function(file) {
3095        if (file.previewElement) {
3096          file.previewElement.classList.add("dz-processing");
3097          if (file._removeLink) {
3098            return file._removeLink.textContent = this.options.dictCancelUpload;
3099          }
3100        }
3101      },
3102      processingmultiple: noop,
3103      uploadprogress: function(file, progress, bytesSent) {
3104        var node, _i, _len, _ref, _results;
3105        if (file.previewElement) {
3106          _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
3107          _results = [];
3108          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3109            node = _ref[_i];
3110            if (node.nodeName === 'PROGRESS') {
3111              _results.push(node.value = progress);
3112            } else {
3113              _results.push(node.style.width = "" + progress + "%");
3114            }
3115          }
3116          return _results;
3117        }
3118      },
3119      totaluploadprogress: noop,
3120      sending: noop,
3121      sendingmultiple: noop,
3122      success: function(file) {
3123        if (file.previewElement) {
3124          return file.previewElement.classList.add("dz-success");
3125        }
3126      },
3127      successmultiple: noop,
3128      canceled: function(file) {
3129        return this.emit("error", file, "Upload canceled.");
3130      },
3131      canceledmultiple: noop,
3132      complete: function(file) {
3133        if (file._removeLink) {
3134          file._removeLink.textContent = this.options.dictRemoveFile;
3135        }
3136        if (file.previewElement) {
3137          return file.previewElement.classList.add("dz-complete");
3138        }
3139      },
3140      completemultiple: noop,
3141      maxfilesexceeded: noop,
3142      maxfilesreached: noop,
3143      queuecomplete: noop,
3144      addedfiles: noop,
3145      previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n  <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n  <div class=\"dz-details\">\n    <div class=\"dz-size\"><span data-dz-size></span></div>\n    <div class=\"dz-filename\"><span data-dz-name></span></div>\n  </div>\n  <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n  <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n  <div class=\"dz-success-mark\">\n    <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n      <title>Check</title>\n      <defs></defs>\n      <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n        <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n      </g>\n    </svg>\n  </div>\n  <div class=\"dz-error-mark\">\n    <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n      <title>Error</title>\n      <defs></defs>\n      <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n        <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n          <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n        </g>\n      </g>\n    </svg>\n  </div>\n</div>"
3146    };
3147
3148    extend = function() {
3149      var key, object, objects, target, val, _i, _len;
3150      target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
3151      for (_i = 0, _len = objects.length; _i < _len; _i++) {
3152        object = objects[_i];
3153        for (key in object) {
3154          val = object[key];
3155          target[key] = val;
3156        }
3157      }
3158      return target;
3159    };
3160
3161    function Dropzone(element, options) {
3162      var elementOptions, fallback, _ref;
3163      this.element = element;
3164      this.version = Dropzone.version;
3165      this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
3166      this.clickableElements = [];
3167      this.listeners = [];
3168      this.files = [];
3169      if (typeof this.element === "string") {
3170        this.element = document.querySelector(this.element);
3171      }
3172      if (!(this.element && (this.element.nodeType != null))) {
3173        throw new Error("Invalid dropzone element.");
3174      }
3175      if (this.element.dropzone) {
3176        throw new Error("Dropzone already attached.");
3177      }
3178      Dropzone.instances.push(this);
3179      this.element.dropzone = this;
3180      elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {};
3181      this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
3182      if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
3183        return this.options.fallback.call(this);
3184      }
3185      if (this.options.url == null) {
3186        this.options.url = this.element.getAttribute("action");
3187      }
3188      if (!this.options.url) {
3189        throw new Error("No URL provided.");
3190      }
3191      if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
3192        throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
3193      }
3194      if (this.options.acceptedMimeTypes) {
3195        this.options.acceptedFiles = this.options.acceptedMimeTypes;
3196        delete this.options.acceptedMimeTypes;
3197      }
3198      this.options.method = this.options.method.toUpperCase();
3199      if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
3200        fallback.parentNode.removeChild(fallback);
3201      }
3202      if (this.options.previewsContainer !== false) {
3203        if (this.options.previewsContainer) {
3204          this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
3205        } else {
3206          this.previewsContainer = this.element;
3207        }
3208      }
3209      if (this.options.clickable) {
3210        if (this.options.clickable === true) {
3211          this.clickableElements = [this.element];
3212        } else {
3213          this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
3214        }
3215      }
3216      this.init();
3217    }
3218
3219    Dropzone.prototype.getAcceptedFiles = function() {
3220      var file, _i, _len, _ref, _results;
3221      _ref = this.files;
3222      _results = [];
3223      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3224        file = _ref[_i];
3225        if (file.accepted) {
3226          _results.push(file);
3227        }
3228      }
3229      return _results;
3230    };
3231
3232    Dropzone.prototype.getRejectedFiles = function() {
3233      var file, _i, _len, _ref, _results;
3234      _ref = this.files;
3235      _results = [];
3236      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3237        file = _ref[_i];
3238        if (!file.accepted) {
3239          _results.push(file);
3240        }
3241      }
3242      return _results;
3243    };
3244
3245    Dropzone.prototype.getFilesWithStatus = function(status) {
3246      var file, _i, _len, _ref, _results;
3247      _ref = this.files;
3248      _results = [];
3249      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3250        file = _ref[_i];
3251        if (file.status === status) {
3252          _results.push(file);
3253        }
3254      }
3255      return _results;
3256    };
3257
3258    Dropzone.prototype.getQueuedFiles = function() {
3259      return this.getFilesWithStatus(Dropzone.QUEUED);
3260    };
3261
3262    Dropzone.prototype.getUploadingFiles = function() {
3263      return this.getFilesWithStatus(Dropzone.UPLOADING);
3264    };
3265
3266    Dropzone.prototype.getAddedFiles = function() {
3267      return this.getFilesWithStatus(Dropzone.ADDED);
3268    };
3269
3270    Dropzone.prototype.getActiveFiles = function() {
3271      var file, _i, _len, _ref, _results;
3272      _ref = this.files;
3273      _results = [];
3274      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3275        file = _ref[_i];
3276        if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {
3277          _results.push(file);
3278        }
3279      }
3280      return _results;
3281    };
3282
3283    Dropzone.prototype.init = function() {
3284      var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1;
3285      if (this.element.tagName === "form") {
3286        this.element.setAttribute("enctype", "multipart/form-data");
3287      }
3288      if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
3289        this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
3290      }
3291      if (this.clickableElements.length) {
3292        setupHiddenFileInput = (function(_this) {
3293          return function() {
3294            if (_this.hiddenFileInput) {
3295              _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput);
3296            }
3297            _this.hiddenFileInput = document.createElement("input");
3298            _this.hiddenFileInput.setAttribute("type", "file");
3299            if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
3300              _this.hiddenFileInput.setAttribute("multiple", "multiple");
3301            }
3302            _this.hiddenFileInput.className = "dz-hidden-input";
3303            if (_this.options.acceptedFiles != null) {
3304              _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
3305            }
3306            if (_this.options.capture != null) {
3307              _this.hiddenFileInput.setAttribute("capture", _this.options.capture);
3308            }
3309            _this.hiddenFileInput.style.visibility = "hidden";
3310            _this.hiddenFileInput.style.position = "absolute";
3311            _this.hiddenFileInput.style.top = "0";
3312            _this.hiddenFileInput.style.left = "0";
3313            _this.hiddenFileInput.style.height = "0";
3314            _this.hiddenFileInput.style.width = "0";
3315            document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput);
3316            return _this.hiddenFileInput.addEventListener("change", function() {
3317              var file, files, _i, _len;
3318              files = _this.hiddenFileInput.files;
3319              if (files.length) {
3320                for (_i = 0, _len = files.length; _i < _len; _i++) {
3321                  file = files[_i];
3322                  _this.addFile(file);
3323                }
3324              }
3325              _this.emit("addedfiles", files);
3326              return setupHiddenFileInput();
3327            });
3328          };
3329        })(this);
3330        setupHiddenFileInput();
3331      }
3332      this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL;
3333      _ref1 = this.events;
3334      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
3335        eventName = _ref1[_i];
3336        this.on(eventName, this.options[eventName]);
3337      }
3338      this.on("uploadprogress", (function(_this) {
3339        return function() {
3340          return _this.updateTotalUploadProgress();
3341        };
3342      })(this));
3343      this.on("removedfile", (function(_this) {
3344        return function() {
3345          return _this.updateTotalUploadProgress();
3346        };
3347      })(this));
3348      this.on("canceled", (function(_this) {
3349        return function(file) {
3350          return _this.emit("complete", file);
3351        };
3352      })(this));
3353      this.on("complete", (function(_this) {
3354        return function(file) {
3355          if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
3356            return setTimeout((function() {
3357              return _this.emit("queuecomplete");
3358            }), 0);
3359          }
3360        };
3361      })(this));
3362      noPropagation = function(e) {
3363        e.stopPropagation();
3364        if (e.preventDefault) {
3365          return e.preventDefault();
3366        } else {
3367          return e.returnValue = false;
3368        }
3369      };
3370      this.listeners = [
3371        {
3372          element: this.element,
3373          events: {
3374            "dragstart": (function(_this) {
3375              return function(e) {
3376                return _this.emit("dragstart", e);
3377              };
3378            })(this),
3379            "dragenter": (function(_this) {
3380              return function(e) {
3381                noPropagation(e);
3382                return _this.emit("dragenter", e);
3383              };
3384            })(this),
3385            "dragover": (function(_this) {
3386              return function(e) {
3387                var efct;
3388                try {
3389                  efct = e.dataTransfer.effectAllowed;
3390                } catch (_error) {}
3391                e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
3392                noPropagation(e);
3393                return _this.emit("dragover", e);
3394              };
3395            })(this),
3396            "dragleave": (function(_this) {
3397              return function(e) {
3398                return _this.emit("dragleave", e);
3399              };
3400            })(this),
3401            "drop": (function(_this) {
3402              return function(e) {
3403                noPropagation(e);
3404                return _this.drop(e);
3405              };
3406            })(this),
3407            "dragend": (function(_this) {
3408              return function(e) {
3409                return _this.emit("dragend", e);
3410              };
3411            })(this)
3412          }
3413        }
3414      ];
3415      this.clickableElements.forEach((function(_this) {
3416        return function(clickableElement) {
3417          return _this.listeners.push({
3418            element: clickableElement,
3419            events: {
3420              "click": function(evt) {
3421                if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
3422                  _this.hiddenFileInput.click();
3423                }
3424                return true;
3425              }
3426            }
3427          });
3428        };
3429      })(this));
3430      this.enable();
3431      return this.options.init.call(this);
3432    };
3433
3434    Dropzone.prototype.destroy = function() {
3435      var _ref;
3436      this.disable();
3437      this.removeAllFiles(true);
3438      if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) {
3439        this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
3440        this.hiddenFileInput = null;
3441      }
3442      delete this.element.dropzone;
3443      return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
3444    };
3445
3446    Dropzone.prototype.updateTotalUploadProgress = function() {
3447      var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;
3448      totalBytesSent = 0;
3449      totalBytes = 0;
3450      activeFiles = this.getActiveFiles();
3451      if (activeFiles.length) {
3452        _ref = this.getActiveFiles();
3453        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3454          file = _ref[_i];
3455          totalBytesSent += file.upload.bytesSent;
3456          totalBytes += file.upload.total;
3457        }
3458        totalUploadProgress = 100 * totalBytesSent / totalBytes;
3459      } else {
3460        totalUploadProgress = 100;
3461      }
3462      return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
3463    };
3464
3465    Dropzone.prototype._getParamName = function(n) {
3466      if (typeof this.options.paramName === "function") {
3467        return this.options.paramName(n);
3468      } else {
3469        return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
3470      }
3471    };
3472
3473    Dropzone.prototype._renameFilename = function(name) {
3474      if (typeof this.options.renameFilename !== "function") {
3475        return name;
3476      }
3477      return this.options.renameFilename(name);
3478    };
3479
3480    Dropzone.prototype.getFallbackForm = function() {
3481      var existingFallback, fields, fieldsString, form;
3482      if (existingFallback = this.getExistingFallback()) {
3483        return existingFallback;
3484      }
3485      fieldsString = "<div class=\"dz-fallback\">";
3486      if (this.options.dictFallbackText) {
3487        fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
3488      }
3489      fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>";
3490      fields = Dropzone.createElement(fieldsString);
3491      if (this.element.tagName !== "FORM") {
3492        form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
3493        form.appendChild(fields);
3494      } else {
3495        this.element.setAttribute("enctype", "multipart/form-data");
3496        this.element.setAttribute("method", this.options.method);
3497      }
3498      return form != null ? form : fields;
3499    };
3500
3501    Dropzone.prototype.getExistingFallback = function() {
3502      var fallback, getFallback, tagName, _i, _len, _ref;
3503      getFallback = function(elements) {
3504        var el, _i, _len;
3505        for (_i = 0, _len = elements.length; _i < _len; _i++) {
3506          el = elements[_i];
3507          if (/(^| )fallback($| )/.test(el.className)) {
3508            return el;
3509          }
3510        }
3511      };
3512      _ref = ["div", "form"];
3513      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3514        tagName = _ref[_i];
3515        if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
3516          return fallback;
3517        }
3518      }
3519    };
3520
3521    Dropzone.prototype.setupEventListeners = function() {
3522      var elementListeners, event, listener, _i, _len, _ref, _results;
3523      _ref = this.listeners;
3524      _results = [];
3525      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3526        elementListeners = _ref[_i];
3527        _results.push((function() {
3528          var _ref1, _results1;
3529          _ref1 = elementListeners.events;
3530          _results1 = [];
3531          for (event in _ref1) {
3532            listener = _ref1[event];
3533            _results1.push(elementListeners.element.addEventListener(event, listener, false));
3534          }
3535          return _results1;
3536        })());
3537      }
3538      return _results;
3539    };
3540
3541    Dropzone.prototype.removeEventListeners = function() {
3542      var elementListeners, event, listener, _i, _len, _ref, _results;
3543      _ref = this.listeners;
3544      _results = [];
3545      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3546        elementListeners = _ref[_i];
3547        _results.push((function() {
3548          var _ref1, _results1;
3549          _ref1 = elementListeners.events;
3550          _results1 = [];
3551          for (event in _ref1) {
3552            listener = _ref1[event];
3553            _results1.push(elementListeners.element.removeEventListener(event, listener, false));
3554          }
3555          return _results1;
3556        })());
3557      }
3558      return _results;
3559    };
3560
3561    Dropzone.prototype.disable = function() {
3562      var file, _i, _len, _ref, _results;
3563      this.clickableElements.forEach(function(element) {
3564        return element.classList.remove("dz-clickable");
3565      });
3566      this.removeEventListeners();
3567      _ref = this.files;
3568      _results = [];
3569      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3570        file = _ref[_i];
3571        _results.push(this.cancelUpload(file));
3572      }
3573      return _results;
3574    };
3575
3576    Dropzone.prototype.enable = function() {
3577      this.clickableElements.forEach(function(element) {
3578        return element.classList.add("dz-clickable");
3579      });
3580      return this.setupEventListeners();
3581    };
3582
3583    Dropzone.prototype.filesize = function(size) {
3584      var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len;
3585      selectedSize = 0;
3586      selectedUnit = "b";
3587      if (size > 0) {
3588        units = ['TB', 'GB', 'MB', 'KB', 'b'];
3589        for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) {
3590          unit = units[i];
3591          cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
3592          if (size >= cutoff) {
3593            selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
3594            selectedUnit = unit;
3595            break;
3596          }
3597        }
3598        selectedSize = Math.round(10 * selectedSize) / 10;
3599      }
3600      return "<strong>" + selectedSize + "</strong> " + selectedUnit;
3601    };
3602
3603    Dropzone.prototype._updateMaxFilesReachedClass = function() {
3604      if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
3605        if (this.getAcceptedFiles().length === this.options.maxFiles) {
3606          this.emit('maxfilesreached', this.files);
3607        }
3608        return this.element.classList.add("dz-max-files-reached");
3609      } else {
3610        return this.element.classList.remove("dz-max-files-reached");
3611      }
3612    };
3613
3614    Dropzone.prototype.drop = function(e) {
3615      var files, items;
3616      if (!e.dataTransfer) {
3617        return;
3618      }
3619      this.emit("drop", e);
3620      files = e.dataTransfer.files;
3621      this.emit("addedfiles", files);
3622      if (files.length) {
3623        items = e.dataTransfer.items;
3624        if (items && items.length && (items[0].webkitGetAsEntry != null)) {
3625          this._addFilesFromItems(items);
3626        } else {
3627          this.handleFiles(files);
3628        }
3629      }
3630    };
3631
3632    Dropzone.prototype.paste = function(e) {
3633      var items, _ref;
3634      if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) {
3635        return;
3636      }
3637      this.emit("paste", e);
3638      items = e.clipboardData.items;
3639      if (items.length) {
3640        return this._addFilesFromItems(items);
3641      }
3642    };
3643
3644    Dropzone.prototype.handleFiles = function(files) {
3645      var file, _i, _len, _results;
3646      _results = [];
3647      for (_i = 0, _len = files.length; _i < _len; _i++) {
3648        file = files[_i];
3649        _results.push(this.addFile(file));
3650      }
3651      return _results;
3652    };
3653
3654    Dropzone.prototype._addFilesFromItems = function(items) {
3655      var entry, item, _i, _len, _results;
3656      _results = [];
3657      for (_i = 0, _len = items.length; _i < _len; _i++) {
3658        item = items[_i];
3659        if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {
3660          if (entry.isFile) {
3661            _results.push(this.addFile(item.getAsFile()));
3662          } else if (entry.isDirectory) {
3663            _results.push(this._addFilesFromDirectory(entry, entry.name));
3664          } else {
3665            _results.push(void 0);
3666          }
3667        } else if (item.getAsFile != null) {
3668          if ((item.kind == null) || item.kind === "file") {
3669            _results.push(this.addFile(item.getAsFile()));
3670          } else {
3671            _results.push(void 0);
3672          }
3673        } else {
3674          _results.push(void 0);
3675        }
3676      }
3677      return _results;
3678    };
3679
3680    Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
3681      var dirReader, errorHandler, readEntries;
3682      dirReader = directory.createReader();
3683      errorHandler = function(error) {
3684        return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
3685      };
3686      readEntries = (function(_this) {
3687        return function() {
3688          return dirReader.readEntries(function(entries) {
3689            var entry, _i, _len;
3690            if (entries.length > 0) {
3691              for (_i = 0, _len = entries.length; _i < _len; _i++) {
3692                entry = entries[_i];
3693                if (entry.isFile) {
3694                  entry.file(function(file) {
3695                    if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
3696                      return;
3697                    }
3698                    file.fullPath = "" + path + "/" + file.name;
3699                    return _this.addFile(file);
3700                  });
3701                } else if (entry.isDirectory) {
3702                  _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name);
3703                }
3704              }
3705              readEntries();
3706            }
3707            return null;
3708          }, errorHandler);
3709        };
3710      })(this);
3711      return readEntries();
3712    };
3713
3714    Dropzone.prototype.accept = function(file, done) {
3715      if (file.size > this.options.maxFilesize * 1024 * 1024) {
3716        return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
3717      } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
3718        return done(this.options.dictInvalidFileType);
3719      } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
3720        done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
3721        return this.emit("maxfilesexceeded", file);
3722      } else {
3723        return this.options.accept.call(this, file, done);
3724      }
3725    };
3726
3727    Dropzone.prototype.addFile = function(file) {
3728      file.upload = {
3729        progress: 0,
3730        total: file.size,
3731        bytesSent: 0
3732      };
3733      this.files.push(file);
3734      file.status = Dropzone.ADDED;
3735      this.emit("addedfile", file);
3736      this._enqueueThumbnail(file);
3737      return this.accept(file, (function(_this) {
3738        return function(error) {
3739          if (error) {
3740            file.accepted = false;
3741            _this._errorProcessing([file], error);
3742          } else {
3743            file.accepted = true;
3744            if (_this.options.autoQueue) {
3745              _this.enqueueFile(file);
3746            }
3747          }
3748          return _this._updateMaxFilesReachedClass();
3749        };
3750      })(this));
3751    };
3752
3753    Dropzone.prototype.enqueueFiles = function(files) {
3754      var file, _i, _len;
3755      for (_i = 0, _len = files.length; _i < _len; _i++) {
3756        file = files[_i];
3757        this.enqueueFile(file);
3758      }
3759      return null;
3760    };
3761
3762    Dropzone.prototype.enqueueFile = function(file) {
3763      if (file.status === Dropzone.ADDED && file.accepted === true) {
3764        file.status = Dropzone.QUEUED;
3765        if (this.options.autoProcessQueue) {
3766          return setTimeout(((function(_this) {
3767            return function() {
3768              return _this.processQueue();
3769            };
3770          })(this)), 0);
3771        }
3772      } else {
3773        throw new Error("This file can't be queued because it has already been processed or was rejected.");
3774      }
3775    };
3776
3777    Dropzone.prototype._thumbnailQueue = [];
3778
3779    Dropzone.prototype._processingThumbnail = false;
3780
3781    Dropzone.prototype._enqueueThumbnail = function(file) {
3782      if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
3783        this._thumbnailQueue.push(file);
3784        return setTimeout(((function(_this) {
3785          return function() {
3786            return _this._processThumbnailQueue();
3787          };
3788        })(this)), 0);
3789      }
3790    };
3791
3792    Dropzone.prototype._processThumbnailQueue = function() {
3793      if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
3794        return;
3795      }
3796      this._processingThumbnail = true;
3797      return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) {
3798        return function() {
3799          _this._processingThumbnail = false;
3800          return _this._processThumbnailQueue();
3801        };
3802      })(this));
3803    };
3804
3805    Dropzone.prototype.removeFile = function(file) {
3806      if (file.status === Dropzone.UPLOADING) {
3807        this.cancelUpload(file);
3808      }
3809      this.files = without(this.files, file);
3810      this.emit("removedfile", file);
3811      if (this.files.length === 0) {
3812        return this.emit("reset");
3813      }
3814    };
3815
3816    Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
3817      var file, _i, _len, _ref;
3818      if (cancelIfNecessary == null) {
3819        cancelIfNecessary = false;
3820      }
3821      _ref = this.files.slice();
3822      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3823        file = _ref[_i];
3824        if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
3825          this.removeFile(file);
3826        }
3827      }
3828      return null;
3829    };
3830
3831    Dropzone.prototype.createThumbnail = function(file, callback) {
3832      var fileReader;
3833      fileReader = new FileReader;
3834      fileReader.onload = (function(_this) {
3835        return function() {
3836          if (file.type === "image/svg+xml") {
3837            _this.emit("thumbnail", file, fileReader.result);
3838            if (callback != null) {
3839              callback();
3840            }
3841            return;
3842          }
3843          return _this.createThumbnailFromUrl(file, fileReader.result, callback);
3844        };
3845      })(this);
3846      return fileReader.readAsDataURL(file);
3847    };
3848
3849    Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback, crossOrigin) {
3850      var img;
3851      img = document.createElement("img");
3852      if (crossOrigin) {
3853        img.crossOrigin = crossOrigin;
3854      }
3855      img.onload = (function(_this) {
3856        return function() {
3857          var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;
3858          file.width = img.width;
3859          file.height = img.height;
3860          resizeInfo = _this.options.resize.call(_this, file);
3861          if (resizeInfo.trgWidth == null) {
3862            resizeInfo.trgWidth = resizeInfo.optWidth;
3863          }
3864          if (resizeInfo.trgHeight == null) {
3865            resizeInfo.trgHeight = resizeInfo.optHeight;
3866          }
3867          canvas = document.createElement("canvas");
3868          ctx = canvas.getContext("2d");
3869          canvas.width = resizeInfo.trgWidth;
3870          canvas.height = resizeInfo.trgHeight;
3871          drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
3872          thumbnail = canvas.toDataURL("image/png");
3873          _this.emit("thumbnail", file, thumbnail);
3874          if (callback != null) {
3875            return callback();
3876          }
3877        };
3878      })(this);
3879      if (callback != null) {
3880        img.onerror = callback;
3881      }
3882      return img.src = imageUrl;
3883    };
3884
3885    Dropzone.prototype.processQueue = function() {
3886      var i, parallelUploads, processingLength, queuedFiles;
3887      parallelUploads = this.options.parallelUploads;
3888      processingLength = this.getUploadingFiles().length;
3889      i = processingLength;
3890      if (processingLength >= parallelUploads) {
3891        return;
3892      }
3893      queuedFiles = this.getQueuedFiles();
3894      if (!(queuedFiles.length > 0)) {
3895        return;
3896      }
3897      if (this.options.uploadMultiple) {
3898        return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
3899      } else {
3900        while (i < parallelUploads) {
3901          if (!queuedFiles.length) {
3902            return;
3903          }
3904          this.processFile(queuedFiles.shift());
3905          i++;
3906        }
3907      }
3908    };
3909
3910    Dropzone.prototype.processFile = function(file) {
3911      return this.processFiles([file]);
3912    };
3913
3914    Dropzone.prototype.processFiles = function(files) {
3915      var file, _i, _len;
3916      for (_i = 0, _len = files.length; _i < _len; _i++) {
3917        file = files[_i];
3918        file.processing = true;
3919        file.status = Dropzone.UPLOADING;
3920        this.emit("processing", file);
3921      }
3922      if (this.options.uploadMultiple) {
3923        this.emit("processingmultiple", files);
3924      }
3925      return this.uploadFiles(files);
3926    };
3927
3928    Dropzone.prototype._getFilesWithXhr = function(xhr) {
3929      var file, files;
3930      return files = (function() {
3931        var _i, _len, _ref, _results;
3932        _ref = this.files;
3933        _results = [];
3934        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3935          file = _ref[_i];
3936          if (file.xhr === xhr) {
3937            _results.push(file);
3938          }
3939        }
3940        return _results;
3941      }).call(this);
3942    };
3943
3944    Dropzone.prototype.cancelUpload = function(file) {
3945      var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;
3946      if (file.status === Dropzone.UPLOADING) {
3947        groupedFiles = this._getFilesWithXhr(file.xhr);
3948        for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {
3949          groupedFile = groupedFiles[_i];
3950          groupedFile.status = Dropzone.CANCELED;
3951        }
3952        file.xhr.abort();
3953        for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {
3954          groupedFile = groupedFiles[_j];
3955          this.emit("canceled", groupedFile);
3956        }
3957        if (this.options.uploadMultiple) {
3958          this.emit("canceledmultiple", groupedFiles);
3959        }
3960      } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {
3961        file.status = Dropzone.CANCELED;
3962        this.emit("canceled", file);
3963        if (this.options.uploadMultiple) {
3964          this.emit("canceledmultiple", [file]);
3965        }
3966      }
3967      if (this.options.autoProcessQueue) {
3968        return this.processQueue();
3969      }
3970    };
3971
3972    resolveOption = function() {
3973      var args, option;
3974      option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
3975      if (typeof option === 'function') {
3976        return option.apply(this, args);
3977      }
3978      return option;
3979    };
3980
3981    Dropzone.prototype.uploadFile = function(file) {
3982      return this.uploadFiles([file]);
3983    };
3984
3985    Dropzone.prototype.uploadFiles = function(files) {
3986      var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
3987      xhr = new XMLHttpRequest();
3988      for (_i = 0, _len = files.length; _i < _len; _i++) {
3989        file = files[_i];
3990        file.xhr = xhr;
3991      }
3992      method = resolveOption(this.options.method, files);
3993      url = resolveOption(this.options.url, files);
3994      xhr.open(method, url, true);
3995      xhr.withCredentials = !!this.options.withCredentials;
3996      response = null;
3997      handleError = (function(_this) {
3998        return function() {
3999          var _j, _len1, _results;
4000          _results = [];
4001          for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
4002            file = files[_j];
4003            _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
4004          }
4005          return _results;
4006        };
4007      })(this);
4008      updateProgress = (function(_this) {
4009        return function(e) {
4010          var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;
4011          if (e != null) {
4012            progress = 100 * e.loaded / e.total;
4013            for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
4014              file = files[_j];
4015              file.upload = {
4016                progress: progress,
4017                total: e.total,
4018                bytesSent: e.loaded
4019              };
4020            }
4021          } else {
4022            allFilesFinished = true;
4023            progress = 100;
4024            for (_k = 0, _len2 = files.length; _k < _len2; _k++) {
4025              file = files[_k];
4026              if (!(file.upload.progress === 100 && file.upload.b
4026ytesSent === file.upload.total)) {
4027                allFilesFinished = false;
4028              }
4029              file.upload.progress = progress;
4030              file.upload.bytesSent = file.upload.total;
4031            }
4032            if (allFilesFinished) {
4033              return;
4034            }
4035          }
4036          _results = [];
4037          for (_l = 0, _len3 = files.length; _l < _len3; _l++) {
4038            file = files[_l];
4039            _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
4040          }
4041          return _results;
4042        };
4043      })(this);
4044      xhr.onload = (function(_this) {
4045        return function(e) {
4046          var _ref;
4047          if (files[0].status === Dropzone.CANCELED) {
4048            return;
4049          }
4050          if (xhr.readyState !== 4) {
4051            return;
4052          }
4053          response = xhr.responseText;
4054          if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
4055            try {
4056              response = JSON.parse(response);
4057            } catch (_error) {
4058              e = _error;
4059              response = "Invalid JSON response from server.";
4060            }
4061          }
4062          updateProgress();
4063          if (!((200 <= (_ref = xhr.status) && _ref < 300))) {
4064            return handleError();
4065          } else {
4066            return _this._finished(files, response, e);
4067          }
4068        };
4069      })(this);
4070      xhr.onerror = (function(_this) {
4071        return function() {
4072          if (files[0].status === Dropzone.CANCELED) {
4073            return;
4074          }
4075          return handleError();
4076        };
4077      })(this);
4078      progressObj = (_ref = xhr.upload) != null ? _ref : xhr;
4079      progressObj.onprogress = updateProgress;
4080      headers = {
4081        "Accept": "application/json",
4082        "Cache-Control": "no-cache",
4083        "X-Requested-With": "XMLHttpRequest"
4084      };
4085      if (this.options.headers) {
4086        extend(headers, this.options.headers);
4087      }
4088      for (headerName in headers) {
4089        headerValue = headers[headerName];
4090        if (headerValue) {
4091          xhr.setRequestHeader(headerName, headerValue);
4092        }
4093      }
4094      formData = new FormData();
4095      if (this.options.params) {
4096        _ref1 = this.options.params;
4097        for (key in _ref1) {
4098          value = _ref1[key];
4099          formData.append(key, value);
4100        }
4101      }
4102      for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
4103        file = files[_j];
4104        this.emit("sending", file, xhr, formData);
4105      }
4106      if (this.options.uploadMultiple) {
4107        this.emit("sendingmultiple", files, xhr, formData);
4108      }
4109      if (this.element.tagName === "FORM") {
4110        _ref2 = this.element.querySelectorAll("input, textarea, select, button");
4111        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
4112          input = _ref2[_k];
4113          inputName = input.getAttribute("name");
4114          inputType = input.getAttribute("type");
4115          if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
4116            _ref3 = input.options;
4117            for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
4118              option = _ref3[_l];
4119              if (option.selected) {
4120                formData.append(inputName, option.value);
4121              }
4122            }
4123          } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
4124            formData.append(inputName, input.value);
4125          }
4126        }
4127      }
4128      for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {
4129        formData.append(this._getParamName(i), files[i], this._renameFilename(files[i].name));
4130      }
4131      return this.submitRequest(xhr, formData, files);
4132    };
4133
4134    Dropzone.prototype.submitRequest = function(xhr, formData, files) {
4135      return xhr.send(formData);
4136    };
4137
4138    Dropzone.prototype._finished = function(files, responseText, e) {
4139      var file, _i, _len;
4140      for (_i = 0, _len = files.length; _i < _len; _i++) {
4141        file = files[_i];
4142        file.status = Dropzone.SUCCESS;
4143        this.emit("success", file, responseText, e);
4144        this.emit("complete", file);
4145      }
4146      if (this.options.uploadMultiple) {
4147        this.emit("successmultiple", files, responseText, e);
4148        this.emit("completemultiple", files);
4149      }
4150      if (this.options.autoProcessQueue) {
4151        return this.processQueue();
4152      }
4153    };
4154
4155    Dropzone.prototype._errorProcessing = function(files, message, xhr) {
4156      var file, _i, _len;
4157      for (_i = 0, _len = files.length; _i < _len; _i++) {
4158        file = files[_i];
4159        file.status = Dropzone.ERROR;
4160        this.emit("error", file, message, xhr);
4161        this.emit("complete", file);
4162      }
4163      if (this.options.uploadMultiple) {
4164        this.emit("errormultiple", files, message, xhr);
4165        this.emit("completemultiple", files);
4166      }
4167      if (this.options.autoProcessQueue) {
4168        return this.processQueue();
4169      }
4170    };
4171
4172    return Dropzone;
4173
4174  })(Emitter);
4175
4176  Dropzone.version = "4.3.0";
4177
4178  Dropzone.options = {};
4179
4180  Dropzone.optionsForElement = function(element) {
4181    if (element.getAttribute("id")) {
4182      return Dropzone.options[camelize(element.getAttribute("id"))];
4183    } else {
4184      return void 0;
4185    }
4186  };
4187
4188  Dropzone.instances = [];
4189
4190  Dropzone.forElement = function(element) {
4191    if (typeof element === "string") {
4192      element = document.querySelector(element);
4193    }
4194    if ((element != null ? element.dropzone : void 0) == null) {
4195      throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
4196    }
4197    return element.dropzone;
4198  };
4199
4200  Dropzone.autoDiscover = true;
4201
4202  Dropzone.discover = function() {
4203    var checkElements, dropzone, dropzones, _i, _len, _results;
4204    if (document.querySelectorAll) {
4205      dropzones = document.querySelectorAll(".dropzone");
4206    } else {
4207      dropzones = [];
4208      checkElements = function(elements) {
4209        var el, _i, _len, _results;
4210        _results = [];
4211        for (_i = 0, _len = elements.length; _i < _len; _i++) {
4212          el = elements[_i];
4213          if (/(^| )dropzone($| )/.test(el.className)) {
4214            _results.push(dropzones.push(el));
4215          } else {
4216            _results.push(void 0);
4217          }
4218        }
4219        return _results;
4220      };
4221      checkElements(document.getElementsByTagName("div"));
4222      checkElements(document.getElementsByTagName("form"));
4223    }
4224    _results = [];
4225    for (_i = 0, _len = dropzones.length; _i < _len; _i++) {
4226      dropzone = dropzones[_i];
4227      if (Dropzone.optionsForElement(dropzone) !== false) {
4228        _results.push(new Dropzone(dropzone));
4229      } else {
4230        _results.push(void 0);
4231      }
4232    }
4233    return _results;
4234  };
4235
4236  Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
4237
4238  Dropzone.isBrowserSupported = function() {
4239    var capableBrowser, regex, _i, _len, _ref;
4240    capableBrowser = true;
4241    if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
4242      if (!("classList" in document.createElement("a"))) {
4243        capableBrowser = false;
4244      } else {
4245        _ref = Dropzone.blacklistedBrowsers;
4246        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
4247          regex = _ref[_i];
4248          if (regex.test(navigator.userAgent)) {
4249            capableBrowser = false;
4250            continue;
4251          }
4252        }
4253      }
4254    } else {
4255      capableBrowser = false;
4256    }
4257    return capableBrowser;
4258  };
4259
4260  without = function(list, rejectedItem) {
4261    var item, _i, _len, _results;
4262    _results = [];
4263    for (_i = 0, _len = list.length; _i < _len; _i++) {
4264      item = list[_i];
4265      if (item !== rejectedItem) {
4266        _results.push(item);
4267      }
4268    }
4269    return _results;
4270  };
4271
4272  camelize = function(str) {
4273    return str.replace(/[\-_](\w)/g, function(match) {
4274      return match.charAt(1).toUpperCase();
4275    });
4276  };
4277
4278  Dropzone.createElement = function(string) {
4279    var div;
4280    div = document.createElement("div");
4281    div.innerHTML = string;
4282    return div.childNodes[0];
4283  };
4284
4285  Dropzone.elementInside = function(element, container) {
4286    if (element === container) {
4287      return true;
4288    }
4289    while (element = element.parentNode) {
4290      if (element === container) {
4291        return true;
4292      }
4293    }
4294    return false;
4295  };
4296
4297  Dropzone.getElement = function(el, name) {
4298    var element;
4299    if (typeof el === "string") {
4300      element = document.querySelector(el);
4301    } else if (el.nodeType != null) {
4302      element = el;
4303    }
4304    if (element == null) {
4305      throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
4306    }
4307    return element;
4308  };
4309
4310  Dropzone.getElements = function(els, name) {
4311    var e, el, elements, _i, _j, _len, _len1, _ref;
4312    if (els instanceof Array) {
4313      elements = [];
4314      try {
4315        for (_i = 0, _len = els.length; _i < _len; _i++) {
4316          el = els[_i];
4317          elements.push(this.getElement(el, name));
4318        }
4319      } catch (_error) {
4320        e = _error;
4321        elements = null;
4322      }
4323    } else if (typeof els === "string") {
4324      elements = [];
4325      _ref = document.querySelectorAll(els);
4326      for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
4327        el = _ref[_j];
4328        elements.push(el);
4329      }
4330    } else if (els.nodeType != null) {
4331      elements = [els];
4332    }
4333    if (!((elements != null) && elements.length)) {
4334      throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
4335    }
4336    return elements;
4337  };
4338
4339  Dropzone.confirm = function(question, accepted, rejected) {
4340    if (window.confirm(question)) {
4341      return accepted();
4342    } else if (rejected != null) {
4343      return rejected();
4344    }
4345  };
4346
4347  Dropzone.isValidFile = function(file, acceptedFiles) {
4348    var baseMimeType, mimeType, validType, _i, _len;
4349    if (!acceptedFiles) {
4350      return true;
4351    }
4352    acceptedFiles = acceptedFiles.split(",");
4353    mimeType = file.type;
4354    baseMimeType = mimeType.replace(/\/.*$/, "");
4355    for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
4356      validType = acceptedFiles[_i];
4357      validType = validType.trim();
4358      if (validType.charAt(0) === ".") {
4359        if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
4360          return true;
4361        }
4362      } else if (/\/\*$/.test(validType)) {
4363        if (baseMimeType === validType.replace(/\/.*$/, "")) {
4364          return true;
4365        }
4366      } else {
4367        if (mimeType === validType) {
4368          return true;
4369        }
4370      }
4371    }
4372    return false;
4373  };
4374
4375  if (typeof jQuery !== "undefined" && jQuery !== null) {
4376    jQuery.fn.dropzone = function(options) {
4377      return this.each(function() {
4378        return new Dropzone(this, options);
4379      });
4380    };
4381  }
4382
4383  if (typeof module !== "undefined" && module !== null) {
4384    module.exports = Dropzone;
4385  } else {
4386    window.Dropzone = Dropzone;
4387  }
4388
4389  Dropzone.ADDED = "added";
4390
4391  Dropzone.QUEUED = "queued";
4392
4393  Dropzone.ACCEPTED = Dropzone.QUEUED;
4394
4395  Dropzone.UPLOADING = "uploading";
4396
4397  Dropzone.PROCESSING = Dropzone.UPLOADING;
4398
4399  Dropzone.CANCELED = "canceled";
4400
4401  Dropzone.ERROR = "error";
4402
4403  Dropzone.SUCCESS = "success";
4404
4405
4406  /*
4407  
4408  Bugfix for iOS 6 and 7
4409  Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
4410  based on the work of https://github.com/stomita/ios-imagefile-megapixel
4411   */
4412
4413  detectVerticalSquash = function(img) {
4414    var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
4415    iw = img.naturalWidth;
4416    ih = img.naturalHeight;
4417    canvas = document.createElement("canvas");
4418    canvas.width = 1;
4419    canvas.height = ih;
4420    ctx = canvas.getContext("2d");
4421    ctx.drawImage(img, 0, 0);
4422    data = ctx.getImageData(0, 0, 1, ih).data;
4423    sy = 0;
4424    ey = ih;
4425    py = ih;
4426    while (py > sy) {
4427      alpha = data[(py - 1) * 4 + 3];
4428      if (alpha === 0) {
4429        ey = py;
4430      } else {
4431        sy = py;
4432      }
4433      py = (ey + sy) >> 1;
4434    }
4435    ratio = py / ih;
4436    if (ratio === 0) {
4437      return 1;
4438    } else {
4439      return ratio;
4440    }
4441  };
4442
4443  drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
4444    var vertSquashRatio;
4445    vertSquashRatio = detectVerticalSquash(img);
4446    return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
4447  };
4448
4449
4450  /*
4451   * contentloaded.js
4452   *
4453   * Author: Diego Perini (diego.perini at gmail.com)
4454   * Summary: cross-browser wrapper for DOMContentLoaded
4455   * Updated: 20101020
4456   * License: MIT
4457   * Version: 1.2
4458   *
4459   * URL:
4460   * http://javascript.nwbox.com/ContentLoaded/
4461   * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
4462   */
4463
4464  contentLoaded = function(win, fn) {
4465    var add, doc, done, init, poll, pre, rem, root, top;
4466    done = false;
4467    top = true;
4468    doc = win.document;
4469    root = doc.documentElement;
4470    add = (doc.addEventListener ? "addEventListener" : "attachEvent");
4471    rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
4472    pre = (doc.addEventListener ? "" : "on");
4473    init = function(e) {
4474      if (e.type === "readystatechange" && doc.readyState !== "complete") {
4475        return;
4476      }
4477      (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
4478      if (!done && (done = true)) {
4479        return fn.call(win, e.type || e);
4480      }
4481    };
4482    poll = function() {
4483      var e;
4484      try {
4485        root.doScroll("left");
4486      } catch (_error) {
4487        e = _error;
4488        setTimeout(poll, 50);
4489        return;
4490      }
4491      return init("poll");
4492    };
4493    if (doc.readyState !== "complete") {
4494      if (doc.createEventObject && root.doScroll) {
4495        try {
4496          top = !win.frameElement;
4497        } catch (_error) {}
4498        if (top) {
4499          poll();
4500        }
4501      }
4502      doc[add](pre + "DOMContentLoaded", init, false);
4503      doc[add](pre + "readystatechange", init, false);
4504      return win[add](pre + "load", init, false);
4505    }
4506  };
4507
4508  Dropzone._autoDiscoverFunction = function() {
4509    if (Dropzone.autoDiscover) {
4510      return Dropzone.discover();
4511    }
4512  };
4513
4514  contentLoaded(window, Dropzone._autoDiscoverFunction);
4515
4516}).call(this);
4517$(document).ready(function() {
4518
4519
4520	function base64ToArrayBuffer (base64) {
4521    base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
4522    var binaryString = atob(base64);
4523    var len = binaryString.length;
4524    var bytes = new Uint8Array(len);
4525    for (var i = 0; i < len; i++) {
4526        bytes[i] = binaryString.charCodeAt(i);
4527    }
4528    return bytes.buffer;
4529	}
4530	
4531
4532	// transform cropper dataURI output to a Blob which Dropzone accepts
4533	var dataURItoBlob = function (dataURI) {
4534    var byteString = atob(dataURI.split(',')[1]);
4535    var ab = new ArrayBuffer(byteString.length);
4536    var ia = new Uint8Array(ab);
4537    for (var i = 0; i < byteString.length; i++) {
4538    	ia[i] = byteString.charCodeAt(i);
4539    }
4540    return new Blob([ab], {type: 'image/jpeg'});
4541	};
4542
4543	Dropzone.autoDiscover = false;
4544	
4545	if($('#my-dropzone-container').length){
4546		
4547		var myDropzone = new Dropzone("div#my-dropzone-container", {
4548				url: "https://www.mdmarchive.co.uk/includes/inc_upload_images.php",
4549			  autoProcessQueue: false,
4550			  parallelUploads: 1,
4551			  uploadMultiple: false,
4552			  maxFiles: 1,
4553			  addRemoveLinks: true,
4554				dictDefaultMessage: "Click to Add Image",
4555				acceptedFiles: ".jpg,.jpeg,.png"
4556	    }
4557		);
4558	
4559		// https://github.com/enyo/dropzone/issues/781
4560	
4561		myDropzone.on('addedfile', function (file) {
4562	    // ignore files which were already cropped and re-rendered
4563	    // to prevent infinite loop
4564	    if (file.cropped) {
4565	    	return;
4566	    }
4567	
4568	    var $img = $('<img>');
4569	
4570	    // cache filename to re-assign it to cropped file
4571	    var cachedFilename = file.name;
4572	    // remove not cropped file from dropzone (we will replace it later)
4573	    myDropzone.removeFile(file);
4574	
4575	    // dynamically create modals to allow multiple files processing
4576	    // modal window template
4577	    var modalTemplate =
4578	      '<div class="modal fade" tabindex="-1" role="dialog">' +
4579	        '<div class="modal-dialog modal-lg" role="document">' +
4580	          '<div class="modal-content">' +
4581	          '<div class="modal-header">' +
4582							
4583	            '<button type="button" class="modal_close" data-bs-dismiss="modal" aria-label="Close"><svg class="close_artbutton"><use xlink:href="#close_artbutton"/></svg></button>' +
4584	            
4585	          '</div>' +
4586	          '<div class="modal-body">' +
4587	          
4588	          	'<div style="margin-bottom:10px;">' +
4589	          
4590	            '<button type="button" class="btn btn-default rotate-left"><span class="fa fa-rotate-left"></span></button>' +
4591	            '<button type="button" class="btn btn-default rotate-right"><span class="fa fa-rotate-right"></span></button>' +
4592
4593							'<button type="button" class="btn btn-default zoom-in"><span class="fa fa-search-plus"></span></button>' +
4594							'<button type="button" class="btn btn-default zoom-out"><span class="fa fa-search-minus"></span></button>' +
4595
4596	            '<button type="button" class="btn btn-default reset">Reset</button>' +
4597	
4598	            '<button type="button" class="btn btn-primary crop-upload">Upload</button>' +
4599	            
4600	          	'</div>' +  
4601	          
4602	            '<div class="image-container"></div>' +
4603	          '</div>' +
4604	          // '<div class="modal-footer">' +
4605
4606	          // '</div>' +
4607	          '</div>' +
4608	        '</div>' +
4609	      '</div>';
4610	
4611	    var $cropperModal = $(modalTemplate);
4612	
4613	    // initialize FileReader which reads uploaded file
4614	    var reader = new FileReader();
4615	    
4616	    
4617	    
4618	    reader.onloadend = function () {
4619
4620	      var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(this.result));
4621        var exifOrientation = exif.Orientation;
4622        
4623	      $cropperModal.find('.image-container').html($img);
4624	      
4625	      
4626	    	var img = new Image;
4627				//set img src based on file input reader
4628				img.src = reader.result;
4629				//create canvas and resize img if > 1024 before using cropper's
4630				//'getCroppedCanvas' because big imgs give error in iOS
4631				
4632				
4633				img.onload = function() {
4634				
4635		      // console.log(img.width);
4636		      
4637		      // lets change the cutoff to 1365 which is 1024 * 4/3
4638		      
4639					if (img.width > 1024 || img.height > 1024) {
4640					
4641					  var canvas = document.createElement("canvas"),
4642					      ctx = canvas.getContext("2d"),
4643					      factor;
4644					  img.width >
4644 img.height ? factor = img.width / 1024 : factor = img.height / 1024;
4645					  
4646					  
4647					  console.log('width = ' + img.width);
4648					  console.log('height = ' + img.height);
4649					  console.log('factor = ' + factor);
4650					  
4651					  // say for instance height is 5184 then factor is 5184 / 1024 = 5.0625 so we need to reduce the width by 5.0625
4652					  
4653					  // remember this only gets triggered if the image is larger than 1024
4654					  
4655					  console.log('orientation = ' + exifOrientation);
4656					  
4657					  canvas.width  = img.width  / factor;
4658					  canvas.height = img.height / factor;
4659				  	
4660					  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
4661
4662					  $img.attr('src', canvas.toDataURL());
4663					}
4664					else {
4665	      		$img.attr('src', reader.result);
4666					}
4667					img = null;
4668		    };
4669		    
4670	
4671	
4672	
4673			function rotateImage(angle) {
4674			  var contData = cropper.getContainerData();
4675			  
4676			  cropper.setCropBoxData({
4677				    width: 2, height: 2, top: (contData.height/ 2) - 1, left: (contData.width / 2) - 1
4678				});
4679			  
4680				cropper.rotate(angle);
4681				
4682				var canvData = cropper.getCanvasData();
4683				var newWidth = canvData.width * (contData.height / canvData.height);
4684				   
4685				if (newWidth >= contData.width) {
4686				    var newHeight = canvData.height * (contData.width / canvData.width);
4687				    var newCanvData = {
4688				        height: newHeight,
4689				        width: contData.width,
4690				        top: (contData.height - newHeight) / 2,
4691				        left: 0
4692				    };
4693				} else {
4694				    var newCanvData = {
4695				        height: contData.height,
4696				        width: newWidth,
4697				        top: 0,
4698				        left: (contData.width - newWidth) / 2
4699				    };
4700				}   
4701				cropper.setCanvasData(newCanvData);
4702				cropper.setCropBoxData(newCanvData);
4703			}	
4704	
4705	
4706		
4707			// https://github.com/fengyuanchen/cropper
4708			// https://github.com/fengyuanchen/cropperjs
4709	    var cropper = {};
4710	    $cropperModal
4711	      .modal('show')
4712	      .on("shown.bs.modal", function () {
4713	        cropper = new Cropper($img.get(0), {
4714	          autoCropArea: 1,
4715	          movable: false,
4716	          viewMode: 2,
4717	          ready: function () {
4718	        		original_data = cropper.getData();
4719					  }
4720	          
4721	        });
4722	      })
4723	      .on('click', '.crop-upload', function () {
4724	        // get cropped image data
4725	        // var blob = cropper.getCroppedCanvas().toDataURL();
4726	        var blob = cropper.getCroppedCanvas().toDataURL('image/jpeg', 1.0);
4727	        // transform it to Blob object
4728	        var newFile = dataURItoBlob(blob);
4729	        // set 'cropped to true' (so that we don't get to that listener again)
4730	        newFile.cropped = true;
4731	        // assign original filename
4732	        newFile.name = cachedFilename;
4733	
4734	        // add cropped file to dropzone
4735	        myDropzone.addFile(newFile);
4736	        // upload cropped file with dropzone
4737	        myDropzone.processQueue();
4738	        $cropperModal.modal('hide');
4739	        
4740	        $('.dz-message').html('<span class="orange">Add another Image</span>');
4741	        
4742	      })
4743	      .on('click', '.rotate-right', function () {
4744	        // https://stackoverflow.com/questions/30845973/fengyuanchen-cropper-how-to-fit-image-into-canvas-if-rotated
4745	        // this function is just above
4746	        rotateImage(90);
4747	      })
4748	      .on('click', '.rotate-left', function () {
4749	        rotateImage(-90);
4750	      })
4751	      .on('click', '.zoom-in', function () {
4752	        cropper.zoom(0.1);
4753	      })
4754	      .on('click', '.zoom-out', function () {
4755	        cropper.zoom(-0.1);
4756	      })
4757	      .on('click', '.reset', function () {
4758	        cropper.reset();
4759	      })	    
4760				
4761	    };
4762	    // read uploaded file (triggers code above)
4763	    reader.readAsDataURL(file);
4764	
4765	      
4766		});
4767		
4768		myDropzone.on("success", function(file, response) {
4769		
4770			// check response for error
4771			
4772	    console.log(response);
4773		
4774			myDropzone.removeFile(file);
4775			
4776	    $.ajax({  
4777		    type: 'GET',
4778		    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_images.php', 
4779		    success: function(response) {
4780		    	$('.upload_images_holder').html(response);
4781		    }
4782			});
4783			
4784	    
4785		});
4786		
4787	
4788	
4789
4790	}
4791
4792
4793});$(document).ready(function() {
4794
4795	const keyword_id = $('#keyword_id').val();
4796	const location_id = $('#location_id').val();
4797
4798	// this one comes from the keyword page
4799	
4800	$("input.typeahead_locations_upload").typeahead({
4801			autoSelect: false,
4802			fitToElement: true,
4803			source:  function (query, process) {
4804				return $.get('https://www.mdmarchive.co.uk/proc/proc_location_lookup.php', { query: query }, function (data) {
4805					// let's see what's returned
4806					console.log(data);
4807					data = $.parseJSON(data);
4808					return process(data);
4809				});
4810			},
4811			updater: function (item) {
4812	
4813				 $.ajax({  
4814					type: 'GET',
4815					url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4816					data: {
4817						location_lookup_value : item.name,
4818						location_lookup_id : item.id,
4819						keyword_id : keyword_id
4820					},
4821					beforeSend: function() {
4822						$('#location_response_loading').slideDown( "slow", function() {});
4823					},
4824					success: function(response) {
4825						$('#location_response').html(response);
4826						$('#location_value').val('');
4827						$('#location_id').val('');
4828						
4829						$('#location_response_loading').slideUp( "fast", function() {});
4830					}
4831				});
4832						
4833			},
4834			matcher: function (item) {
4835				return true;
4836			}
4837	});
4838	
4839	
4840	// this one comes from the location page
4841	
4842	$("input.typeahead_location_keyword_upload").typeahead({
4843			autoSelect: false,
4844			fitToElement: true,
4845			source:  function (query, process) {
4846				return $.get('https://www.mdmarchive.co.uk/proc/proc_keyword_lookup_location.php', { query: query }, function (data) {
4847					// let's see what's returned
4848					console.log(data);
4849					data = $.parseJSON(data);
4850					return process(data);
4851				});
4852			},
4853			updater: function (item) {
4854	
4855				 $.ajax({  
4856					type: 'GET',
4857					url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4858					data: {
4859						keyword_lookup_value : item.name,
4860						keyword_lookup_id : item.id,
4861						location_id : location_id
4862					},
4863					beforeSend: function() {
4864						$('#location_response_loading').slideDown( "slow", function() {});
4865					},
4866					success: function(response) {
4867						$('#location_response').html(response);
4868						$('#location_value').val('');
4869						$('#location_id').val('');
4870						
4871						$('#location_response_loading').slideUp( "fast", function() {});
4872					}
4873				});
4874						
4875			},
4876			matcher: function (item) {
4877				return true;
4878			}
4879	});
4880	
4881	
4882	
4883	
4884	
4885	
4886	
4887	
4888	
4889	
4890	
4891	$(document).on('click touch', '.locationkeyword_delete', function(e) {
4892		e.preventDefault();
4893		
4894		if (!confirm('Are you sure you want to delete this location?')) {
4895			return;
4896		}
4897		
4898		$.ajax({  
4899			type: 'GET',
4900			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4901			data: {
4902				locationkeyword_delete : $(this).data('locationkeyword'),
4903				keyword_id : keyword_id,
4904			},
4905			success: function(response) {
4906				$('#location_response').html(response);
4907			}
4908		});
4909	});
4910	
4911	
4912	$(document).on('click touch', '.location_error', function(e) {
4913		e.preventDefault();
4914		 $.ajax({  
4915			type: 'GET',
4916			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4917			data: {
4918				location_error_location : $(this).data('location'),
4919				location_error_locationkeyword : $(this).data('locationkeyword'),
4920				keyword_id : keyword_id,
4921			},
4922			success: function(response) {
4923				$('#location_response').html(response);
4924			}
4925		});
4926	});
4927	
4928
4929	$(document).on('click touch', '#location_address_submit', function(e) {
4930		e.preventDefault();
4931		 $.ajax({  
4932			type: 'GET',
4933			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4934			data: {
4935				address_1 : $('#address_1').val(),
4936				address_2 : $('#address_2').val(),
4937				town : $('#town').val(),
4938				postcode : $('#postcode').val(),
4939				year : $('#year').val(),
4940				location_update_id : $('#location_update_id').val(),
4941				keyword_id : keyword_id,
4942			},
4943			success: function(response) {
4944				$('#location_response').html(response);
4945			}
4946		});
4947	});
4948	
4949	
4950	$(document).on('change', '.location_keyword_year_edit', function(e) {
4951		e.preventDefault();
4952		$.ajax({  
4953			type: 'GET',
4954			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4955			data: {
4956				locationkeyword_edit : $(this).data('locationkeyword'),
4957				locationkeyword_year : $(this).val(),
4958				keyword_id : keyword_id,
4959			},
4960			success: function(response) {
4961				$('#location_response').html(response);
4962			}
4963		});
4964	});
4965	
4966	
4967	
4968	
4969	
4970	
4971	
4972	
4973	
4974	
4975	
4976	
4977	
4978	
4979	$(document).on('click touch', '.keyword_location_delete', function(e) {
4980		e.preventDefault();
4981		
4982		if (!confirm('Are you sure you want to remove this place from this location?')) {
4983			return;
4984		}
4985		
4986		$.ajax({  
4987			type: 'GET',
4988			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
4989			data: {
4990				keywordlocation_delete : $(this).data('keywordlocation'),
4991				location_id : location_id,
4992			},
4993			success: function(response) {
4994				$('#location_response').html(response);
4995			}
4996		});
4997	});
4998	
4999	$(document).on('click touch', '#keyword_year_submit', function(e) {
5000		e.preventDefault();
5001		 $.ajax({  
5002			type: 'GET',
5003			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
5004			data: {
5005				year : $('#year').val(),
5006				keyword_update_id : $('#keyword_update_id').val(),
5007				location_id : location_id,
5008			},
5009			success: function(response) {
5010				$('#location_response').html(response);
5011			}
5012		});
5013	});
5014	
5015	
5016	$(document).on('change', '.keyword_location_year_edit', function(e) {
5017		e.preventDefault();
5018		$.ajax({  
5019			type: 'GET',
5020			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
5021			data: {
5022				keywordlocation_edit : $(this).data('keywordlocation'),
5023				keywordlocation_year : $(this).val(),
5024				location_id : location_id,
5025			},
5026			success: function(response) {
5027				$('#location_response').html(response);
5028			}
5029		});
5030	});
5031	
5032	
5033	$(document).on('click touch', '#location_address_update', function(e) {
5034		e.preventDefault();
5035		 $.ajax({  
5036			type: 'GET',
5037			url: 'https://www.mdmarchive.co.uk/includes/inc_upload_locations.php', 
5038			data: {
5039				address_1 : $('#address_1').val(),
5040				address_2 : $('#address_2').val(),
5041				town : $('#town').val(),
5042				postcode : $('#postcode').val(),
5043				google_maps_url : $('#google_maps_url').val(),
5044				location_id : location_id,
5045			},
5046			success: function(response) {
5047				// $('#location_response').html(response);
5048				location.reload();
5049			}
5050		});
5051	});
5052	
5053	
5054	
5055	
5056	
5057});$(document).ready(function() {
5058
5059
5060	
5061	
5062	
5063
5064	$("input.typeahead_keywords_upload").typeahead({
5065  		autoSelect: false,
5066  		fitToElement: true,
5067	    source:  function (query, process) {
5068		  	return $.get('https://www.mdmarchive.co.uk/proc/proc_keyword_lookup_upload.php', { query: query }, function (data) {
5069		  		// let's see what's returned
5070		    	console.log(data);
5071		      data = $.parseJSON(data);
5072			    return process(data);
5073			  });
5074			},
5075	    updater: function (item) {
5076	      // console.log(item.id);
5077	      // console.log(item.name);
5078	      // $('#keyword_id').val(item.id);
5079	      
5080	      // auto submit on select
5081	      // $('#keyword_button').trigger('click');
5082	      // populates input field
5083	      // return item;
5084				
5085				
5086				
5087				var ajaxStart = performance.now();
5088				
5089				$.ajax({
5090				
5091					type: 'GET',
5092					url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php',
5093					data: {
5094						keyword_value: item.name,
5095						keyword_id: item.id
5096					},
5097					beforeSend: function() {
5098						console.log('[keyword ajax] beforeSend', Math.round(performance.now() - ajaxStart)+'ms');
5099						$('#keyword_response_loading').show();
5100					},
5101					success: function(response) {
5102						console.log('[keyword ajax] success', Math.round(performance.now() - ajaxStart)+'ms');
5103						$('#keyword_response').html(response);
5104						$('#keyword_value').val('');
5105						$('#keyword_id').val('');
5106						$('#keyword_response_loading').hide();
5107					},
5108					error: function(xhr, status, error) {
5109						console.log('[keyword ajax] error', status, error, Math.round(performance.now() - ajaxStart)+'ms');
5110						$('#keyword_response_loading').hide();
5111					}
5112				
5113				});
5114				
5115				
5116			  /*
5117		 		$.ajax({  
5118			    type: 'GET',
5119			    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5120			    data: {
5121			    	keyword_value : item.name,
5122			    	keyword_id : item.id
5123			    },
5124					beforeSend: function() {
5125						$('#keyword_response_loading').slideDown( "slow", function() {});
5126					},
5127			    success: function(response) {
5128			    	$('#keyword_response').html(response);
5129			    	$('#keyword_value').val('');
5130			    	$('#keyword_id').val('');
5131						
5132						$('#keyword_response_loading').slideUp( "fast", function() {});
5133			    }
5134				});
5135			  */
5136				
5137				
5138	    },
5139		  matcher: function (item) {
5140		    return true;
5141		  }
5142	});
5143	
5144	
5145	$(document).on('click touch', '#keyword_button', function(e) {
5146 		$.ajax({  
5147	    type: 'GET',
5148	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5149	    data: {
5150	    	keyword_value : $('#keyword_value').val(),
5151	    	keyword_id : $('#keyword_id').val()
5152	    },
5153	    success: function(response) {
5154	    	$('#keyword_response').html(response);
5155	    	$('#keyword_value').val('');
5156	    	$('#keyword_id').val('');
5157	    }
5158		});
5159	});
5160	
5161	
5162	
5163	
5164	
5165	
5166	
5167	
5168	
5169	$(document).on('click touch', '.upload_add_new_keyword_people_button', function(e) {
5170 		$.ajax({  
5171	    type: 'GET',
5172	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5173	    data: {
5174	    	keyword_add_new : $('.upload_add_new_keyword_people').val()
5175	    },
5176	    success: function(response) {
5177	    	$('#keyword_response').html(response);
5178	    	$('.upload_add_new_keyword_people').val('');
5179			  $('.upload_add_new_people_hider').slideToggle( "fast", function() {
5180			    // Animation complete.
5181			  });
5182	    }
5183		});
5184	});
5185	
5186	
5187	$(document).on('click touch', '.upload_add_new_keyword_places_button', function(e) {
5188 		$.ajax({  
5189	    type: 'GET',
5190	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5191	    data: {
5192	    	keyword_add_new : $('.upload_add_new_keyword_places').val(),
5193	    	keyword_add_new_place : '1'
5194	    },
5195	    success: function(response) {
5196	    	$('#keyword_response').html(response);
5197	    	$('.upload_add_new_keyword_places').val('');
5198			  $('.upload_add_new_places_hider').slideToggle( "fast", function() {
5199			    // Animation complete.
5200			  });
5201	    }
5202		});
5203	});
5204	
5205	
5206
5207
5208	$(document).on('click touch', '.keyword_delete', function(e) {
5209		e.preventDefault();
5210		
5211		var keyword_to_delete = $(this).data('keyword');
5212		
5213		$(this).parent().fadeOut(400, function() {
5214			$.ajax({  
5215				type: 'GET',
5216				url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5217				data: {
5218					keyword_delete : keyword_to_delete
5219				},
5220				success: function(response) {
5221					$('#keyword_response').html(response);
5222				}
5223			});
5224		});
5225	});
5226
5227	$(document).on('click touch', '.keyword_type', function(e) {
5228		e.preventDefault();
5229 		$.ajax({  
5230	    type: 'GET',
5231	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5232	    data: {
5233	    	keyword_set_type : $(this).data('keyword'),
5234				keyword_type : $(this).data('keywordtype'),
5235				keyword_subtype : $(this).data('keywordsubtype'),
5236	    },
5237	    success: function(response) {
5238	    	$('#keyword_response').html(response);
5239	    }
5240		});
5241	});
5242
5243	$(document).on('click touch', '.keyword_district', function(e) {
5244		e.preventDefault();
5245 		$.ajax({  
5246	    type: 'GET',
5247	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5248	    data: {
5249	    	keyword_set_district : $(this).data('keyword'),
5250	    	keyword_district : $(this).data('keyworddistrict'),
5251	    },
5252	    success: function(response) {
5253	    	$('#keyword_response').html(response);
5254	    }
5255		});
5256	});
5257
5258	$(document).on('click touch', '.keyword_error', function(e) {
5259		e.preventDefault();
5260 		$.ajax({  
5261	    type: 'GET',
5262	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_keywords.php', 
5263	    data: {
5264	    	keyword_error_keyword : $(this).data('keyword'),
5265	    	keyword_error_product : $(this).data('keywordproduct'),
5266	    },
5267	    success: function(response) {
5268	    	$('#keyword_response').html(response);
5269	    }
5270		});
5271	});
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287	// http://itsolutionstuff.com/post/dynamic-autocomplete-search-using-bootstrap-typeahead-js-exampleexample.html
5288
5289	// https://github.com/bassjobsen/Bootstrap-3-Typeahead/issues
5290	// https://github.com/bassjobsen/Bootstrap-3-Typeahead/issues/278
5291
5292
5293});$(document).ready(function() {
5294
5295
5296	$("#upload_form").validate({
5297  	
5298  	rules: {
5299	    date: {
5300	      required: true,
5301      	remote: "https://www.mdmarchive.co.uk/includes/inc_upload_date.php"
5302	    },
5303	    keyword_value: {
5304      	required:  function(element) {
5305      		if ($("#at_least_one_tag").length) {
5306      			return false;
5307      		}
5308      		else {
5309      			return true;
5310      		}
5311      	}
5312	    },
5313	    media_link: {
5314      	required: true
5315	    }
5316	  }
5317	
5318	});
5319
5320
5321
5322
5323	$(document).on('click touch', '.upload_carry_on_button', function(e) {
5324		e.preventDefault();
5325		$('.partial_complete_message').slideUp();
5326	});
5327
5328
5329
5330
5331	$('.upload_format').on('change', function()	{
5332		var data = $(this).val();
5333		
5334		// revalidate on change rather than focusout
5335		$(this).valid(); 
5336		
5337 		$.ajax({  
5338	    type: 'GET',
5339	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_format.php', 
5340	    data: { format : data },
5341	    success: function(response) {
5342	    }
5343		});
5344	});
5345
5346	$('.upload_date').on('input', function()	{
5347		var data = $(this).val();
5348 		$.ajax({  
5349	    type: 'GET',
5350	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_date.php', 
5351	    data: { date : data },
5352	    success: function(response) {
5353	    }
5354		});
5355	});
5356
5357
5358
5359	$("input[name=product_type]").on("change", function() {
5360		var data = $(this).val();
5361 		$.ajax({  
5362	    type: 'GET',
5363	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_product_type.php', 
5364	    data: { product_type : data },
5365	    success: function(response) {
5366	    }
5367		});
5368    $(".product_type_result").hide();
5369    $("#product_type_result_"+data).show();
5370  });
5371
5372
5373
5374
5375	$(document).on('click touch', '.image_remove', function(e) {
5376		e.preventDefault();
5377 		$.ajax({  
5378	    type: 'GET',
5379	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_images.php', 
5380	    data: {
5381	    	image_delete : $(this).data('image')
5382	    },
5383	    success: function(response) {
5384	    	$('.upload_images_holder').html(response);
5385	    }
5386		});
5387	});
5388
5389
5390	$('#media_link_video').on('input', function()	{
5391		var data = $(this).val();
5392 		$.ajax({  
5393	    type: 'GET',
5394	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_media_link_video.php', 
5395	    data: { media_link_video : data },
5396	    success: function(response) {
5397	    	$('#media_link_video_repsonse').html(response);
5398	    }
5399		});
5400	});
5401
5402
5403	$('#media_link_audio').on('input', function()	{
5404		var data = $(this).val();
5405 		$.ajax({  
5406	    type: 'GET',
5407	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_media_link_audio.php', 
5408	    data: { media_link_audio : data },
5409	    success: function(response) {
5410	    	$('#media_link_audio_repsonse').html(response);
5411	    }
5412		});
5413	});
5414
5415
5416
5417
5418	$("#upload_form input:text").keypress(function(event) {
5419	  if (event.keyCode == 13) {
5420	    document.activeElement.blur();
5421	    event.preventDefault();
5422	    return false;
5423	  }
5424  });
5425
5426	$('.upload_story').on('blur', function () {
5427		var data = $(this).val();
5428		
5429		
5430 		$.ajax({  
5431	    type: 'POST',
5432	    url: 'https://www.mdmarchive.co.uk/includes/inc_upload_story.php', 
5433	    data: { story : data },
5434	    success: function(response) {
5435	    
5436				console.log(response);
5437	    }
5438		});
5439	});
5440
5441
5442
5443
5444
5445});$(document).ready(function() {
5446
5447
5448$(document).on('click touch', '.exhibition_artefact_skip', function(e) {
5449	e.preventDefault();
5450	var $this = $(this);
5451	
5452	var seo_link = $this.attr('href');
5453	var url = $this.data('url');
5454	
5455	// if it's from a modal
5456	if($('#dynamicmodal').hasClass('show')){
5457
5458		$('#dynamicmodal').slideUp( "slow", function() {
5459
5460			$(this).find(".modal-body").load(url);
5461			$( "#dynamicmodal" ).slideDown( "slow", function() {
5462			
5463				window.history.replaceState(null, null, seo_link);
5464				
5465			});
5466		});
5467
5468	}
5469});
5470
5471
5472	/*
5473	$(document).on('click touchend', '.exhibition_expand', function(e) {
5474		e.preventDefault();
5475	  var $this = $(this);
5476	  
5477		$this.parent('.exhibition_story_short').hide( "slow", function() {
5478			$this.parent().next().show( "fast", function() {
5479	    	$('.grid').isotope('destroy');
5480	    	$('.grid').isotope({
5481			    itemSelector: '.grid-item',
5482			    percentPosition: true,
5483				  masonry: {
5484				    columnWidth: '.grid-sizer'
5485				  }
5486			  });
5487		  });
5488	  });
5489
5490	});
5491	
5492	$(document).on('click touchend', '.exhibition_contract', function(e) {
5493		e.preventDefault();
5494	  var $this = $(this);
5495	  
5496		$this.parent('.exhibition_story_long').hide( "slow", function() {
5497			$this.parent().prev().show( "fast", function() {
5498	    	$('.grid').isotope('destroy');
5499	    	$('.grid').isotope({
5500			    itemSelector: '.grid-item',
5501			    percentPosition: true,
5502				  masonry: {
5503				    columnWidth: '.grid-sizer'
5504				  }
5505			  });
5506		  });
5507	  });
5508
5509	});
5510	*/
5511
5512
5513
5514
5515
5516
5517	/*
5518	$(document).on('click touch', '.add_to_exhibition', function(e) {
5519	  var $this = $(this);
5520		e.preventDefault();
5521		
5522		// if it's from a modal
5523		if($('#dynamicmodal').hasClass('in')){
5524	
5525			$('#dynamicmodal').slideUp( "slow", function() {
5526
5527		 		$.ajax({  
5528			    type: 'GET',
5529			    url: '/proc_exhibition_add.php', 
5530			    data: {
5531			    	product : $this.data('product'),
5532			    	exhibition : $this.data('exhibition'),
5533			    },
5534			    success: function(response) {
5535			    	$('#dynamicmodal .modal-body').html(response);
5536			    	$( "#dynamicmodal" ).slideDown( "slow", function() {
5537			    	
5538			    	});
5539			    }
5540				});
5541		  });
5542			
5543			
5544	
5545		}
5546		else {
5547	 		$.ajax({  
5548		    type: 'GET',
5549		    url: '/proc_exhibition_add.php', 
5550		    data: {
5551		    	product : $this.data('product'),
5552		    	exhibition : $this.data('exhibition'),
5553		    },
5554		    success: function(response) {
5555		    	$('#dynamicmodal .modal-body').html(response);
5556		    	$('#dynamicmodal').modal('show');
5557		    }
5558			});
5559			
5560		}
5561		
5562	});
5563
5564
5565	$(document).on('click touch', '.del_from_exhibition', function(e) {
5566	  var $this = $(this);
5567		e.preventDefault();
5568		
5569		// if it's from a modal
5570		if($('#dynamicmodal').hasClass('in')){
5571	
5572			$('#dynamicmodal').slideUp( "slow", function() {
5573
5574		 		$.ajax({  
5575			    type: 'GET',
5576			    url: '/proc_exhibition_add.php', 
5577			    data: {
5578			    	product : $this.data('product'),
5579			    	exhibition : $this.data('exhibition'),
5580			    	delete : '1',
5581			    },
5582			    success: function(response) {
5583			    	$('#dynamicmodal .modal-body').html(response);
5584			    	$( "#dynamicmodal" ).slideDown( "slow", function() {
5585			    	
5586			    	});
5587			    }
5588				});
5589		  });
5590		}
5591		
5592	});
5593
5594
5595
5596	// this part is for saving the story
5597	
5598	$(document).on('submit', '#exhibition_artefact_form', function(e) {
5599	  var $this = $(this);
5600		e.preventDefault();
5601		
5602		var datastring = $("#exhibition_artefact_form").serialize();
5603		
5604		// if it's from a modal
5605		if($('#dynamicmodal').hasClass('in')){
5606	
5607			$('#dynamicmodal').slideUp( "slow", function() {
5608
5609		 		$.ajax({  
5610			    type: 'POST',
5611			    url: '/proc_exhibition_add.php', 
5612			    data: datastring,
5613			    success: function(response) {
5614			    	$('#dynamicmodal .modal-body').html(response);
5615			    	$( "#dynamicmodal" ).slideDown( "slow", function() {
5616			    	
5617			    	});
5618			    }
5619				});
5620		  });
5621		}
5622				
5623	});
5624	
5625	*/
5626	
5627	
5628	/*
5629	$(document).on('submit', '#exhibition_form', function(e) {
5630	  var $this = $(this);
5631		e.preventDefault();
5632		
5633		var datastring = $("#exhibition_form").serialize();
5634		
5635		// if it's from a modal
5636		if($('#dynamicmodal').hasClass('in')){
5637	
5638			$('#dynamicmodal').slideUp( "slow", function() {
5639
5640		 		$.ajax({  
5641			    type: 'GET',
5642			    url: '/proc_exhibition_add.php', 
5643			    data: datastring,
5644			    success: function(response) {
5645			    	$('#dynamicmodal .modal-body').html(response);
5646			    	$( "#dynamicmodal" ).slideDown( "slow", function() {
5647			    	
5648			    	});
5649			    }
5650				});
5651		  });
5652		}
5653				
5654	});
5655	*/
5656
5657
5658
5659});$(document).ready(function() {
5660	
5661	
5662	$("#cmma_search").submit(function(e){
5663		
5664		e.preventDefault();
5665		
5666		console.log('test');
5667
5668		var cmma_search_results = $("#cmma_search_results");
5669		
5670		$.ajax({  
5671			type: 'POST',
5672			url: '/connecting-manchesters-music-archives/proc_cmma_search.php', 
5673			data: $(this).serialize(),
5674			success: function(response) {
5675				cmma_search_results.html(response);
5676			}
5677		});
5678		
5679
5680	});
5681	
5682	
5683	
5684	$(document).on('click touch', '.cmma_button_click', function(e) {
5685		
5686		e.preventDefault();
5687		
5688		console.log($(this).data('id'));
5689		
5690		// show a 'working' button
5691		
5692		var button = $(this);
5693		var holder = button.next('.cmma_item_results');
5694		var button_text = button.text();
5695		
5696		console.log(button_text);
5697		
5698		if (button.hasClass('active')) {
5699			holder.slideUp( "slow", function() {
5700				// Animation complete.
5701				button.text(function () {
5702					return $(this).text().replace("Hide", "Show"); 
5703				});
5704			});
5705		}
5706		else {
5707			if (holder.is(':empty')) {
5708				$.ajax({  
5709					type: 'GET',
5710					url: '/connecting-manchesters-music-archives/inc_cmma_items_lookup.php', 
5711					data: {
5712						id : button.data('id'),
5713						admin : button.data('admin'),
5714					},
5715					success: function(response) {
5716						holder.append(response);
5717						holder.slideDown( "slow", function() {
5718							// Animation complete.
5719							
5720							button.text(function () {
5721								return $(this).text().replace("Show", "Hide"); 
5722							});
5723						});
5724					}
5725				});
5726			}
5727			else {
5728				holder.slideDown( "slow", function() {
5729					// Animation complete.
5730					
5731					button.text(function () {
5732						return $(this).text().replace("Show", "Hide"); 
5733					});
5734				});
5735			}
5736		}
5737		
5738		button.toggleClass('active');
5739		
5740		
5741	});
5742
5743
5744});/*! Magnific Popup - v1.1.0 - 2016-02-20
vendor: 37,682 bytes, lines 5745-7436
5745* http://dimsemenov.com/plugins/magnific-popup/
5746* Copyright (c) 2016 Dmitry Semenov; */
5747;(function (factory) { 
5748if (typeof define === 'function' && define.amd) { 
5749 // AMD. Register as an anonymous module. 
5750 define(['jquery'], factory); 
5751 } else if (typeof exports === 'object') { 
5752 // Node/CommonJS 
5753 factory(require('jquery')); 
5754 } else { 
5755 // Browser globals 
5756 factory(window.jQuery || window.Zepto); 
5757 } 
5758 }(function($) { 
5759
5760/*>>core*/
5761/**
5762 * 
5763 * Magnific Popup Core JS file
5764 * 
5765 */
5766
5767
5768/**
5769 * Private static constants
5770 */
5771var CLOSE_EVENT = 'Close',
5772	BEFORE_CLOSE_EVENT = 'BeforeClose',
5773	AFTER_CLOSE_EVENT = 'AfterClose',
5774	BEFORE_APPEND_EVENT = 'BeforeAppend',
5775	MARKUP_PARSE_EVENT = 'MarkupParse',
5776	OPEN_EVENT = 'Open',
5777	CHANGE_EVENT = 'Change',
5778	NS = 'mfp',
5779	EVENT_NS = '.' + NS,
5780	READY_CLASS = 'mfp-ready',
5781	REMOVING_CLASS = 'mfp-removing',
5782	PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
5783
5784
5785/**
5786 * Private vars 
5787 */
5788/*jshint -W079 */
5789var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
5790	MagnificPopup = function(){},
5791	_isJQ = !!(window.jQuery),
5792	_prevStatus,
5793	_window = $(window),
5794	_document,
5795	_prevContentType,
5796	_wrapClasses,
5797	_currPopupType;
5798
5799
5800/**
5801 * Private functions
5802 */
5803var _mfpOn = function(name, f) {
5804		mfp.ev.on(NS + name + EVENT_NS, f);
5805	},
5806	_getEl = function(className, appendTo, html, raw) {
5807		var el = document.createElement('div');
5808		el.className = 'mfp-'+className;
5809		if(html) {
5810			el.innerHTML = html;
5811		}
5812		if(!raw) {
5813			el = $(el);
5814			if(appendTo) {
5815				el.appendTo(appendTo);
5816			}
5817		} else if(appendTo) {
5818			appendTo.appendChild(el);
5819		}
5820		return el;
5821	},
5822	_mfpTrigger = function(e, data) {
5823		mfp.ev.triggerHandler(NS + e, data);
5824
5825		if(mfp.st.callbacks) {
5826			// converts "mfpEventName" to "eventName" callback and triggers it if it's present
5827			e = e.charAt(0).toLowerCase() + e.slice(1);
5828			if(mfp.st.callbacks[e]) {
5829				mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
5830			}
5831		}
5832	},
5833	_getCloseBtn = function(type) {
5834		if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
5835			mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
5836			_currPopupType = type;
5837		}
5838		return mfp.currTemplate.closeBtn;
5839	},
5840	// Initialize Magnific Popup only when called at least once
5841	_checkInstance = function() {
5842		if(!$.magnificPopup.instance) {
5843			/*jshint -W020 */
5844			mfp = new MagnificPopup();
5845			mfp.init();
5846			$.magnificPopup.instance = mfp;
5847		}
5848	},
5849	// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
5850	supportsTransitions = function() {
5851		var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
5852			v = ['ms','O','Moz','Webkit']; // 'v' for vendor
5853
5854		if( s['transition'] !== undefined ) {
5855			return true; 
5856		}
5857			
5858		while( v.length ) {
5859			if( v.pop() + 'Transition' in s ) {
5860				return true;
5861			}
5862		}
5863				
5864		return false;
5865	};
5866
5867
5868
5869/**
5870 * Public functions
5871 */
5872MagnificPopup.prototype = {
5873
5874	constructor: MagnificPopup,
5875
5876	/**
5877	 * Initializes Magnific Popup plugin. 
5878	 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
5879	 */
5880	init: function() {
5881		var appVersion = navigator.appVersion;
5882		mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
5883		mfp.isAndroid = (/android/gi).test(appVersion);
5884		mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
5885		mfp.supportsTransition = supportsTransitions();
5886
5887		// We disable fixed positioned lightbox on devices that don't handle it nicely.
5888		// If you know a better way of detecting this - let me know.
5889		mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
5890		_document = $(document);
5891
5892		mfp.popupsCache = {};
5893	},
5894
5895	/**
5896	 * Opens popup
5897	 * @param  data [description]
5898	 */
5899	open: function(data) {
5900
5901		var i;
5902
5903		if(data.isObj === false) { 
5904			// convert jQuery collection to array to avoid conflicts later
5905			mfp.items = data.items.toArray();
5906
5907			mfp.index = 0;
5908			var items = data.items,
5909				item;
5910			for(i = 0; i < items.length; i++) {
5911				item = items[i];
5912				if(item.parsed) {
5913					item = item.el[0];
5914				}
5915				if(item === data.el[0]) {
5916					mfp.index = i;
5917					break;
5918				}
5919			}
5920		} else {
5921			mfp.items = $.isArray(data.items) ? data.items : [data.items];
5922			mfp.index = data.index || 0;
5923		}
5924
5925		// if popup is already opened - we just update the content
5926		if(mfp.isOpen) {
5927			mfp.updateItemHTML();
5928			return;
5929		}
5930		
5931		mfp.types = []; 
5932		_wrapClasses = '';
5933		if(data.mainEl && data.mainEl.length) {
5934			mfp.ev = data.mainEl.eq(0);
5935		} else {
5936			mfp.ev = _document;
5937		}
5938
5939		if(data.key) {
5940			if(!mfp.popupsCache[data.key]) {
5941				mfp.popupsCache[data.key] = {};
5942			}
5943			mfp.currTemplate = mfp.popupsCache[data.key];
5944		} else {
5945			mfp.currTemplate = {};
5946		}
5947
5948
5949
5950		mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 
5951		mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
5952
5953		if(mfp.st.modal) {
5954			mfp.st.closeOnContentClick = false;
5955			mfp.st.closeOnBgClick = false;
5956			mfp.st.showCloseBtn = false;
5957			mfp.st.enableEscapeKey = false;
5958		}
5959		
5960
5961		// Building markup
5962		// main containers are created only once
5963		if(!mfp.bgOverlay) {
5964
5965			// Dark overlay
5966			mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
5967				mfp.close();
5968			});
5969
5970			mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
5971				if(mfp._checkIfClose(e.target)) {
5972					mfp.close();
5973				}
5974			});
5975
5976			mfp.container = _getEl('container', mfp.wrap);
5977		}
5978
5979		mfp.contentContainer = _getEl('content');
5980		if(mfp.st.preloader) {
5981			mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
5982		}
5983
5984
5985		// Initializing modules
5986		var modules = $.magnificPopup.modules;
5987		for(i = 0; i < modules.length; i++) {
5988			var n = modules[i];
5989			n = n.charAt(0).toUpperCase() + n.slice(1);
5990			mfp['init'+n].call(mfp);
5991		}
5992		_mfpTrigger('BeforeOpen');
5993
5994
5995		if(mfp.st.showCloseBtn) {
5996			// Close button
5997			if(!mfp.st.closeBtnInside) {
5998				mfp.wrap.append( _getCloseBtn() );
5999			} else {
6000				_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
6001					values.close_replaceWith = _getCloseBtn(item.type);
6002				});
6003				_wrapClasses += ' mfp-close-btn-in';
6004			}
6005		}
6006
6007		if(mfp.st.alignTop) {
6008			_wrapClasses += ' mfp-align-top';
6009		}
6010
6011	
6012
6013		if(mfp.fixedContentPos) {
6014			mfp.wrap.css({
6015				overflow: mfp.st.overflowY,
6016				overflowX: 'hidden',
6017				overflowY: mfp.st.overflowY
6018			});
6019		} else {
6020			mfp.wrap.css({ 
6021				top: _window.scrollTop(),
6022				position: 'absolute'
6023			});
6024		}
6025		if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
6026			mfp.bgOverlay.css({
6027				height: _document.height(),
6028				position: 'absolute'
6029			});
6030		}
6031
6032		
6033
6034		if(mfp.st.enableEscapeKey) {
6035			// Close on ESC key
6036			_document.on('keyup' + EVENT_NS, function(e) {
6037				if(e.keyCode === 27) {
6038					mfp.close();
6039				}
6040			});
6041		}
6042
6043		_window.on('resize' + EVENT_NS, function() {
6044			mfp.updateSize();
6045		});
6046
6047
6048		if(!mfp.st.closeOnContentClick) {
6049			_wrapClasses += ' mfp-auto-cursor';
6050		}
6051		
6052		if(_wrapClasses)
6053			mfp.wrap.addClass(_wrapClasses);
6054
6055
6056		// this triggers recalculation of layout, so we get it once to not to trigger twice
6057		var windowHeight = mfp.wH = _window.height();
6058
6059		
6060		var windowStyles = {};
6061
6062		if( mfp.fixedContentPos ) {
6063            if(mfp._hasScrollBar(windowHeight)){
6064                var s = mfp._getScrollbarSize();
6065                if(s) {
6066                    windowStyles.marginRight = s;
6067                }
6068            }
6069        }
6070
6071		if(mfp.fixedContentPos) {
6072			if(!mfp.isIE7) {
6073				windowStyles.overflow = 'hidden';
6074			} else {
6075				// ie7 double-scroll bug
6076				$('body, html').css('overflow', 'hidden');
6077			}
6078		}
6079
6080		
6081		
6082		var classesToadd = mfp.st.mainClass;
6083		if(mfp.isIE7) {
6084			classesToadd += ' mfp-ie7';
6085		}
6086		if(classesToadd) {
6087			mfp._addClassToMFP( classesToadd );
6088		}
6089
6090		// add content
6091		mfp.updateItemHTML();
6092
6093		_mfpTrigger('BuildControls');
6094
6095		// remove scrollbar, add margin e.t.c
6096		$('html').css(windowStyles);
6097		
6098		// add everything to DOM
6099		mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
6100
6101		// Save last focused element
6102		mfp._lastFocusedEl = document.activeElement;
6103		
6104		// Wait for next cycle to allow CSS transition
6105		setTimeout(function() {
6106			
6107			if(mfp.content) {
6108				mfp._addClassToMFP(READY_CLASS);
6109				mfp._setFocus();
6110			} else {
6111				// if content is not defined (not loaded e.t.c) we add class only for BG
6112				mfp.bgOverlay.addClass(READY_CLASS);
6113			}
6114			
6115			// Trap the focus in popup
6116			_document.on('focusin' + EVENT_NS, mfp._onFocusIn);
6117
6118		}, 16);
6119
6120		mfp.isOpen = true;
6121		mfp.updateSize(windowHeight);
6122		_mfpTrigger(OPEN_EVENT);
6123
6124		return data;
6125	},
6126
6127	/**
6128	 * Closes the popup
6129	 */
6130	close: function() {
6131		if(!mfp.isOpen) return;
6132		_mfpTrigger(BEFORE_CLOSE_EVENT);
6133
6134		mfp.isOpen = false;
6135		// for CSS3 animation
6136		if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {
6137			mfp._addClassToMFP(REMOVING_CLASS);
6138			setTimeout(function() {
6139				mfp._close();
6140			}, mfp.st.removalDelay);
6141		} else {
6142			mfp._close();
6143		}
6144	},
6145
6146	/**
6147	 * Helper for close() function
6148	 */
6149	_close: function() {
6150		_mfpTrigger(CLOSE_EVENT);
6151
6152		var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
6153
6154		mfp.bgOverlay.detach();
6155		mfp.wrap.detach();
6156		mfp.container.empty();
6157
6158		if(mfp.st.mainClass) {
6159			classesToRemove += mfp.st.mainClass + ' ';
6160		}
6161
6162		mfp._removeClassFromMFP(classesToRemove);
6163
6164		if(mfp.fixedContentPos) {
6165			var windowStyles = {marginRight: ''};
6166			if(mfp.isIE7) {
6167				$('body, html').css('overflow', '');
6168			} else {
6169				windowStyles.overflow = '';
6170			}
6171			$('html').css(windowStyles);
6172		}
6173		
6174		_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
6175		mfp.ev.off(EVENT_NS);
6176
6177		// clean up DOM elements that aren't removed
6178		mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
6179		mfp.bgOverlay.attr('class', 'mfp-bg');
6180		mfp.container.attr('class', 'mfp-container');
6181
6182		// remove close button from target element
6183		if(mfp.st.showCloseBtn &&
6184		(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
6185			if(mfp.currTemplate.closeBtn)
6186				mfp.currTemplate.closeBtn.detach();
6187		}
6188
6189
6190		if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
6191			$(mfp._lastFocusedEl).focus(); // put tab focus back
6192		}
6193		mfp.currItem = null;	
6194		mfp.content = null;
6195		mfp.currTemplate = null;
6196		mfp.prevHeight = 0;
6197
6198		_mfpTrigger(AFTER_CLOSE_EVENT);
6199	},
6200	
6201	updateSize: function(winHeight) {
6202
6203		if(mfp.isIOS) {
6204			// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
6205			var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
6206			var height = window.innerHeight * zoomLevel;
6207			mfp.wrap.css('height', height);
6208			mfp.wH = height;
6209		} else {
6210			mfp.wH = winHeight || _window.height();
6211		}
6212		// Fixes #84: popup incorrectly positioned with position:relative on body
6213		if(!mfp.fixedContentPos) {
6214			mfp.wrap.css('height', mfp.wH);
6215		}
6216
6217		_mfpTrigger('Resize');
6218
6219	},
6220
6221	/**
6222	 * Set content of popup based on current index
6223	 */
6224	updateItemHTML: function() {
6225		var item = mfp.items[mfp.index];
6226
6227		// Detach and perform modifications
6228		mfp.contentContainer.detach();
6229
6230		if(mfp.content)
6231			mfp.content.detach();
6232
6233		if(!item.parsed) {
6234			item = mfp.parseEl( mfp.index );
6235		}
6236
6237		var type = item.type;
6238
6239		_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
6240		// BeforeChange event works like so:
6241		// _mfpOn('BeforeChange', function(e, prevType, newType) { });
6242
6243		mfp.currItem = item;
6244
6245		if(!mfp.currTemplate[type]) {
6246			var markup = mfp.st[type] ? mfp.st[type].markup : false;
6247
6248			// allows to modify markup
6249			_mfpTrigger('FirstMarkupParse', markup);
6250
6251			if(markup) {
6252				mfp.currTemplate[type] = $(markup);
6253			} else {
6254				// if there is no markup found we just define that template is parsed
6255				mfp.currTemplate[type] = true;
6256			}
6257		}
6258
6259		if(_prevContentType && _prevContentType !== item.type) {
6260			mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
6261		}
6262
6263		var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
6264		mfp.appendContent(newContent, type);
6265
6266		item.preloaded = true;
6267
6268		_mfpTrigger(CHANGE_EVENT, item);
6269		_prevContentType = item.type;
6270
6271		// Append container back after its content changed
6272		mfp.container.prepend(mfp.contentContainer);
6273
6274		_mfpTrigger('AfterChange');
6275	},
6276
6277
6278	/**
6279	 * Set HTML content of popup
6280	 */
6281	appendContent: function(newContent, type) {
6282		mfp.content = newContent;
6283
6284		if(newContent) {
6285			if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
6286				mfp.currTemplate[type] === true) {
6287				// if there is no markup, we just append close button element inside
6288				if(!mfp.content.find('.mfp-close').length) {
6289					mfp.content.append(_getCloseBtn());
6290				}
6291			} else {
6292				mfp.content = newContent;
6293			}
6294		} else {
6295			mfp.content = '';
6296		}
6297
6298		_mfpTrigger(BEFORE_APPEND_EVENT);
6299		mfp.container.addClass('mfp-'+type+'-holder');
6300
6301		mfp.contentContainer.append(mfp.content);
6302	},
6303
6304
6305	/**
6306	 * Creates Magnific Popup data object based on given data
6307	 * @param  {int} index Index of item to parse
6308	 */
6309	parseEl: function(index) {
6310		var item = mfp.items[index],
6311			type;
6312
6313		if(item.tagName) {
6314			item = { el: $(item) };
6315		} else {
6316			type = item.type;
6317			item = { data: item, src: item.src };
6318		}
6319
6320		if(item.el) {
6321			var types = mfp.types;
6322
6323			// check for 'mfp-TYPE' class
6324			for(var i = 0; i < types.length; i++) {
6325				if( item.el.hasClass('mfp-'+types[i]) ) {
6326					type = types[i];
6327					break;
6328				}
6329			}
6330
6331			item.src = item.el.attr('data-mfp-src');
6332			if(!item.src) {
6333				item.src = item.el.attr('href');
6334			}
6335		}
6336
6337		item.type = type || mfp.st.type || 'inline';
6338		item.index = index;
6339		item.parsed = true;
6340		mfp.items[index] = item;
6341		_mfpTrigger('ElementParse', item);
6342
6343		return mfp.items[index];
6344	},
6345
6346
6347	/**
6348	 * Initializes single popup or a group of popups
6349	 */
6350	addGroup: function(el, options) {
6351		var eHandler = function(e) {
6352			e.mfpEl = this;
6353			mfp._openClick(e, el, options);
6354		};
6355
6356		if(!options) {
6357			options = {};
6358		}
6359
6360		var eName = 'click.magnificPopup';
6361		options.mainEl = el;
6362
6363		if(options.items) {
6364			options.isObj = true;
6365			el.off(eName).on(eName, eHandler);
6366		} else {
6367			options.isObj = false;
6368			if(options.delegate) {
6369				el.off(eName).on(eName, options.delegate , eHandler);
6370			} else {
6371				options.items = el;
6372				el.off(eName).on(eName, eHandler);
6373			}
6374		}
6375	},
6376	_openClick: function(e, el, options) {
6377		var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
6378
6379
6380		if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
6381			return;
6382		}
6383
6384		var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
6385
6386		if(disableOn) {
6387			if($.isFunction(disableOn)) {
6388				if( !disableOn.call(mfp) ) {
6389					return true;
6390				}
6391			} else { // else it's number
6392				if( _window.width() < disableOn ) {
6393					return true;
6394				}
6395			}
6396		}
6397
6398		if(e.type) {
6399			e.preventDefault();
6400
6401			// This will prevent popup from closing if element is inside and popup is already opened
6402			if(mfp.isOpen) {
6403				e.stopPropagation();
6404			}
6405		}
6406
6407		options.el = $(e.mfpEl);
6408		if(options.delegate) {
6409			options.items = el.find(options.delegate);
6410		}
6411		mfp.open(options);
6412	},
6413
6414
6415	/**
6416	 * Updates text on preloader
6417	 */
6418	updateStatus: function(status, text) {
6419
6420		if(mfp.preloader) {
6421			if(_prevStatus !== status) {
6422				mfp.container.removeClass('mfp-s-'+_prevStatus);
6423			}
6424
6425			if(!text && status === 'loading') {
6426				text = mfp.st.tLoading;
6427			}
6428
6429			var data = {
6430				status: status,
6431				text: text
6432			};
6433			// allows to modify status
6434			_mfpTrigger('UpdateStatus', data);
6435
6436			status = data.status;
6437			text = data.text;
6438
6439			mfp.preloader.html(text);
6440
6441			mfp.preloader.find('a').on('click', function(e) {
6442				e.stopImmediatePropagation();
6443			});
6444
6445			mfp.container.addClass('mfp-s-'+status);
6446			_prevStatus = status;
6447		}
6448	},
6449
6450
6451	/*
6452		"Private" helpers that aren't private at all
6453	 */
6454	// Check to close popup or not
6455	// "target" is an element that was clicked
6456	_checkIfClose: function(target) {
6457
6458		if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
6459			return;
6460		}
6461
6462		var closeOnContent = mfp.st.closeOnContentClick;
6463		var closeOnBg = mfp.st.closeOnBgClick;
6464
6465		if(closeOnContent && closeOnBg) {
6466			return true;
6467		} else {
6468
6469			// We close the popup if click is on close button or on preloader. Or if there is no content.
6470			if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
6471				return true;
6472			}
6473
6474			// if click is outside the content
6475			if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {
6476				if(closeOnBg) {
6477					// last check, if the clicked element is in DOM, (in case it's removed onclick)
6478					if( $.contains(document, target) ) {
6479						return true;
6480					}
6481				}
6482			} else if(closeOnContent) {
6483				return true;
6484			}
6485
6486		}
6487		return false;
6488	},
6489	_addClassToMFP: function(cName) {
6490		mfp.bgOverlay.addClass(cName);
6491		mfp.wrap.addClass(cName);
6492	},
6493	_removeClassFromMFP: function(cName) {
6494		this.bgOverlay.removeClass(cName);
6495		mfp.wrap.removeClass(cName);
6496	},
6497	_hasScrollBar: function(winHeight) {
6498		return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
6499	},
6500	_setFocus: function() {
6501		(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
6502	},
6503	_onFocusIn: function(e) {
6504		if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
6505			mfp._setFocus();
6506			return false;
6507		}
6508	},
6509	_parseMarkup: function(template, values, item) {
6510		var arr;
6511		if(item.data) {
6512			values = $.extend(item.data, values);
6513		}
6514		_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
6515
6516		$.each(values, function(key, value) {
6517			if(value === undefined || value === false) {
6518				return true;
6519			}
6520			arr = key.split('_');
6521			if(arr.length > 1) {
6522				var el = template.find(EVENT_NS + '-'+arr[0]);
6523
6524				if(el.length > 0) {
6525					var attr = arr[1];
6526					if(attr === 'replaceWith') {
6527						if(el[0] !== value[0]) {
6528							el.replaceWith(value);
6529						}
6530					} else if(attr === 'img') {
6531						if(el.is('img')) {
6532							el.attr('src', value);
6533						} else {
6534							el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
6535						}
6536					} else {
6537						el.attr(arr[1], value);
6538					}
6539				}
6540
6541			} else {
6542				template.find(EVENT_NS + '-'+key).html(value);
6543			}
6544		});
6545	},
6546
6547	_getScrollbarSize: function() {
6548		// thx David
6549		if(mfp.scrollbarSize === undefined) {
6550			var scrollDiv = document.createElement("div");
6551			scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
6552			document.body.appendChild(scrollDiv);
6553			mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
6554			document.body.removeChild(scrollDiv);
6555		}
6556		return mfp.scrollbarSize;
6557	}
6558
6559}; /* MagnificPopup core prototype end */
6560
6561
6562
6563
6564/**
6565 * Public static functions
6566 */
6567$.magnificPopup = {
6568	instance: null,
6569	proto: MagnificPopup.prototype,
6570	modules: [],
6571
6572	open: function(options, index) {
6573		_checkInstance();
6574
6575		if(!options) {
6576			options = {};
6577		} else {
6578			options = $.extend(true, {}, options);
6579		}
6580
6581		options.isObj = true;
6582		options.index = index || 0;
6583		return this.instance.open(options);
6584	},
6585
6586	close: function() {
6587		return $.magnificPopup.instance && $.magnificPopup.instance.close();
6588	},
6589
6590	registerModule: function(name, module) {
6591		if(module.options) {
6592			$.magnificPopup.defaults[name] = module.options;
6593		}
6594		$.extend(this.proto, module.proto);
6595		this.modules.push(name);
6596	},
6597
6598	defaults: {
6599
6600		// Info about options is in docs:
6601		// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
6602
6603		disableOn: 0,
6604
6605		key: null,
6606
6607		midClick: false,
6608
6609		mainClass: '',
6610
6611		preloader: true,
6612
6613		focus: '', // CSS selector of input to focus after popup is opened
6614
6615		closeOnContentClick: false,
6616
6617		closeOnBgClick: true,
6618
6619		closeBtnInside: true,
6620
6621		showCloseBtn: true,
6622
6623		enableEscapeKey: true,
6624
6625		modal: false,
6626
6627		alignTop: false,
6628
6629		removalDelay: 0,
6630
6631		prependTo: null,
6632
6633		fixedContentPos: 'auto',
6634
6635		fixedBgPos: 'auto',
6636
6637		overflowY: 'auto',
6638
6639		closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',
6640
6641		tClose: 'Close (Esc)',
6642
6643		tLoading: 'Loading...',
6644
6645		autoFocusLast: true
6646
6647	}
6648};
6649
6650
6651
6652$.fn.magnificPopup = function(options) {
6653	_checkInstance();
6654
6655	var jqEl = $(this);
6656
6657	// We call some API method of first param is a string
6658	if (typeof options === "string" ) {
6659
6660		if(options === 'open') {
6661			var items,
6662				itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
6663				index = parseInt(arguments[1], 10) || 0;
6664
6665			if(itemOpts.items) {
6666				items = itemOpts.items[index];
6667			} else {
6668				items = jqEl;
6669				if(itemOpts.delegate) {
6670					items = items.find(itemOpts.delegate);
6671				}
6672				items = items.eq( index );
6673			}
6674			mfp._openClick({mfpEl:items}, jqEl, itemOpts);
6675		} else {
6676			if(mfp.isOpen)
6677				mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
6678		}
6679
6680	} else {
6681		// clone options obj
6682		options = $.extend(true, {}, options);
6683
6684		/*
6685		 * As Zepto doesn't support .data() method for objects
6686		 * and it works only in normal browsers
6687		 * we assign "options" object directly to the DOM element. FTW!
6688		 */
6689		if(_isJQ) {
6690			jqEl.data('magnificPopup', options);
6691		} else {
6692			jqEl[0].magnificPopup = options;
6693		}
6694
6695		mfp.addGroup(jqEl, options);
6696
6697	}
6698	return jqEl;
6699};
6700
6701/*>>core*/
6702
6703/*>>inline*/
6704
6705var INLINE_NS = 'inline',
6706	_hiddenClass,
6707	_inlinePlaceholder,
6708	_lastInlineElement,
6709	_putInlineElementsBack = function() {
6710		if(_lastInlineElement) {
6711			_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
6712			_lastInlineElement = null;
6713		}
6714	};
6715
6716$.magnificPopup.registerModule(INLINE_NS, {
6717	options: {
6718		hiddenClass: 'hide', // will be appended with `mfp-` prefix
6719		markup: '',
6720		tNotFound: 'Content not found'
6721	},
6722	proto: {
6723
6724		initInline: function() {
6725			mfp.types.push(INLINE_NS);
6726
6727			_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
6728				_putInlineElementsBack();
6729			});
6730		},
6731
6732		getInline: function(item, template) {
6733
6734			_putInlineElementsBack();
6735
6736			if(item.src) {
6737				var inlineSt = mfp.st.inline,
6738					el = $(item.src);
6739
6740				if(el.length) {
6741
6742					// If target element has parent - we replace it with placeholder and put it back after popup is closed
6743					var parent = el[0].parentNode;
6744					if(parent && parent.tagName) {
6745						if(!_inlinePlaceholder) {
6746							_hiddenClass = inlineSt.hiddenClass;
6747							_inlinePlaceholder = _getEl(_hiddenClass);
6748							_hiddenClass = 'mfp-'+_hiddenClass;
6749						}
6750						// replace target inline element with placeholder
6751						_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
6752					}
6753
6754					mfp.updateStatus('ready');
6755				} else {
6756					mfp.updateStatus('error', inlineSt.tNotFound);
6757					el = $('<div>');
6758				}
6759
6760				item.inlineElement = el;
6761				return el;
6762			}
6763
6764			mfp.updateStatus('ready');
6765			mfp._parseMarkup(template, {}, item);
6766			return template;
6767		}
6768	}
6769});
6770
6771/*>>inline*/
6772
6773/*>>ajax*/
6774var AJAX_NS = 'ajax',
6775	_ajaxCur,
6776	_removeAjaxCursor = function() {
6777		if(_ajaxCur) {
6778			$(document.body).removeClass(_ajaxCur);
6779		}
6780	},
6781	_destroyAjaxRequest = function() {
6782		_removeAjaxCursor();
6783		if(mfp.req) {
6784			mfp.req.abort();
6785		}
6786	};
6787
6788$.magnificPopup.registerModule(AJAX_NS, {
6789
6790	options: {
6791		settings: null,
6792		cursor: 'mfp-ajax-cur',
6793		tError: '<a href="%url%">The content</a> could not be loaded.'
6794	},
6795
6796	proto: {
6797		initAjax: function() {
6798			mfp.types.push(AJAX_NS);
6799			_ajaxCur = mfp.st.ajax.cursor;
6800
6801			_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
6802			_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
6803		},
6804		getAjax: function(item) {
6805
6806			if(_ajaxCur) {
6807				$(document.body).addClass(_ajaxCur);
6808			}
6809
6810			mfp.updateStatus('loading');
6811
6812			var opts = $.extend({
6813				url: item.src,
6814				success: function(data, textStatus, jqXHR) {
6815					var temp = {
6816						data:data,
6817						xhr:jqXHR
6818					};
6819
6820					_mfpTrigger('ParseAjax', temp);
6821
6822					mfp.appendContent( $(temp.data), AJAX_NS );
6823
6824					item.finished = true;
6825
6826					_removeAjaxCursor();
6827
6828					mfp._setFocus();
6829
6830					setTimeout(function() {
6831						mfp.wrap.addClass(READY_CLASS);
6832					}, 16);
6833
6834					mfp.updateStatus('ready');
6835
6836					_mfpTrigger('AjaxContentAdded');
6837				},
6838				error: function() {
6839					_removeAjaxCursor();
6840					item.finished = item.loadError = true;
6841					mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
6842				}
6843			}, mfp.st.ajax.settings);
6844
6845			mfp.req = $.ajax(opts);
6846
6847			return '';
6848		}
6849	}
6850});
6851
6852/*>>ajax*/
6853
6854/*>>image*/
6855var _imgInterval,
6856	_getTitle = function(item) {
6857		if(item.data && item.data.title !== undefined)
6858			return item.data.title;
6859
6860		var src = mfp.st.image.titleSrc;
6861
6862		if(src) {
6863			if($.isFunction(src)) {
6864				return src.call(mfp, item);
6865			} else if(item.el) {
6866				return item.el.attr(src) || '';
6867			}
6868		}
6869		return '';
6870	};
6871
6872$.magnificPopup.registerModule('image', {
6873
6874	options: {
6875		markup: '<div class="mfp-figure">'+
6876					'<div class="mfp-close"></div>'+
6877					'<figure>'+
6878						'<div class="mfp-img"></div>'+
6879						'<figcaption>'+
6880							'<div class="mfp-bottom-bar">'+
6881								'<div class="mfp-title"></div>'+
6882								'<div class="mfp-counter"></div>'+
6883							'</div>'+
6884						'</figcaption>'+
6885					'</figure>'+
6886				'</div>',
6887		cursor: 'mfp-zoom-out-cur',
6888		titleSrc: 'title',
6889		verticalFit: true,
6890		tError: '<a href="%url%">The image</a> could not be loaded.'
6891	},
6892
6893	proto: {
6894		initImage: function() {
6895			var imgSt = mfp.st.image,
6896				ns = '.image';
6897
6898			mfp.types.push('image');
6899
6900			_mfpOn(OPEN_EVENT+ns, function() {
6901				if(mfp.currItem.type === 'image' && imgSt.cursor) {
6902					$(document.body).addClass(imgSt.cursor);
6903				}
6904			});
6905
6906			_mfpOn(CLOSE_EVENT+ns, function() {
6907				if(imgSt.cursor) {
6908					$(document.body).removeClass(imgSt.cursor);
6909				}
6910				_window.off('resize' + EVENT_NS);
6911			});
6912
6913			_mfpOn('Resize'+ns, mfp.resizeImage);
6914			if(mfp.isLowIE) {
6915				_mfpOn('AfterChange', mfp.resizeImage);
6916			}
6917		},
6918		resizeImage: function() {
6919			var item = mfp.currItem;
6920			if(!item || !item.img) return;
6921
6922			if(mfp.st.image.verticalFit) {
6923				var decr = 0;
6924				// fix box-sizing in ie7/8
6925				if(mfp.isLowIE) {
6926					decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
6927				}
6928				item.img.css('max-height', mfp.wH-decr);
6929			}
6930		},
6931		_onImageHasSize: function(item) {
6932			if(item.img) {
6933
6934				item.hasSize = true;
6935
6936				if(_imgInterval) {
6937					clearInterval(_imgInterval);
6938				}
6939
6940				item.isCheckingImgSize = false;
6941
6942				_mfpTrigger('ImageHasSize', item);
6943
6944				if(item.imgHidden) {
6945					if(mfp.content)
6946						mfp.content.removeClass('mfp-loading');
6947
6948					item.imgHidden = false;
6949				}
6950
6951			}
6952		},
6953
6954		/**
6955		 * Function that loops until the image has size to display elements that rely on it asap
6956		 */
6957		findImageSize: function(item) {
6958
6959			var counter = 0,
6960				img = item.img[0],
6961				mfpSetInterval = function(delay) {
6962
6963					if(_imgInterval) {
6964						clearInterval(_imgInterval);
6965					}
6966					// decelerating interval that checks for size of an image
6967					_imgInterval = setInterval(function() {
6968						if(img.naturalWidth > 0) {
6969							mfp._onImageHasSize(item);
6970							return;
6971						}
6972
6973						if(counter > 200) {
6974							clearInterval(_imgInterval);
6975						}
6976
6977						counter++;
6978						if(counter === 3) {
6979							mfpSetInterval(10);
6980						} else if(counter === 40) {
6981							mfpSetInterval(50);
6982						} else if(counter === 100) {
6983							mfpSetInterval(500);
6984						}
6985					}, delay);
6986				};
6987
6988			mfpSetInterval(1);
6989		},
6990
6991		getImage: function(item, template) {
6992
6993			var guard = 0,
6994
6995				// image load complete handler
6996				onLoadComplete = function() {
6997					if(item) {
6998						if (item.img[0].complete) {
6999							item.img.off('.mfploader');
7000
7001							if(item === mfp.currItem){
7002								mfp._onImageHasSize(item);
7003
7004								mfp.updateStatus('ready');
7005							}
7006
7007							item.hasSize = true;
7008							item.loaded = true;
7009
7010							_mfpTrigger('ImageLoadComplete');
7011
7012						}
7013						else {
7014							// if image complete check fails 200 times (20 sec), we assume that there was an error.
7015							guard++;
7016							if(guard < 200) {
7017								setTimeout(onLoadComplete,100);
7018							} else {
7019								onLoadError();
7020							}
7021						}
7022					}
7023				},
7024
7025				// image error handler
7026				onLoadError = function() {
7027					if(item) {
7028						item.img.off('.mfploader');
7029						if(item === mfp.currItem){
7030							mfp._onImageHasSize(item);
7031							mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
7032						}
7033
7034						item.hasSize = true;
7035						item.loaded = true;
7036						item.loadError = true;
7037					}
7038				},
7039				imgSt = mfp.st.image;
7040
7041
7042			var el = template.find('.mfp-img');
7043			if(el.length) {
7044				var img = document.createElement('img');
7045				img.className = 'mfp-img';
7046				if(item.el && item.el.find('img').length) {
7047					img.alt = item.el.find('img').attr('alt');
7048				}
7049				item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
7050				img.src = item.src;
7051
7052				// without clone() "error" event is not firing when IMG is replaced by new IMG
7053				// TODO: find a way to avoid such cloning
7054				if(el.is('img')) {
7055					item.img = item.img.clone();
7056				}
7057
7058				img = item.img[0];
7059				if(img.naturalWidth > 0) {
7060					item.hasSize = true;
7061				} else if(!img.width) {
7062					item.hasSize = false;
7063				}
7064			}
7065
7066			mfp._parseMarkup(template, {
7067				title: _getTitle(item),
7068				img_replaceWith: item.img
7069			}, item);
7070
7071			mfp.resizeImage();
7072
7073			if(item.hasSize) {
7074				if(_imgInterval) clearInterval(_imgInterval);
7075
7076				if(item.loadError) {
7077					template.addClass('mfp-loading');
7078					mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
7079				} else {
7080					template.removeClass('mfp-loading');
7081					mfp.updateStatus('ready');
7082				}
7083				return template;
7084			}
7085
7086			mfp.updateStatus('loading');
7087			item.loading = true;
7088
7089			if(!item.hasSize) {
7090				item.imgHidden = true;
7091				template.addClass('mfp-loading');
7092				mfp.findImageSize(item);
7093			}
7094
7095			return template;
7096		}
7097	}
7098});
7099
7100/*>>image*/
7101
7102/*>>zoom*/
7103var hasMozTransform,
7104	getHasMozTransform = function() {
7105		if(hasMozTransform === undefined) {
7106			hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
7107		}
7108		return hasMozTransform;
7109	};
7110
7111$.magnificPopup.registerModule('zoom', {
7112
7113	options: {
7114		enabled: false,
7115		easing: 'ease-in-out',
7116		duration: 300,
7117		opener: function(element) {
7118			return element.is('img') ? element : element.find('img');
7119		}
7120	},
7121
7122	proto: {
7123
7124		initZoom: function() {
7125			var zoomSt = mfp.st.zoom,
7126				ns = '.zoom',
7127				image;
7128
7129			if(!zoomSt.enabled || !mfp.supportsTransition) {
7130				return;
7131			}
7132
7133			var duration = zoomSt.duration,
7134				getElToAnimate = function(image) {
7135					var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
7136						transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
7137						cssObj = {
7138							position: 'fixed',
7139							zIndex: 9999,
7140							left: 0,
7141							top: 0,
7142							'-webkit-backface-visibility': 'hidden'
7143						},
7144						t = 'transition';
7145
7146					cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
7147
7148					newImg.css(cssObj);
7149					return newImg;
7150				},
7151				showMainContent = function() {
7152					mfp.content.css('visibility', 'visible');
7153				},
7154				openTimeout,
7155				animatedImg;
7156
7157			_mfpOn('BuildControls'+ns, function() {
7158				if(mfp._allowZoom()) {
7159
7160					clearTimeout(openTimeout);
7161					mfp.content.css('visibility', 'hidden');
7162
7163					// Basically, all code below does is clones existing image, puts in on top of the current one and animated it
7164
7165					image = mfp._getItemToZoom();
7166
7167					if(!image) {
7168						showMainContent();
7169						return;
7170					}
7171
7172					animatedImg = getElToAnimate(image);
7173
7174					animatedImg.css( mfp._getOffset() );
7175
7176					mfp.wrap.append(animatedImg);
7177
7178					openTimeout = setTimeout(function() {
7179						animatedImg.css( mfp._getOffset( true ) );
7180						openTimeout = setTimeout(function() {
7181
7182							showMainContent();
7183
7184							setTimeout(function() {
7185								animatedImg.remove();
7186								image = animatedImg = null;
7187								_mfpTrigger('ZoomAnimationEnded');
7188							}, 16); // avoid blink when switching images
7189
7190						}, duration); // this timeout equals animation duration
7191
7192					}, 16); // by adding this timeout we avoid short glitch at the beginning of animation
7193
7194
7195					// Lots of timeouts...
7196				}
7197			});
7198			_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
7199				if(mfp._allowZoom()) {
7200
7201					clearTimeout(openTimeout);
7202
7203					mfp.st.removalDelay = duration;
7204
7205					if(!image) {
7206						image = mfp._getItemToZoom();
7207						if(!image) {
7208							return;
7209						}
7210						animatedImg = getElToAnimate(image);
7211					}
7212
7213					animatedImg.css( mfp._getOffset(true) );
7214					mfp.wrap.append(animatedImg);
7215					mfp.content.css('visibility', 'hidden');
7216
7217					setTimeout(function() {
7218						animatedImg.css( mfp._getOffset() );
7219					}, 16);
7220				}
7221
7222			});
7223
7224			_mfpOn(CLOSE_EVENT+ns, function() {
7225				if(mfp._allowZoom()) {
7226					showMainContent();
7227					if(animatedImg) {
7228						animatedImg.remove();
7229					}
7230					image = null;
7231				}
7232			});
7233		},
7234
7235		_allowZoom: function() {
7236			return mfp.currItem.type === 'image';
7237		},
7238
7239		_getItemToZoom: function() {
7240			if(mfp.currItem.hasSize) {
7241				return mfp.currItem.img;
7242			} else {
7243				return false;
7244			}
7245		},
7246
7247		// Get element postion relative to viewport
7248		_getOffset: function(isLarge) {
7249			var el;
7250			if(isLarge) {
7251				el = mfp.currItem.img;
7252			} else {
7253				el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
7254			}
7255
7256			var offset = el.offset();
7257			var paddingTop = parseInt(el.css('padding-top'),10);
7258			var paddingBottom = parseInt(el.css('padding-bottom'),10);
7259			offset.top -= ( $(window).scrollTop() - paddingTop );
7260
7261
7262			/*
7263
7264			Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
7265
7266			 */
7267			var obj = {
7268				width: el.width(),
7269				// fix Zepto height+padding issue
7270				height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
7271			};
7272
7273			// I hate to do this, but there is no another option
7274			if( getHasMozTransform() ) {
7275				obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
7276			} else {
7277				obj.left = offset.left;
7278				obj.top = offset.top;
7279			}
7280			return obj;
7281		}
7282
7283	}
7284});
7285
7286
7287
7288/*>>zoom*/
7289
7290/*>>iframe*/
7291
7292var IFRAME_NS = 'iframe',
7293	_emptyPage = '//about:blank',
7294
7295	_fixIframeBugs = function(isShowing) {
7296		if(mfp.currTemplate[IFRAME_NS]) {
7297			var el = mfp.currTemplate[IFRAME_NS].find('iframe');
7298			if(el.length) {
7299				// reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
7300				if(!isShowing) {
7301					el[0].src = _emptyPage;
7302				}
7303
7304				// IE8 black screen bug fix
7305				if(mfp.isIE8) {
7306					el.css('display', isShowing ? 'block' : 'none');
7307				}
7308			}
7309		}
7310	};
7311
7312$.magnificPopup.registerModule(IFRAME_NS, {
7313
7314	options: {
7315		markup: '<div class="mfp-iframe-scaler">'+
7316					'<div class="mfp-close"></div>'+
7317					'<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
7318				'</div>',
7319
7320		srcAction: 'iframe_src',
7321
7322		// we don't care and support only one default type of URL by default
7323		patterns: {
7324			youtube: {
7325				index: 'youtube.com',
7326				id: 'v=',
7327				src: '//www.youtube.com/embed/%id%?autoplay=1'
7328			},
7329			vimeo: {
7330				index: 'vimeo.com/',
7331				id: '/',
7332				src: '//player.vimeo.com/video/%id%?autoplay=1'
7333			},
7334			gmaps: {
7335				index: '//maps.google.',
7336				src: '%id%&output=embed'
7337			}
7338		}
7339	},
7340
7341	proto: {
7342		initIframe: function() {
7343			mfp.types.push(IFRAME_NS);
7344
7345			_mfpOn('BeforeChange', function(e, prevType, newType) {
7346				if(prevType !== newType) {
7347					if(prevType === IFRAME_NS) {
7348						_fixIframeBugs(); // iframe if removed
7349					} else if(newType === IFRAME_NS) {
7350						_fixIframeBugs(true); // iframe is showing
7351					}
7352				}// else {
7353					// iframe source is switched, don't do anything
7354				//}
7355			});
7356
7357			_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
7358				_fixIframeBugs();
7359			});
7360		},
7361
7362		getIframe: function(item, template) {
7363			var embedSrc = item.src;
7364			var iframeSt = mfp.st.iframe;
7365
7366			$.each(iframeSt.patterns, function() {
7367				if(embedSrc.indexOf( this.index ) > -1) {
7368					if(this.id) {
7369						if(typeof this.id === 'string') {
7370							embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
7371						} else {
7372							embedSrc = this.id.call( this, embedSrc );
7373						}
7374					}
7375					embedSrc = this.src.replace('%id%', embedSrc );
7376					return false; // break;
7377				}
7378			});
7379
7380			var dataObj = {};
7381			if(iframeSt.srcAction) {
7382				dataObj[iframeSt.srcAction] = embedSrc;
7383			}
7384			mfp._parseMarkup(template, dataObj, item);
7385
7386			mfp.updateStatus('ready');
7387
7388			return template;
7389		}
7390	}
7391});
7392
7393
7394
7395/*>>iframe*/
7396
7397/*>>gallery*/
7398/**
7399 * Get looped index depending on number of slides
7400 */
7401var _getLoopedId = function(index) {
7402		var numSlides = mfp.items.length;
7403		if(index > numSlides - 1) {
7404			return index - numSlides;
7405		} else  if(index < 0) {
7406			return numSlides + index;
7407		}
7408		return index;
7409	},
7410	_replaceCurrTotal = function(text, curr, total) {
7411		return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
7412	};
7413
7414$.magnificPopup.registerModule('gallery', {
7415
7416	options: {
7417		enabled: false,
7418		arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
7419		preload: [0,2],
7420		navigateByImgClick: true,
7421		arrows: true,
7422
7423		tPrev: 'Previous (Left arrow key)',
7424		tNext: 'Next (Right arrow key)',
7425		tCounter: '%curr% of %total%'
7426	},
7427
7428	proto: {
7429		initGallery: function() {
7430
7431			var gSt = mfp.st.gallery,
7432				ns = '.mfp-gallery';
7433
7434			mfp.direction = true; // true - next, false - prev
7435
7436			if(!gSt || !gSt.enabled ) return false;
7437
7438			_wrapClasses += ' mfp-gallery';
7439
7440			_mfpOn(OPEN_EVENT+ns, function() {
7441
7442				if(gSt.navigateByImgClick) {
7443					mfp.wrap.on('click'+ns, '.mfp-img', function() {
7444						if(mfp.items.length > 1) {
7445							mfp.next();
7446							return false;
7447						}
7448					});
7449				}
7450
7451				_document.on('keydown'+ns, function(e) {
7452					if (e.keyCode === 37) {
7453						mfp.prev();
7454					} else if (e.keyCode === 39) {
7455						mfp.next();
7456					}
7457				});
7458			});
7459
7460			_mfpOn('UpdateStatus'+ns, function(e, data) {
7461				if(data.text) {
7462					data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
7463				}
7464			});
7465
7466			_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
7467				var l = mfp.items.length;
7468				values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
7469			});
7470
7471			_mfpOn('BuildControls' + ns, function() {
7472				if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
7473					var markup = gSt.arrowMarkup,
7474						arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
7475						arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
7476
7477					arrowLeft.click(function() {
7478						mfp.prev();
7479					});
7480					arrowRight.click(function() {
7481						mfp.next();
7482					});
7483
7484					mfp.container.append(arrowLeft.add(arrowRight));
7485				}
7486			});
7487
7488			_mfpOn(CHANGE_EVENT+ns, function() {
7489				if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
7490
7491				mfp._preloadTimeout = setTimeout(function() {
7492					mfp.preloadNearbyImages();
7493					mfp._preloadTimeout = null;
7494				}, 16);
7495			});
7496
7497
7498			_mfpOn(CLOSE_EVENT+ns, function() {
7499				_document.off(ns);
7500				mfp.wrap.off('click'+ns);
7501				mfp.arrowRight = mfp.arrowLeft = null;
7502			});
7503
7504		},
7505		next: function() {
7506			mfp.direction = true;
7507			mfp.index = _getLoopedId(mfp.index + 1);
7508			mfp.updateItemHTML();
7509		},
7510		prev: function() {
7511			mfp.direction = false;
7512			mfp.index = _getLoopedId(mfp.index - 1);
7513			mfp.updateItemHTML();
7514		},
7515		goTo: function(newIndex) {
7516			mfp.direction = (newIndex >= mfp.index);
7517			mfp.index = newIndex;
7518			mfp.updateItemHTML();
7519		},
7520		preloadNearbyImages: function() {
7521			var p = mfp.st.gallery.preload,
7522				preloadBefore = Math.min(p[0], mfp.items.length),
7523				preloadAfter = Math.min(p[1], mfp.items.length),
7524				i;
7525
7526			for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
7527				mfp._preloadItem(mfp.index+i);
7528			}
7529			for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
7530				mfp._preloadItem(mfp.index-i);
7531			}
7532		},
7533		_preloadItem: function(index) {
7534			index = _getLoopedId(index);
7535
7536			if(mfp.items[index].preloaded) {
7537				return;
7538			}
7539
7540			var item = mfp.items[index];
7541			if(!item.parsed) {
7542				item = mfp.parseEl( index );
7543			}
7544
7545			_mfpTrigger('LazyLoad', item);
7546
7547			if(item.type === 'image') {
7548				item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
7549					item.hasSize = true;
7550				}).on('error.mfploader', function() {
7551					item.hasSize = true;
7552					item.loadError = true;
7553					_mfpTrigger('LazyLoadError', item);
7554				}).attr('src', item.src);
7555			}
7556
7557
7558			item.preloaded = true;
7559		}
7560	}
7561});
7562
7563/*>>gallery*/
7564
7565/*>>retina*/
7566
7567var RETINA_NS = 'retina';
7568
7569$.magnificPopup.registerModule(RETINA_NS, {
7570	options: {
7571		replaceSrc: function(item) {
7572			return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
7573		},
7574		ratio: 1 // Function or number.  Set to 1 to disable.
7575	},
7576	proto: {
7577		initRetina: function() {
7578			if(window.devicePixelRatio > 1) {
7579
7580				var st = mfp.st.retina,
7581					ratio = st.ratio;
7582
7583				ratio = !isNaN(ratio) ? ratio : ratio();
7584
7585				if(ratio > 1) {
7586					_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
7587						item.img.css({
7588							'max-width': item.img[0].naturalWidth / ratio,
7589							'width': '100%'
7590						});
7591					});
7592					_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
7593						item.src = st.replaceSrc(item, ratio);
7594					});
7595				}
7596			}
7597
7598		}
7599	}
7600});
7601
7602/*>>retina*/
7603 _checkInstance(); }));$(document).ready(function() {
7604
7605	
7606	// have to use document because sometimes we're loading artefact images into a modal on the archive page
7607	$(document).magnificPopup({
7608		delegate: '.magnific_gallery_click', // child items selector, by clicking on it popup will open
7609		type: 'image',
7610		closeOnContentClick: true,
7611		gallery: {
7612			enabled: true
7613		},
7614		image: {
7615			verticalFit: false
7616		}
7617	});
7618	
7619	
7620	$('.magnific_gallery_click_height_restrict').magnificPopup({
7621		type: 'image',
7622		closeOnContentClick: true,
7623		gallery: {
7624			enabled: true
7625		},
7626		image: {
7627			verticalFit: true
7628		}
7629	});
7630
7631
7632	/*
7633	$("#dynamicmodal").on("shown.bs.modal", function(e) {
7634			var link = $(e.relatedTarget);
7635			$(this).find(".modal-body").load(link.data('url'));
7636			// window.history.replaceState(null, null, link.attr("href"));
7637	});
7638	$('#dynamicmodal').on('hidden.bs.modal', function () {
7639		var $this = $(this);
7640		$this.find(".modal-body").html('');
7641		// window.history.replaceState(null, null, original_url);
7642	});
7643	
7644	
7645	*/
7646
7647
7648
7649	const dynamicmodal = document.getElementById('dynamicmodal');
7650	const modalBody = dynamicmodal.querySelector('.modal-body');
7651	
7652	let isClosingModal = false;
7653	let modalIsOpen = false;
7654	
7655	if (!history.state) {
7656		history.replaceState({ page: 'initial' }, '', window.location.href);
7657	}
7658	
7659	dynamicmodal.addEventListener('show.bs.modal', function (event) {
7660		const button = event.relatedTarget;
7661		if (button) {
7662			const cleanUrl = button.getAttribute('href');
7663			const ajaxUrl = button.getAttribute('data-bs-url');
7664	
7665			history.pushState({ page: 'modal' }, '', cleanUrl);
7666			modalIsOpen = true;
7667	
7668			fetch(ajaxUrl)
7669				.then(res => res.text())
7670				.then(html => {
7671					modalBody.innerHTML = html;
7672				});
7673		}
7674	});
7675	
7676	dynamicmodal.addEventListener('hide.bs.modal', function () {
7677		modalBody.innerHTML = '';
7678	
7679		if (history.state?.page === 'modal') {
7680			isClosingModal = true;
7681			history.back(); // Return to { page: 'initial' }
7682		}
7683		modalIsOpen = false;
7684	});
7685	
7686	window.addEventListener('popstate', function (event) {
7687		const modalInstance = bootstrap.Modal.getOrCreateInstance(dynamicmodal);
7688	
7689		if (event.state?.page === 'modal') {
7690			if (!modalIsOpen) {
7691				modalInstance.show();
7692			}
7693			modalIsOpen = true;
7694	
7695		} else if (event.state?.page === 'initial') {
7696			if (modalIsOpen) {
7697				// ✅ Just close modal, do not reload
7698				modalInstance.hide();
7699			} else if (!isClosingModal) {
7700				// ✅ Only reload if this was not triggered by modal close
7701				location.reload();
7702			}
7703	
7704			// ✅ Delay resetting flags to ensure modal closes first
7705			setTimeout(() => {
7706				isClosingModal = false;
7707				modalIsOpen = false;
7708			}, 50);
7709		}
7710	});
7711	
7712
7713
7714	
7715	
7716	const collapse_search = document.getElementById('collapse_search');
7717	const header_search = document.getElementById('header_search');
7718	
7719	collapse_search.addEventListener('shown.bs.collapse', event => {
7720		header_search.focus();
7721	})
7722	
7723	
7724	
7725	$(".validate_this_form").validate();
7726
7727
7728
7729	
7730	function autoheight(a) {
7731    if (!$(a).prop('scrollTop')) {
7732      do {
7733        var b = $(a).prop('scrollHeight');
7734        var h = $(a).height();
7735        $(a).height(h - 5);
7736      }
7737      while (b && (b != $(a).prop('scrollHeight')));
7738    };
7739    $(a).height($(a).prop('scrollHeight') + 20);
7740	}
7741	
7742	// open any autoheight boxes onload
7743	autoheight($(".autoExpand"));
7744	
7745	// if it's a popup
7746	$(document).on('focus', '.autoExpand', function(e) {
7747		autoheight(this);
7748	});
7749	
7750	
7751	
7752	
7753	
7754	gsap.registerPlugin(ScrollTrigger);
7755	
7756	ScrollTrigger.matchMedia({
7757		
7758		// desktop
7759		"(min-width: 992px)": function() {
7760	
7761	
7762			$(".gsap_hover_toggle_trigger").each(function (index, element){
7763				var tl = gsap.timeline({paused:true});
7764				
7765	
7766				tl.fromTo($(element).find(".gsap_hover_toggle"), {
7767					height: 0,
7768					opacity: 0
7769				}, {
7770					height: function(i, target) {
7771						target.style.height = "auto"; 
7772						var height = target.offsetHeight; //record the natural height
7773						target.style.height = "0px"; //now reset it to 0
7774						return height; //return the natural height
7775					},
7776					opacity: 1,
7777					duration: 0.2
7778				},
7779				0);
7780				
7781				if ($(element).find(".block__bar")) {
7782					
7783					tl.fromTo($(element).find(".block__bar"), {
7784						width: 0
7785					}, {
7786						width: '100%',
7787						duration: 0.3
7788					},
7789					0);
7790					
7791				}
7792				
7793				tl.fromTo($(element), {
7794					backgroundImage: 'linear-gradient(180deg, rgba(13, 15, 33, 0.1596) 0%, rgba(13, 15, 33, 0.456) 65%,rgba(13, 15, 33, 0.76) 80%, rgba(13, 15, 33, 0.96) 100%)',
7795				}, {
7796					backgroundImage: 'linear-gradient(180deg, rgba(13, 15, 33, 0.1596) 0%,rgba(13, 15, 33, 0.76) 30%, rgba(13, 15, 33, 0.96) 100%)',
7797					duration: 0.3
7798				},
7799				0);
7800				
7801				
7802				
7803				element.animation = tl;
7804			})
7805			
7806			$(".gsap_hover_toggle_trigger").mouseenter(function(){
7807				this.animation.play();
7808			})
7809			
7810			$(".gsap_hover_toggle_trigger").mouseleave(function(){
7811				this.animation.reverse();
7812			})
7813	
7814	
7815		},
7816	
7817		// mobile
7818		/*
7819		"(max-width: 991px)": function() {
7820	
7821			$(".gsap_hover_toggle_trigger").each(function (index, element){
7822	
7823				gsap.fromTo($(element).find(".gsap_hover_toggle"), {
7824					height: 0,
7825					opacity: 0
7826				}, {
7827					height: function(i, target) {
7828						target.style.height = "auto"; 
7829						var height = target.offsetHeight; //record the natural height
7830						target.style.height = "0px"; //now reset it to 0
7831						return height; //return the natural height
7832					},
7833					opacity: 1,
7834					duration: 0.5,
7835					scrollTrigger: {
7836						// markers: true,
7837						trigger: element,
7838						start: "top 30%"
7839					}
7840				},
7841				0);
7842				
7843			})
7844			
7845		},
7846		*/
7847		
7848		// all 
7849		"all": function() {
7850	
7851		}
7852		
7853	});
7854
7855
7856});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.