73 | var selector_chosen = quickElement('div', selector_div, '');
74 | selector_chosen.className = 'selector-chosen';
75 | var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
76 | quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name]));
77 |
78 | var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
79 | to_box.className = 'filtered';
80 | var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link');
81 | clear_all.className = 'selector-clearall';
82 |
83 | from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
84 |
85 | // Set up the JavaScript event handlers for the select box filter interface
86 | addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
87 | addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
88 | addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
89 | addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
90 | addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
91 | addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
92 | addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
93 | SelectBox.init(field_id + '_from');
94 | SelectBox.init(field_id + '_to');
95 | // Move selected from_box options to to_box
96 | SelectBox.move(field_id + '_from', field_id + '_to');
97 |
98 | if (!is_stacked) {
99 | // In horizontal mode, give the same height to the two boxes.
100 | var j_from_box = $(from_box);
101 | var j_to_box = $(to_box);
102 | var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }
103 | if (j_from_box.outerHeight() > 0) {
104 | resize_filters(); // This fieldset is already open. Resize now.
105 | } else {
106 | // This fieldset is probably collapsed. Wait for its 'show' event.
107 | j_to_box.closest('fieldset').one('show.fieldset', resize_filters);
108 | }
109 | }
110 |
111 | // Initial icon refresh
112 | SelectFilter.refresh_icons(field_id);
113 | },
114 | refresh_icons: function(field_id) {
115 | var from = $('#' + field_id + '_from');
116 | var to = $('#' + field_id + '_to');
117 | var is_from_selected = from.find('option:selected').length > 0;
118 | var is_to_selected = to.find('option:selected').length > 0;
119 | // Active if at least one item is selected
120 | $('#' + field_id + '_add_link').toggleClass('active', is_from_selected);
121 | $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected);
122 | // Active if the corresponding box isn't empty
123 | $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
124 | $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
125 | },
126 | filter_key_up: function(event, field_id) {
127 | var from = document.getElementById(field_id + '_from');
128 | // don't submit form if user pressed Enter
129 | if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
130 | from.selectedIndex = 0;
131 | SelectBox.move(field_id + '_from', field_id + '_to');
132 | from.selectedIndex = 0;
133 | return false;
134 | }
135 | var temp = from.selectedIndex;
136 | SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
137 | from.selectedIndex = temp;
138 | return true;
139 | },
140 | filter_key_down: function(event, field_id) {
141 | var from = document.getElementById(field_id + '_from');
142 | // right arrow -- move across
143 | if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
144 | var old_index = from.selectedIndex;
145 | SelectBox.move(field_id + '_from', field_id + '_to');
146 | from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
147 | return false;
148 | }
149 | // down arrow -- wrap around
150 | if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
151 | from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
152 | }
153 | // up arrow -- wrap around
154 | if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
155 | from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
156 | }
157 | return true;
158 | }
159 | }
160 |
161 | })(django.jQuery);
162 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/actions.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.fn.actions = function(opts) {
3 | var options = $.extend({}, $.fn.actions.defaults, opts);
4 | var actionCheckboxes = $(this);
5 | var list_editable_changed = false;
6 | var checker = function(checked) {
7 | if (checked) {
8 | showQuestion();
9 | } else {
10 | reset();
11 | }
12 | $(actionCheckboxes).prop("checked", checked)
13 | .parent().parent().toggleClass(options.selectedClass, checked);
14 | },
15 | updateCounter = function() {
16 | var sel = $(actionCheckboxes).filter(":checked").length;
17 | $(options.counterContainer).html(interpolate(
18 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
19 | sel: sel,
20 | cnt: _actions_icnt
21 | }, true));
22 | $(options.allToggle).prop("checked", function() {
23 | if (sel == actionCheckboxes.length) {
24 | value = true;
25 | showQuestion();
26 | } else {
27 | value = false;
28 | clearAcross();
29 | }
30 | return value;
31 | });
32 | },
33 | showQuestion = function() {
34 | $(options.acrossClears).hide();
35 | $(options.acrossQuestions).show();
36 | $(options.allContainer).hide();
37 | },
38 | showClear = function() {
39 | $(options.acrossClears).show();
40 | $(options.acrossQuestions).hide();
41 | $(options.actionContainer).toggleClass(options.selectedClass);
42 | $(options.allContainer).show();
43 | $(options.counterContainer).hide();
44 | },
45 | reset = function() {
46 | $(options.acrossClears).hide();
47 | $(options.acrossQuestions).hide();
48 | $(options.allContainer).hide();
49 | $(options.counterContainer).show();
50 | },
51 | clearAcross = function() {
52 | reset();
53 | $(options.acrossInput).val(0);
54 | $(options.actionContainer).removeClass(options.selectedClass);
55 | };
56 | // Show counter by default
57 | $(options.counterContainer).show();
58 | // Check state of checkboxes and reinit state if needed
59 | $(this).filter(":checked").each(function(i) {
60 | $(this).parent().parent().toggleClass(options.selectedClass);
61 | updateCounter();
62 | if ($(options.acrossInput).val() == 1) {
63 | showClear();
64 | }
65 | });
66 | $(options.allToggle).show().click(function() {
67 | checker($(this).prop("checked"));
68 | updateCounter();
69 | });
70 | $("div.actions span.question a").click(function(event) {
71 | event.preventDefault();
72 | $(options.acrossInput).val(1);
73 | showClear();
74 | });
75 | $("div.actions span.clear a").click(function(event) {
76 | event.preventDefault();
77 | $(options.allToggle).prop("checked", false);
78 | clearAcross();
79 | checker(0);
80 | updateCounter();
81 | });
82 | lastChecked = null;
83 | $(actionCheckboxes).click(function(event) {
84 | if (!event) { event = window.event; }
85 | var target = event.target ? event.target : event.srcElement;
86 | if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) {
87 | var inrange = false;
88 | $(lastChecked).prop("checked", target.checked)
89 | .parent().parent().toggleClass(options.selectedClass, target.checked);
90 | $(actionCheckboxes).each(function() {
91 | if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
92 | inrange = (inrange) ? false : true;
93 | }
94 | if (inrange) {
95 | $(this).prop("checked", target.checked)
96 | .parent().parent().toggleClass(options.selectedClass, target.checked);
97 | }
98 | });
99 | }
100 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked);
101 | lastChecked = target;
102 | updateCounter();
103 | });
104 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
105 | list_editable_changed = true;
106 | });
107 | $('form#changelist-form button[name="index"]').click(function(event) {
108 | if (list_editable_changed) {
109 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
110 | }
111 | });
112 | $('form#changelist-form input[name="_save"]').click(function(event) {
113 | var action_changed = false;
114 | $('div.actions select option:selected').each(function() {
115 | if ($(this).val()) {
116 | action_changed = true;
117 | }
118 | });
119 | if (action_changed) {
120 | if (list_editable_changed) {
121 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
122 | } else {
123 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
124 | }
125 | }
126 | });
127 | };
128 | /* Setup plugin defaults */
129 | $.fn.actions.defaults = {
130 | actionContainer: "div.actions",
131 | counterContainer: "span.action-counter",
132 | allContainer: "div.actions span.all",
133 | acrossInput: "div.actions input.select-across",
134 | acrossQuestions: "div.actions span.question",
135 | acrossClears: "div.actions span.clear",
136 | allToggle: "#action-toggle",
137 | selectedClass: "selected"
138 | };
139 | })(django.jQuery);
140 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/actions.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a.fn.actions=function(n){var b=a.extend({},a.fn.actions.defaults,n),e=a(this),g=false,k=function(c){c?i():j();a(e).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},f=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).prop("checked",function(){if(c==e.length){value=true;i()}else{value=false;l()}return value})},i=
2 | function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},j=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},l=function(){j();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();
3 | a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);f();a(b.acrossInput).val()==1&&m()});a(b.allToggle).show().click(function(){k(a(this).prop("checked"));f()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).prop("checked",false);l();k(0);f()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?
4 | c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey===true){var h=false;a(lastChecked).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))h=h?false:true;h&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);lastChecked=d;f()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){g=
5 | true});a('form#changelist-form button[name="index"]').click(function(){if(g)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c=true});if(c)return g?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):
6 | confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
7 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/admin/RelatedObjectLookups.js:
--------------------------------------------------------------------------------
1 | // Handles related-objects functionality: lookup link for raw_id_fields
2 | // and Add Another links.
3 |
4 | function html_unescape(text) {
5 | // Unescape a string that was escaped using django.utils.html.escape.
6 | text = text.replace(/</g, '<');
7 | text = text.replace(/>/g, '>');
8 | text = text.replace(/"/g, '"');
9 | text = text.replace(/'/g, "'");
10 | text = text.replace(/&/g, '&');
11 | return text;
12 | }
13 |
14 | // IE doesn't accept periods or dashes in the window name, but the element IDs
15 | // we use to generate popup window names may contain them, therefore we map them
16 | // to allowed characters in a reversible way so that we can locate the correct
17 | // element when the popup window is dismissed.
18 | function id_to_windowname(text) {
19 | text = text.replace(/\./g, '__dot__');
20 | text = text.replace(/\-/g, '__dash__');
21 | return text;
22 | }
23 |
24 | function windowname_to_id(text) {
25 | text = text.replace(/__dot__/g, '.');
26 | text = text.replace(/__dash__/g, '-');
27 | return text;
28 | }
29 |
30 | function showRelatedObjectLookupPopup(triggeringLink) {
31 | var name = triggeringLink.id.replace(/^lookup_/, '');
32 | name = id_to_windowname(name);
33 | var href;
34 | if (triggeringLink.href.search(/\?/) >= 0) {
35 | href = triggeringLink.href + '&_popup=1';
36 | } else {
37 | href = triggeringLink.href + '?_popup=1';
38 | }
39 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
40 | win.focus();
41 | return false;
42 | }
43 |
44 | function dismissRelatedLookupPopup(win, chosenId) {
45 | var name = windowname_to_id(win.name);
46 | var elem = document.getElementById(name);
47 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
48 | elem.value += ',' + chosenId;
49 | } else {
50 | document.getElementById(name).value = chosenId;
51 | }
52 | win.close();
53 | }
54 |
55 | function showAddAnotherPopup(triggeringLink) {
56 | var name = triggeringLink.id.replace(/^add_/, '');
57 | name = id_to_windowname(name);
58 | href = triggeringLink.href
59 | if (href.indexOf('?') == -1) {
60 | href += '?_popup=1';
61 | } else {
62 | href += '&_popup=1';
63 | }
64 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
65 | win.focus();
66 | return false;
67 | }
68 |
69 | function dismissAddAnotherPopup(win, newId, newRepr) {
70 | // newId and newRepr are expected to have previously been escaped by
71 | // django.utils.html.escape.
72 | newId = html_unescape(newId);
73 | newRepr = html_unescape(newRepr);
74 | var name = windowname_to_id(win.name);
75 | var elem = document.getElementById(name);
76 | if (elem) {
77 | var elemName = elem.nodeName.toUpperCase();
78 | if (elemName == 'SELECT') {
79 | var o = new Option(newRepr, newId);
80 | elem.options[elem.options.length] = o;
81 | o.selected = true;
82 | } else if (elemName == 'INPUT') {
83 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
84 | elem.value += ',' + newId;
85 | } else {
86 | elem.value = newId;
87 | }
88 | }
89 | } else {
90 | var toId = name + "_to";
91 | elem = document.getElementById(toId);
92 | var o = new Option(newRepr, newId);
93 | SelectBox.add_to_cache(toId, o);
94 | SelectBox.redisplay(toId);
95 | }
96 | win.close();
97 | }
98 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/calendar.js:
--------------------------------------------------------------------------------
1 | /*
2 | calendar.js - Calendar functions by Adrian Holovaty
3 | depends on core.js for utility functions like removeChildren or quickElement
4 | */
5 |
6 | // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
7 | var CalendarNamespace = {
8 | monthsOfYear: gettext('January February March April May June July August September October November December').split(' '),
9 | daysOfWeek: gettext('S M T W T F S').split(' '),
10 | firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
11 | isLeapYear: function(year) {
12 | return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0));
13 | },
14 | getDaysInMonth: function(month,year) {
15 | var days;
16 | if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
17 | days = 31;
18 | }
19 | else if (month==4 || month==6 || month==9 || month==11) {
20 | days = 30;
21 | }
22 | else if (month==2 && CalendarNamespace.isLeapYear(year)) {
23 | days = 29;
24 | }
25 | else {
26 | days = 28;
27 | }
28 | return days;
29 | },
30 | draw: function(month, year, div_id, callback) { // month = 1-12, year = 1-9999
31 | var today = new Date();
32 | var todayDay = today.getDate();
33 | var todayMonth = today.getMonth()+1;
34 | var todayYear = today.getFullYear();
35 | var todayClass = '';
36 |
37 | month = parseInt(month);
38 | year = parseInt(year);
39 | var calDiv = document.getElementById(div_id);
40 | removeChildren(calDiv);
41 | var calTable = document.createElement('table');
42 | quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year);
43 | var tableBody = quickElement('tbody', calTable);
44 |
45 | // Draw days-of-week header
46 | var tableRow = quickElement('tr', tableBody);
47 | for (var i = 0; i < 7; i++) {
48 | quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
49 | }
50 |
51 | var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
52 | var days = CalendarNamespace.getDaysInMonth(month, year);
53 |
54 | // Draw blanks before first of month
55 | tableRow = quickElement('tr', tableBody);
56 | for (var i = 0; i < startingPos; i++) {
57 | var _cell = quickElement('td', tableRow, ' ');
58 | _cell.style.backgroundColor = '#f3f3f3';
59 | }
60 |
61 | // Draw days of month
62 | var currentDay = 1;
63 | for (var i = startingPos; currentDay <= days; i++) {
64 | if (i%7 == 0 && currentDay != 1) {
65 | tableRow = quickElement('tr', tableBody);
66 | }
67 | if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) {
68 | todayClass='today';
69 | } else {
70 | todayClass='';
71 | }
72 | var cell = quickElement('td', tableRow, '', 'class', todayClass);
73 |
74 | quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));');
75 | currentDay++;
76 | }
77 |
78 | // Draw blanks after end of month (optional, but makes for valid code)
79 | while (tableRow.childNodes.length < 7) {
80 | var _cell = quickElement('td', tableRow, ' ');
81 | _cell.style.backgroundColor = '#f3f3f3';
82 | }
83 |
84 | calDiv.appendChild(calTable);
85 | }
86 | }
87 |
88 | // Calendar -- A calendar instance
89 | function Calendar(div_id, callback) {
90 | // div_id (string) is the ID of the element in which the calendar will
91 | // be displayed
92 | // callback (string) is the name of a JavaScript function that will be
93 | // called with the parameters (year, month, day) when a day in the
94 | // calendar is clicked
95 | this.div_id = div_id;
96 | this.callback = callback;
97 | this.today = new Date();
98 | this.currentMonth = this.today.getMonth() + 1;
99 | this.currentYear = this.today.getFullYear();
100 | }
101 | Calendar.prototype = {
102 | drawCurrent: function() {
103 | CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback);
104 | },
105 | drawDate: function(month, year) {
106 | this.currentMonth = month;
107 | this.currentYear = year;
108 | this.drawCurrent();
109 | },
110 | drawPreviousMonth: function() {
111 | if (this.currentMonth == 1) {
112 | this.currentMonth = 12;
113 | this.currentYear--;
114 | }
115 | else {
116 | this.currentMonth--;
117 | }
118 | this.drawCurrent();
119 | },
120 | drawNextMonth: function() {
121 | if (this.currentMonth == 12) {
122 | this.currentMonth = 1;
123 | this.currentYear++;
124 | }
125 | else {
126 | this.currentMonth++;
127 | }
128 | this.drawCurrent();
129 | },
130 | drawPreviousYear: function() {
131 | this.currentYear--;
132 | this.drawCurrent();
133 | },
134 | drawNextYear: function() {
135 | this.currentYear++;
136 | this.drawCurrent();
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/collapse.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $(document).ready(function() {
3 | // Add anchor tag for Show/Hide link
4 | $("fieldset.collapse").each(function(i, elem) {
5 | // Don't hide if fields in this fieldset have errors
6 | if ($(elem).find("div.errors").length == 0) {
7 | $(elem).addClass("collapsed").find("h2").first().append(' (
' + gettext("Show") +
9 | ' )');
10 | }
11 | });
12 | // Add toggle to anchor tag
13 | $("fieldset.collapse a.collapse-toggle").click(function(ev) {
14 | if ($(this).closest("fieldset").hasClass("collapsed")) {
15 | // Show
16 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
17 | } else {
18 | // Hide
19 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
20 | }
21 | return false;
22 | });
23 | });
24 | })(django.jQuery);
25 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/collapse.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){0==a(b).find("div.errors").length&&a(b).addClass("collapsed").find("h2").first().append(' (
'+gettext("Show")+" )")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
2 | [a(this).attr("id")]);return!1})})})(django.jQuery);
3 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/core.js:
--------------------------------------------------------------------------------
1 | // Core javascript helper functions
2 |
3 | // basic browser identification & version
4 | var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
6 |
7 | // Cross-browser event handlers.
8 | function addEvent(obj, evType, fn) {
9 | if (obj.addEventListener) {
10 | obj.addEventListener(evType, fn, false);
11 | return true;
12 | } else if (obj.attachEvent) {
13 | var r = obj.attachEvent("on" + evType, fn);
14 | return r;
15 | } else {
16 | return false;
17 | }
18 | }
19 |
20 | function removeEvent(obj, evType, fn) {
21 | if (obj.removeEventListener) {
22 | obj.removeEventListener(evType, fn, false);
23 | return true;
24 | } else if (obj.detachEvent) {
25 | obj.detachEvent("on" + evType, fn);
26 | return true;
27 | } else {
28 | return false;
29 | }
30 | }
31 |
32 | function cancelEventPropagation(e) {
33 | if (!e) e = window.event;
34 | e.cancelBubble = true;
35 | if (e.stopPropagation) e.stopPropagation();
36 | }
37 |
38 | // quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
39 | function quickElement() {
40 | var obj = document.createElement(arguments[0]);
41 | if (arguments[2] != '' && arguments[2] != null) {
42 | var textNode = document.createTextNode(arguments[2]);
43 | obj.appendChild(textNode);
44 | }
45 | var len = arguments.length;
46 | for (var i = 3; i < len; i += 2) {
47 | obj.setAttribute(arguments[i], arguments[i+1]);
48 | }
49 | arguments[1].appendChild(obj);
50 | return obj;
51 | }
52 |
53 | // "a" is reference to an object
54 | function removeChildren(a) {
55 | while (a.hasChildNodes()) a.removeChild(a.lastChild);
56 | }
57 |
58 | // ----------------------------------------------------------------------------
59 | // Cross-browser xmlhttp object
60 | // from http://jibbering.com/2002/4/httprequest.html
61 | // ----------------------------------------------------------------------------
62 | var xmlhttp;
63 | /*@cc_on @*/
64 | /*@if (@_jscript_version >= 5)
65 | try {
66 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
67 | } catch (e) {
68 | try {
69 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
70 | } catch (E) {
71 | xmlhttp = false;
72 | }
73 | }
74 | @else
75 | xmlhttp = false;
76 | @end @*/
77 | if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
78 | xmlhttp = new XMLHttpRequest();
79 | }
80 |
81 | // ----------------------------------------------------------------------------
82 | // Find-position functions by PPK
83 | // See http://www.quirksmode.org/js/findpos.html
84 | // ----------------------------------------------------------------------------
85 | function findPosX(obj) {
86 | var curleft = 0;
87 | if (obj.offsetParent) {
88 | while (obj.offsetParent) {
89 | curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
90 | obj = obj.offsetParent;
91 | }
92 | // IE offsetParent does not include the top-level
93 | if (isIE && obj.parentElement){
94 | curleft += obj.offsetLeft - obj.scrollLeft;
95 | }
96 | } else if (obj.x) {
97 | curleft += obj.x;
98 | }
99 | return curleft;
100 | }
101 |
102 | function findPosY(obj) {
103 | var curtop = 0;
104 | if (obj.offsetParent) {
105 | while (obj.offsetParent) {
106 | curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
107 | obj = obj.offsetParent;
108 | }
109 | // IE offsetParent does not include the top-level
110 | if (isIE && obj.parentElement){
111 | curtop += obj.offsetTop - obj.scrollTop;
112 | }
113 | } else if (obj.y) {
114 | curtop += obj.y;
115 | }
116 | return curtop;
117 | }
118 |
119 | //-----------------------------------------------------------------------------
120 | // Date object extensions
121 | // ----------------------------------------------------------------------------
122 |
123 | Date.prototype.getTwelveHours = function() {
124 | hours = this.getHours();
125 | if (hours == 0) {
126 | return 12;
127 | }
128 | else {
129 | return hours <= 12 ? hours : hours-12
130 | }
131 | }
132 |
133 | Date.prototype.getTwoDigitMonth = function() {
134 | return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
135 | }
136 |
137 | Date.prototype.getTwoDigitDate = function() {
138 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
139 | }
140 |
141 | Date.prototype.getTwoDigitTwelveHour = function() {
142 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
143 | }
144 |
145 | Date.prototype.getTwoDigitHour = function() {
146 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
147 | }
148 |
149 | Date.prototype.getTwoDigitMinute = function() {
150 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
151 | }
152 |
153 | Date.prototype.getTwoDigitSecond = function() {
154 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
155 | }
156 |
157 | Date.prototype.getHourMinute = function() {
158 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
159 | }
160 |
161 | Date.prototype.getHourMinuteSecond = function() {
162 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
163 | }
164 |
165 | Date.prototype.strftime = function(format) {
166 | var fields = {
167 | c: this.toString(),
168 | d: this.getTwoDigitDate(),
169 | H: this.getTwoDigitHour(),
170 | I: this.getTwoDigitTwelveHour(),
171 | m: this.getTwoDigitMonth(),
172 | M: this.getTwoDigitMinute(),
173 | p: (this.getHours() >= 12) ? 'PM' : 'AM',
174 | S: this.getTwoDigitSecond(),
175 | w: '0' + this.getDay(),
176 | x: this.toLocaleDateString(),
177 | X: this.toLocaleTimeString(),
178 | y: ('' + this.getFullYear()).substr(2, 4),
179 | Y: '' + this.getFullYear(),
180 | '%' : '%'
181 | };
182 | var result = '', i = 0;
183 | while (i < format.length) {
184 | if (format.charAt(i) === '%') {
185 | result = result + fields[format.charAt(i + 1)];
186 | ++i;
187 | }
188 | else {
189 | result = result + format.charAt(i);
190 | }
191 | ++i;
192 | }
193 | return result;
194 | }
195 |
196 | // ----------------------------------------------------------------------------
197 | // String object extensions
198 | // ----------------------------------------------------------------------------
199 | String.prototype.pad_left = function(pad_length, pad_string) {
200 | var new_string = this;
201 | for (var i = 0; new_string.length < pad_length; i++) {
202 | new_string = pad_string + new_string;
203 | }
204 | return new_string;
205 | }
206 |
207 | // ----------------------------------------------------------------------------
208 | // Get the computed style for and element
209 | // ----------------------------------------------------------------------------
210 | function getStyle(oElm, strCssRule){
211 | var strValue = "";
212 | if(document.defaultView && document.defaultView.getComputedStyle){
213 | strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
214 | }
215 | else if(oElm.currentStyle){
216 | strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
217 | return p1.toUpperCase();
218 | });
219 | strValue = oElm.currentStyle[strCssRule];
220 | }
221 | return strValue;
222 | }
223 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/inlines.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Django admin inlines
3 | *
4 | * Based on jQuery Formset 1.1
5 | * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
6 | * @requires jQuery 1.2.6 or later
7 | *
8 | * Copyright (c) 2009, Stanislaus Madueke
9 | * All rights reserved.
10 | *
11 | * Spiced up with Code from Zain Memon's GSoC project 2009
12 | * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip.
13 | *
14 | * Licensed under the New BSD License
15 | * See: http://www.opensource.org/licenses/bsd-license.php
16 | */
17 | (function($) {
18 | $.fn.formset = function(opts) {
19 | var options = $.extend({}, $.fn.formset.defaults, opts);
20 | var $this = $(this);
21 | var $parent = $this.parent();
22 | var updateElementIndex = function(el, prefix, ndx) {
23 | var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
24 | var replacement = prefix + "-" + ndx;
25 | if ($(el).prop("for")) {
26 | $(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
27 | }
28 | if (el.id) {
29 | el.id = el.id.replace(id_regex, replacement);
30 | }
31 | if (el.name) {
32 | el.name = el.name.replace(id_regex, replacement);
33 | }
34 | };
35 | var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
36 | var nextIndex = parseInt(totalForms.val(), 10);
37 | var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
38 | // only show the add button if we are allowed to add more items,
39 | // note that max_num = None translates to a blank string.
40 | var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
41 | $this.each(function(i) {
42 | $(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
43 | });
44 | if ($this.length && showAddButton) {
45 | var addButton;
46 | if ($this.prop("tagName") == "TR") {
47 | // If forms are laid out as table rows, insert the
48 | // "add" button in a new table row:
49 | var numCols = this.eq(-1).children().length;
50 | $parent.append('
' + options.addText + " ");
51 | addButton = $parent.find("tr:last a");
52 | } else {
53 | // Otherwise, insert it immediately after the last form:
54 | $this.filter(":last").after('
");
55 | addButton = $this.filter(":last").next().find("a");
56 | }
57 | addButton.click(function(e) {
58 | e.preventDefault();
59 | var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
60 | var template = $("#" + options.prefix + "-empty");
61 | var row = template.clone(true);
62 | row.removeClass(options.emptyCssClass)
63 | .addClass(options.formCssClass)
64 | .attr("id", options.prefix + "-" + nextIndex);
65 | if (row.is("tr")) {
66 | // If the forms are laid out in table rows, insert
67 | // the remove button into the last table cell:
68 | row.children(":last").append('
");
69 | } else if (row.is("ul") || row.is("ol")) {
70 | // If they're laid out as an ordered/unordered list,
71 | // insert an
after the last list item:
72 | row.append(' ' + options.deleteText + " ");
73 | } else {
74 | // Otherwise, just insert the remove button as the
75 | // last child element of the form's container:
76 | row.children(":first").append('
' + options.deleteText + " ");
77 | }
78 | row.find("*").each(function() {
79 | updateElementIndex(this, options.prefix, totalForms.val());
80 | });
81 | // Insert the new form when it has been fully edited
82 | row.insertBefore($(template));
83 | // Update number of total forms
84 | $(totalForms).val(parseInt(totalForms.val(), 10) + 1);
85 | nextIndex += 1;
86 | // Hide add button in case we've hit the max, except we want to add infinitely
87 | if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
88 | addButton.parent().hide();
89 | }
90 | // The delete button of each row triggers a bunch of other things
91 | row.find("a." + options.deleteCssClass).click(function(e) {
92 | e.preventDefault();
93 | // Remove the parent form containing this button:
94 | var row = $(this).parents("." + options.formCssClass);
95 | row.remove();
96 | nextIndex -= 1;
97 | // If a post-delete callback was provided, call it with the deleted form:
98 | if (options.removed) {
99 | options.removed(row);
100 | }
101 | // Update the TOTAL_FORMS form count.
102 | var forms = $("." + options.formCssClass);
103 | $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
104 | // Show add button again once we drop below max
105 | if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
106 | addButton.parent().show();
107 | }
108 | // Also, update names and ids for all remaining form controls
109 | // so they remain in sequence:
110 | for (var i=0, formCount=forms.length; i
'+a.addText+" "),h=d.find("tr:last a")):(c.filter(":last").after('"),h=c.filter(":last").next().find("a"));h.click(function(d){d.preventDefault();var f=b("#id_"+a.prefix+"-TOTAL_FORMS"),d=b("#"+a.prefix+
3 | "-empty"),c=d.clone(true);c.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+g);c.is("tr")?c.children(":last").append('"):c.is("ul")||c.is("ol")?c.append(''+a.deleteText+" "):c.children(":first").append(''+a.deleteText+" ");c.find("*").each(function(){i(this,
4 | a.prefix,f.val())});c.insertBefore(b(d));b(f).val(parseInt(f.val(),10)+1);g=g+1;e.val()!==""&&e.val()-f.val()<=0&&h.parent().hide();c.find("a."+a.deleteCssClass).click(function(d){d.preventDefault();d=b(this).parents("."+a.formCssClass);d.remove();g=g-1;a.removed&&a.removed(d);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(e.val()===""||e.val()-d.length>0)&&h.parent().show();for(var c=0,f=d.length;c 0) {
25 | values.push($(field).val());
26 | }
27 | })
28 | field.val(URLify(values.join(' '), maxLength));
29 | };
30 |
31 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate);
32 | });
33 | };
34 | })(django.jQuery);
35 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/prepopulate.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a.fn.prepopulate=function(d,g){return this.each(function(){var b=a(this);b.data("_changed",false);b.change(function(){b.data("_changed",true)});var c=function(){if(b.data("_changed")!=true){var e=[];a.each(d,function(h,f){a(f).val().length>0&&e.push(a(f).val())});b.val(URLify(e.join(" "),g))}};a(d.join(",")).keyup(c).change(c).focus(c)})}})(django.jQuery);
2 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/timeparse.js:
--------------------------------------------------------------------------------
1 | var timeParsePatterns = [
2 | // 9
3 | { re: /^\d{1,2}$/i,
4 | handler: function(bits) {
5 | if (bits[0].length == 1) {
6 | return '0' + bits[0] + ':00';
7 | } else {
8 | return bits[0] + ':00';
9 | }
10 | }
11 | },
12 | // 13:00
13 | { re: /^\d{2}[:.]\d{2}$/i,
14 | handler: function(bits) {
15 | return bits[0].replace('.', ':');
16 | }
17 | },
18 | // 9:00
19 | { re: /^\d[:.]\d{2}$/i,
20 | handler: function(bits) {
21 | return '0' + bits[0].replace('.', ':');
22 | }
23 | },
24 | // 3 am / 3 a.m. / 3am
25 | { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
26 | handler: function(bits) {
27 | var hour = parseInt(bits[1]);
28 | if (hour == 12) {
29 | hour = 0;
30 | }
31 | if (bits[2].toLowerCase() == 'p') {
32 | if (hour == 12) {
33 | hour = 0;
34 | }
35 | return (hour + 12) + ':00';
36 | } else {
37 | if (hour < 10) {
38 | return '0' + hour + ':00';
39 | } else {
40 | return hour + ':00';
41 | }
42 | }
43 | }
44 | },
45 | // 3.30 am / 3:15 a.m. / 3.00am
46 | { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
47 | handler: function(bits) {
48 | var hour = parseInt(bits[1]);
49 | var mins = parseInt(bits[2]);
50 | if (mins < 10) {
51 | mins = '0' + mins;
52 | }
53 | if (hour == 12) {
54 | hour = 0;
55 | }
56 | if (bits[3].toLowerCase() == 'p') {
57 | if (hour == 12) {
58 | hour = 0;
59 | }
60 | return (hour + 12) + ':' + mins;
61 | } else {
62 | if (hour < 10) {
63 | return '0' + hour + ':' + mins;
64 | } else {
65 | return hour + ':' + mins;
66 | }
67 | }
68 | }
69 | },
70 | // noon
71 | { re: /^no/i,
72 | handler: function(bits) {
73 | return '12:00';
74 | }
75 | },
76 | // midnight
77 | { re: /^mid/i,
78 | handler: function(bits) {
79 | return '00:00';
80 | }
81 | }
82 | ];
83 |
84 | function parseTimeString(s) {
85 | for (var i = 0; i < timeParsePatterns.length; i++) {
86 | var re = timeParsePatterns[i].re;
87 | var handler = timeParsePatterns[i].handler;
88 | var bits = re.exec(s);
89 | if (bits) {
90 | return handler(bits);
91 | }
92 | }
93 | return s;
94 | }
95 |
--------------------------------------------------------------------------------
/static/static_root/admin/js/urlify.js:
--------------------------------------------------------------------------------
1 | var LATIN_MAP = {
2 | 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
3 | 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
4 | 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
5 | 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
6 | 'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
7 | 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
8 | 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó':
9 | 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u',
10 | 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
11 | }
12 | var LATIN_SYMBOLS_MAP = {
13 | '©':'(c)'
14 | }
15 | var GREEK_MAP = {
16 | 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
17 | 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
18 | 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
19 | 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
20 | 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
21 | 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
22 | 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
23 | 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
24 | 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
25 | 'Ϋ':'Y'
26 | }
27 | var TURKISH_MAP = {
28 | 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
29 | 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G'
30 | }
31 | var RUSSIAN_MAP = {
32 | 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
33 | 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
34 | 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
35 | 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
36 | 'я':'ya',
37 | 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
38 | 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
39 | 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
40 | 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
41 | 'Я':'Ya'
42 | }
43 | var UKRAINIAN_MAP = {
44 | 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
45 | }
46 | var CZECH_MAP = {
47 | 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
48 | 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
49 | 'Ů':'U', 'Ž':'Z'
50 | }
51 |
52 | var POLISH_MAP = {
53 | 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z',
54 | 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'e', 'Ł':'L', 'Ń':'N', 'Ó':'o', 'Ś':'S',
55 | 'Ź':'Z', 'Ż':'Z'
56 | }
57 |
58 | var LATVIAN_MAP = {
59 | 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n',
60 | 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'i',
61 | 'Ķ':'k', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'u', 'Ž':'Z'
62 | }
63 |
64 | var ALL_DOWNCODE_MAPS=new Array()
65 | ALL_DOWNCODE_MAPS[0]=LATIN_MAP
66 | ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
67 | ALL_DOWNCODE_MAPS[2]=GREEK_MAP
68 | ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
69 | ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
70 | ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
71 | ALL_DOWNCODE_MAPS[6]=CZECH_MAP
72 | ALL_DOWNCODE_MAPS[7]=POLISH_MAP
73 | ALL_DOWNCODE_MAPS[8]=LATVIAN_MAP
74 |
75 | var Downcoder = new Object();
76 | Downcoder.Initialize = function()
77 | {
78 | if (Downcoder.map) // already made
79 | return ;
80 | Downcoder.map ={}
81 | Downcoder.chars = '' ;
82 | for(var i in ALL_DOWNCODE_MAPS)
83 | {
84 | var lookup = ALL_DOWNCODE_MAPS[i]
85 | for (var c in lookup)
86 | {
87 | Downcoder.map[c] = lookup[c] ;
88 | Downcoder.chars += c ;
89 | }
90 | }
91 | Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ;
92 | }
93 |
94 | downcode= function( slug )
95 | {
96 | Downcoder.Initialize() ;
97 | var downcoded =""
98 | var pieces = slug.match(Downcoder.regex);
99 | if(pieces)
100 | {
101 | for (var i = 0 ; i < pieces.length ; i++)
102 | {
103 | if (pieces[i].length == 1)
104 | {
105 | var mapped = Downcoder.map[pieces[i]] ;
106 | if (mapped != null)
107 | {
108 | downcoded+=mapped;
109 | continue ;
110 | }
111 | }
112 | downcoded+=pieces[i];
113 | }
114 | }
115 | else
116 | {
117 | downcoded = slug;
118 | }
119 | return downcoded;
120 | }
121 |
122 |
123 | function URLify(s, num_chars) {
124 | // changes, e.g., "Petty theft" to "petty_theft"
125 | // remove all these words from the string before urlifying
126 | s = downcode(s);
127 | removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
128 | "is", "in", "into", "like", "of", "off", "on", "onto", "per",
129 | "since", "than", "the", "this", "that", "to", "up", "via",
130 | "with"];
131 | r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
132 | s = s.replace(r, '');
133 | // if downcode doesn't hit, the char will be stripped here
134 | s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
135 | s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
136 | s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
137 | s = s.toLowerCase(); // convert to lowercase
138 | return s.substring(0, num_chars);// trim to first num_chars chars
139 | }
140 |
141 |
--------------------------------------------------------------------------------
/static/static_root/img/placeholder.svg:
--------------------------------------------------------------------------------
1 | 242x200
--------------------------------------------------------------------------------