nodebb-plugin-recent-cards-2 3.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +22 -0
- package/LICENSE +8 -0
- package/README.md +78 -0
- package/eslint.config.mjs +12 -0
- package/library.js +291 -0
- package/package.json +37 -0
- package/plugin.json +42 -0
- package/static/external/bootstrap-grid.css +14 -0
- package/static/lib/admin.js +13 -0
- package/static/lib/external.js +33 -0
- package/static/lib/main.js +368 -0
- package/static/slick/slick-theme.css +113 -0
- package/static/slick/slick.css +118 -0
- package/static/slick/slick.min.js +1 -0
- package/static/style.scss +138 -0
- package/static/templates/admin/plugins/nodebb-plugin-recent-cards/tests/external.tpl +23 -0
- package/static/templates/admin/plugins/nodebb-plugin-recent-cards/widget.tpl +60 -0
- package/static/templates/admin/plugins/recentcards.tpl +32 -0
- package/static/templates/partials/nodebb-plugin-recent-cards/external/style.tpl +307 -0
- package/static/templates/partials/nodebb-plugin-recent-cards/header.tpl +74 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
$(document).ready(function () {
|
|
4
|
+
const rtl = $('html').attr('data-dir') === 'rtl';
|
|
5
|
+
const arrowClasses = 'link-secondary position-absolute top-50 translate-middle-y p-1 z-1';
|
|
6
|
+
const nextIcon = rtl ? 'fa-chevron-left' : 'fa-chevron-right';
|
|
7
|
+
const prevIcon = rtl ? 'fa-chevron-right' : 'fa-chevron-left';
|
|
8
|
+
const nextArrow = `<a href="#" class="${arrowClasses} slick-next" title="">
|
|
9
|
+
<i class="fa-solid fa-fw ${nextIcon} fa-lg"></i>
|
|
10
|
+
</a>`;
|
|
11
|
+
const prevArrow = `<a href="#" class="${arrowClasses} slick-prev" title="">
|
|
12
|
+
<i class="fa-solid fa-fw ${prevIcon} fa-lg"></i>
|
|
13
|
+
</a>`;
|
|
14
|
+
|
|
15
|
+
async function initSlick(container) {
|
|
16
|
+
if (!container.length || container.hasClass('slick-initialized')) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!config.recentCards || !config.recentCards.enableCarousel) {
|
|
21
|
+
container.removeClass('carousel-mode invisible');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const slideCount = parseInt(config.recentCards.maxSlides, 10) || 4;
|
|
26
|
+
const slideMargin = 16;
|
|
27
|
+
const env = utils.findBootstrapEnvironment();
|
|
28
|
+
if (['xxl', 'xl', 'lg'].includes(env)) {
|
|
29
|
+
const cards = container.find('.recent-card-container .recent-card');
|
|
30
|
+
const cardCount = Math.min(cards.length, slideCount);
|
|
31
|
+
if (cardCount > 0) {
|
|
32
|
+
cards.css({
|
|
33
|
+
width: (container.width() - ((cardCount - 1) * slideMargin)) / cardCount,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
container.slick({
|
|
38
|
+
infinite: false,
|
|
39
|
+
slidesToShow: slideCount,
|
|
40
|
+
slidesToScroll: slideCount,
|
|
41
|
+
rtl: rtl,
|
|
42
|
+
variableWidth: true,
|
|
43
|
+
dots: !!config.recentCards.enableCarouselPagination,
|
|
44
|
+
nextArrow: nextArrow,
|
|
45
|
+
prevArrow: prevArrow,
|
|
46
|
+
responsive: [{
|
|
47
|
+
breakpoint: 992, // md
|
|
48
|
+
settings: {
|
|
49
|
+
slidesToShow: 3,
|
|
50
|
+
slidesToScroll: 2,
|
|
51
|
+
infinite: false,
|
|
52
|
+
},
|
|
53
|
+
}, {
|
|
54
|
+
breakpoint: 768, // sm/xs
|
|
55
|
+
settings: {
|
|
56
|
+
slidesToShow: 2,
|
|
57
|
+
slidesToScroll: 1,
|
|
58
|
+
infinite: false,
|
|
59
|
+
},
|
|
60
|
+
}],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
container.removeClass('overflow-hidden invisible');
|
|
64
|
+
container.find('.slick-prev').translateAttr('title', '[[global:pagination.previouspage]]');
|
|
65
|
+
container.find('.slick-next').translateAttr('title', '[[global:pagination.nextpage]]');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// --- Category Filter ---
|
|
69
|
+
|
|
70
|
+
const isMobile = () => window.innerWidth < 576;
|
|
71
|
+
|
|
72
|
+
function openDropdown(pluginContainer) {
|
|
73
|
+
const dropdown = pluginContainer.find('.rc-filter-dropdown');
|
|
74
|
+
const btn = pluginContainer.find('.rc-filter-btn');
|
|
75
|
+
dropdown.removeClass('d-none');
|
|
76
|
+
btn.attr('aria-expanded', 'true');
|
|
77
|
+
|
|
78
|
+
// On mobile: add backdrop and lock body scroll
|
|
79
|
+
if (isMobile()) {
|
|
80
|
+
const backdrop = $('<div class="rc-backdrop"></div>');
|
|
81
|
+
backdrop.on('click', function () {
|
|
82
|
+
closeAllDropdowns();
|
|
83
|
+
});
|
|
84
|
+
pluginContainer.find('.rc-filter-wrapper').append(backdrop);
|
|
85
|
+
document.body.style.overflow = 'hidden';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function closeAllDropdowns() {
|
|
90
|
+
$('.rc-filter-dropdown').addClass('d-none');
|
|
91
|
+
$('.rc-filter-btn').attr('aria-expanded', 'false');
|
|
92
|
+
$('.rc-backdrop').remove();
|
|
93
|
+
document.body.style.overflow = '';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isLightColor(hex) {
|
|
97
|
+
if (!hex) return true;
|
|
98
|
+
hex = hex.replace('#', '');
|
|
99
|
+
if (hex.length === 3) {
|
|
100
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
101
|
+
}
|
|
102
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
|
103
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
|
104
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
|
105
|
+
return (r * 299 + g * 587 + b * 114) / 1000 > 128;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getStorageKey(categories) {
|
|
109
|
+
const sortedCids = categories.map(c => c.cid).sort((a, b) => a - b);
|
|
110
|
+
return 'rc-filter-' + sortedCids.join('-');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function loadFilter(storageKey, validCids) {
|
|
114
|
+
try {
|
|
115
|
+
const stored = JSON.parse(localStorage.getItem(storageKey));
|
|
116
|
+
if (!Array.isArray(stored)) return null;
|
|
117
|
+
const filtered = stored.filter(cid => validCids.includes(cid));
|
|
118
|
+
return filtered.length ? filtered : null;
|
|
119
|
+
} catch (e) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function saveFilter(storageKey, selectedCids, allCids) {
|
|
125
|
+
if (!selectedCids || selectedCids.length === 0 || selectedCids.length === allCids.length) {
|
|
126
|
+
localStorage.removeItem(storageKey);
|
|
127
|
+
} else {
|
|
128
|
+
localStorage.setItem(storageKey, JSON.stringify(selectedCids));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function buildDropdown(pluginContainer, categories, selectedCids) {
|
|
133
|
+
const inner = pluginContainer.find('.rc-filter-dropdown-inner');
|
|
134
|
+
inner.empty();
|
|
135
|
+
|
|
136
|
+
categories.forEach(function (cat) {
|
|
137
|
+
const isChecked = !selectedCids || selectedCids.includes(cat.cid);
|
|
138
|
+
const item = $('<label class="rc-filter-option d-flex align-items-center gap-2 px-3 py-2"></label>');
|
|
139
|
+
const checkbox = $('<input type="checkbox" class="form-check-input mt-0">')
|
|
140
|
+
.attr('data-cid', cat.cid)
|
|
141
|
+
.prop('checked', isChecked);
|
|
142
|
+
|
|
143
|
+
const nameSpan = $('<span class="badge"></span>')
|
|
144
|
+
.css({ backgroundColor: cat.bgColor || '#6c757d', color: cat.color || '#fff' })
|
|
145
|
+
.text(cat.name);
|
|
146
|
+
|
|
147
|
+
item.append(checkbox);
|
|
148
|
+
if (cat.icon) {
|
|
149
|
+
item.append($('<i></i>').addClass('fa').addClass(cat.icon).css('color', cat.bgColor || '#6c757d'));
|
|
150
|
+
}
|
|
151
|
+
item.append(nameSpan);
|
|
152
|
+
inner.append(item);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function updateChips(pluginContainer, selectedCids, categories) {
|
|
157
|
+
const chipsContainer = pluginContainer.find('.rc-filter-chips');
|
|
158
|
+
chipsContainer.empty();
|
|
159
|
+
|
|
160
|
+
if (!selectedCids || selectedCids.length === 0 || selectedCids.length === categories.length) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
selectedCids.forEach(function (cid) {
|
|
165
|
+
const cat = categories.find(c => c.cid === cid);
|
|
166
|
+
if (!cat) return;
|
|
167
|
+
const chip = $('<span class="rc-filter-chip badge d-flex align-items-center gap-1"></span>')
|
|
168
|
+
.attr('data-cid', cid)
|
|
169
|
+
.css({ backgroundColor: cat.bgColor || '#6c757d', color: cat.color || '#fff' });
|
|
170
|
+
chip.append($('<span></span>').text(cat.name));
|
|
171
|
+
const closeBtn = $('<button type="button" class="btn-close rc-chip-remove" aria-label="Remove"></button>');
|
|
172
|
+
if (!isLightColor(cat.bgColor)) {
|
|
173
|
+
closeBtn.addClass('btn-close-white');
|
|
174
|
+
}
|
|
175
|
+
chip.append(closeBtn);
|
|
176
|
+
chipsContainer.append(chip);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
chipsContainer.append(
|
|
180
|
+
$('<button type="button" class="btn btn-link btn-sm rc-clear-all text-decoration-none p-0 ms-1"></button>')
|
|
181
|
+
.text('Temizle')
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function updateFilterButton(pluginContainer, selectedCids, categories) {
|
|
186
|
+
const btn = pluginContainer.find('.rc-filter-btn');
|
|
187
|
+
const isFiltered = selectedCids && selectedCids.length > 0 && selectedCids.length < categories.length;
|
|
188
|
+
btn.toggleClass('btn-outline-secondary', !isFiltered);
|
|
189
|
+
btn.toggleClass('btn-primary', isFiltered);
|
|
190
|
+
const label = btn.find('.rc-filter-label');
|
|
191
|
+
label.text(isFiltered ? 'Filtrele (' + selectedCids.length + ')' : 'Filtrele');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function applyFilter(pluginContainer, selectedCids, categories) {
|
|
195
|
+
const carouselContainer = pluginContainer.find('.recent-cards');
|
|
196
|
+
const isSlickInitialized = carouselContainer.hasClass('slick-initialized');
|
|
197
|
+
const isCarouselMode = config.recentCards && config.recentCards.enableCarousel;
|
|
198
|
+
const showAll = !selectedCids || selectedCids.length === 0 || selectedCids.length === categories.length;
|
|
199
|
+
|
|
200
|
+
// Step 1: Destroy slick if initialized
|
|
201
|
+
if (isSlickInitialized) {
|
|
202
|
+
try {
|
|
203
|
+
carouselContainer.slick('unslick');
|
|
204
|
+
} catch (e) {
|
|
205
|
+
// Slick was not properly initialized
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Step 2: Restore any previously detached cards back into the container
|
|
210
|
+
const stash = pluginContainer.data('rc-stashed-cards');
|
|
211
|
+
if (stash && stash.length) {
|
|
212
|
+
carouselContainer.append(stash);
|
|
213
|
+
pluginContainer.removeData('rc-stashed-cards');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Step 3: Detach cards that don't match the filter (not just hide — Slick counts hidden children)
|
|
217
|
+
const toStashElements = [];
|
|
218
|
+
let visibleCount = 0;
|
|
219
|
+
carouselContainer.find('.recent-card-container').each(function () {
|
|
220
|
+
const cardCid = parseInt($(this).attr('data-cid'), 10);
|
|
221
|
+
if (showAll || selectedCids.includes(cardCid)) {
|
|
222
|
+
visibleCount++;
|
|
223
|
+
} else {
|
|
224
|
+
toStashElements.push(this);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
if (toStashElements.length) {
|
|
229
|
+
const toStash = $(toStashElements).detach();
|
|
230
|
+
pluginContainer.data('rc-stashed-cards', toStash);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Step 4: Handle empty state
|
|
234
|
+
const emptyState = pluginContainer.find('.rc-empty-state');
|
|
235
|
+
if (visibleCount === 0) {
|
|
236
|
+
emptyState.removeClass('d-none');
|
|
237
|
+
carouselContainer.addClass('d-none');
|
|
238
|
+
} else {
|
|
239
|
+
emptyState.addClass('d-none');
|
|
240
|
+
carouselContainer.removeClass('d-none');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Step 5: Reinitialize slick with only the cards still in the DOM
|
|
244
|
+
if (isCarouselMode && visibleCount > 0) {
|
|
245
|
+
carouselContainer.addClass('overflow-hidden invisible');
|
|
246
|
+
initSlick(carouselContainer);
|
|
247
|
+
} else if (!isCarouselMode) {
|
|
248
|
+
carouselContainer.removeClass('carousel-mode invisible');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Step 6: Update UI
|
|
252
|
+
updateChips(pluginContainer, selectedCids, categories);
|
|
253
|
+
updateFilterButton(pluginContainer, selectedCids, categories);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function parseCategories(pluginContainer) {
|
|
257
|
+
const scriptTag = pluginContainer.find('script.rc-categories-data');
|
|
258
|
+
if (!scriptTag.length) return [];
|
|
259
|
+
try {
|
|
260
|
+
const parsed = JSON.parse(scriptTag.text());
|
|
261
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
262
|
+
} catch (e) {
|
|
263
|
+
return [];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function initFilter(pluginContainer) {
|
|
268
|
+
const categories = parseCategories(pluginContainer);
|
|
269
|
+
const filterBar = pluginContainer.find('.rc-filter-bar');
|
|
270
|
+
|
|
271
|
+
// Hide filter if fewer than 2 categories
|
|
272
|
+
if (categories.length < 2) {
|
|
273
|
+
filterBar.addClass('d-none');
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const allCids = categories.map(c => c.cid);
|
|
278
|
+
const storageKey = getStorageKey(categories);
|
|
279
|
+
const savedFilter = loadFilter(storageKey, allCids);
|
|
280
|
+
|
|
281
|
+
buildDropdown(pluginContainer, categories, savedFilter);
|
|
282
|
+
|
|
283
|
+
// Bind events (use .off first to prevent duplicates from ajaxify)
|
|
284
|
+
pluginContainer.off('.rcFilter');
|
|
285
|
+
|
|
286
|
+
// Toggle dropdown
|
|
287
|
+
pluginContainer.on('click.rcFilter', '.rc-filter-btn', function (e) {
|
|
288
|
+
e.stopPropagation();
|
|
289
|
+
const isOpen = !pluginContainer.find('.rc-filter-dropdown').hasClass('d-none');
|
|
290
|
+
closeAllDropdowns();
|
|
291
|
+
if (!isOpen) {
|
|
292
|
+
openDropdown(pluginContainer);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Checkbox change
|
|
297
|
+
pluginContainer.on('change.rcFilter', '.rc-filter-option input[type="checkbox"]', function () {
|
|
298
|
+
const selected = [];
|
|
299
|
+
pluginContainer.find('.rc-filter-option input:checked').each(function () {
|
|
300
|
+
selected.push(parseInt($(this).attr('data-cid'), 10));
|
|
301
|
+
});
|
|
302
|
+
saveFilter(storageKey, selected, allCids);
|
|
303
|
+
applyFilter(pluginContainer, selected, categories);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Chip remove
|
|
307
|
+
pluginContainer.on('click.rcFilter', '.rc-chip-remove', function (e) {
|
|
308
|
+
e.stopPropagation();
|
|
309
|
+
const chip = $(this).closest('.rc-filter-chip');
|
|
310
|
+
const cidToRemove = parseInt(chip.attr('data-cid'), 10);
|
|
311
|
+
pluginContainer.find('.rc-filter-option input[data-cid="' + cidToRemove + '"]')
|
|
312
|
+
.prop('checked', false).trigger('change');
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// Clear all
|
|
316
|
+
pluginContainer.on('click.rcFilter', '.rc-clear-all', function (e) {
|
|
317
|
+
e.stopPropagation();
|
|
318
|
+
pluginContainer.find('.rc-filter-option input').prop('checked', true);
|
|
319
|
+
saveFilter(storageKey, allCids, allCids);
|
|
320
|
+
applyFilter(pluginContainer, null, categories);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Apply saved filter if exists
|
|
324
|
+
if (savedFilter) {
|
|
325
|
+
applyFilter(pluginContainer, savedFilter, categories);
|
|
326
|
+
return true; // filter was applied (slick handled inside applyFilter)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return false; // no filter applied, caller should init slick
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function setupWidget(pluginContainer) {
|
|
333
|
+
const filterApplied = initFilter(pluginContainer);
|
|
334
|
+
if (!filterApplied) {
|
|
335
|
+
initSlick(pluginContainer.find('.recent-cards'));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Close dropdown on outside click & Escape
|
|
340
|
+
function bindGlobalHandlers() {
|
|
341
|
+
$(document).off('.rcFilter');
|
|
342
|
+
|
|
343
|
+
$(document).on('click.rcFilter', function (e) {
|
|
344
|
+
if (!$(e.target).closest('.rc-filter-wrapper').length) {
|
|
345
|
+
closeAllDropdowns();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
$(document).on('keydown.rcFilter', function (e) {
|
|
350
|
+
if (e.key === 'Escape') {
|
|
351
|
+
closeAllDropdowns();
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Initialize
|
|
357
|
+
bindGlobalHandlers();
|
|
358
|
+
$('.recent-cards-plugin').each(function () {
|
|
359
|
+
setupWidget($(this));
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
$(window).on('action:ajaxify.contentLoaded', function () {
|
|
363
|
+
bindGlobalHandlers();
|
|
364
|
+
$('.recent-cards-plugin').each(function () {
|
|
365
|
+
setupWidget($(this));
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
|
|
2
|
+
/* modified from https://gist.github.com/vivekkumawat/c8351e28412a194aac977bf996c4a6d8 */
|
|
3
|
+
|
|
4
|
+
/* CSS For Slick Slider */
|
|
5
|
+
/* Note: Don't use slick-theme.css file */
|
|
6
|
+
|
|
7
|
+
/* Adding margin between slides */
|
|
8
|
+
.slick-slide {
|
|
9
|
+
margin: 0 8px;
|
|
10
|
+
}
|
|
11
|
+
.slick-list {
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* Arrows */
|
|
16
|
+
.slick-prev.slick-disabled,
|
|
17
|
+
.slick-next.slick-disabled
|
|
18
|
+
{
|
|
19
|
+
opacity: .25;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* rtlcss converts these to right/left:0px on RTL */
|
|
23
|
+
.slick-prev { left: 0px; }
|
|
24
|
+
.slick-next { right: 0px; }
|
|
25
|
+
|
|
26
|
+
/* Dots */
|
|
27
|
+
.slick-dotted.slick-slider
|
|
28
|
+
{
|
|
29
|
+
margin-bottom: 30px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.slick-dots
|
|
33
|
+
{
|
|
34
|
+
position: absolute;
|
|
35
|
+
bottom: -25px;
|
|
36
|
+
|
|
37
|
+
display: block;
|
|
38
|
+
|
|
39
|
+
width: 100%;
|
|
40
|
+
padding: 0;
|
|
41
|
+
margin: 0;
|
|
42
|
+
|
|
43
|
+
list-style: none;
|
|
44
|
+
|
|
45
|
+
text-align: center;
|
|
46
|
+
}
|
|
47
|
+
.slick-dots li
|
|
48
|
+
{
|
|
49
|
+
position: relative;
|
|
50
|
+
|
|
51
|
+
display: inline-block;
|
|
52
|
+
|
|
53
|
+
width: 20px;
|
|
54
|
+
height: 20px;
|
|
55
|
+
margin: 0 5px;
|
|
56
|
+
padding: 0;
|
|
57
|
+
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
}
|
|
60
|
+
.slick-dots li button
|
|
61
|
+
{
|
|
62
|
+
font-size: 0;
|
|
63
|
+
line-height: 0;
|
|
64
|
+
|
|
65
|
+
display: block;
|
|
66
|
+
|
|
67
|
+
width: 20px;
|
|
68
|
+
height: 20px;
|
|
69
|
+
padding: 5px;
|
|
70
|
+
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
|
|
73
|
+
color: transparent;
|
|
74
|
+
border: 0;
|
|
75
|
+
outline: none;
|
|
76
|
+
background: transparent;
|
|
77
|
+
}
|
|
78
|
+
.slick-dots li button:hover,
|
|
79
|
+
.slick-dots li button:focus
|
|
80
|
+
{
|
|
81
|
+
outline: none;
|
|
82
|
+
}
|
|
83
|
+
.slick-dots li button:hover:before,
|
|
84
|
+
.slick-dots li button:focus:before
|
|
85
|
+
{
|
|
86
|
+
opacity: 1;
|
|
87
|
+
}
|
|
88
|
+
.slick-dots li button:before
|
|
89
|
+
{
|
|
90
|
+
font-size: 8px;
|
|
91
|
+
line-height: 20px;
|
|
92
|
+
|
|
93
|
+
position: absolute;
|
|
94
|
+
top: 0;
|
|
95
|
+
left: 0;
|
|
96
|
+
|
|
97
|
+
width: 20px;
|
|
98
|
+
height: 20px;
|
|
99
|
+
|
|
100
|
+
content: '•';
|
|
101
|
+
text-align: center;
|
|
102
|
+
|
|
103
|
+
opacity: .25;
|
|
104
|
+
color: black;
|
|
105
|
+
|
|
106
|
+
-webkit-font-smoothing: antialiased;
|
|
107
|
+
-moz-osx-font-smoothing: grayscale;
|
|
108
|
+
}
|
|
109
|
+
.slick-dots li.slick-active button:before
|
|
110
|
+
{
|
|
111
|
+
opacity: .75;
|
|
112
|
+
color: black;
|
|
113
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* Slider */
|
|
2
|
+
.slick-slider
|
|
3
|
+
{
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
display: block;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
|
|
9
|
+
-webkit-user-select: none;
|
|
10
|
+
-moz-user-select: none;
|
|
11
|
+
-ms-user-select: none;
|
|
12
|
+
user-select: none;
|
|
13
|
+
|
|
14
|
+
-webkit-touch-callout: none;
|
|
15
|
+
-khtml-user-select: none;
|
|
16
|
+
-ms-touch-action: pan-y;
|
|
17
|
+
touch-action: pan-y;
|
|
18
|
+
-webkit-tap-highlight-color: transparent;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.slick-list
|
|
22
|
+
{
|
|
23
|
+
position: relative;
|
|
24
|
+
|
|
25
|
+
display: block;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
|
|
28
|
+
margin: 0;
|
|
29
|
+
padding: 0;
|
|
30
|
+
}
|
|
31
|
+
.slick-list:focus
|
|
32
|
+
{
|
|
33
|
+
outline: none;
|
|
34
|
+
}
|
|
35
|
+
.slick-list.dragging
|
|
36
|
+
{
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
cursor: hand;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.slick-slider .slick-track,
|
|
42
|
+
.slick-slider .slick-list
|
|
43
|
+
{
|
|
44
|
+
-webkit-transform: translate3d(0, 0, 0);
|
|
45
|
+
-moz-transform: translate3d(0, 0, 0);
|
|
46
|
+
-ms-transform: translate3d(0, 0, 0);
|
|
47
|
+
-o-transform: translate3d(0, 0, 0);
|
|
48
|
+
transform: translate3d(0, 0, 0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.slick-track
|
|
52
|
+
{
|
|
53
|
+
position: relative;
|
|
54
|
+
top: 0;
|
|
55
|
+
left: 0;
|
|
56
|
+
|
|
57
|
+
display: block;
|
|
58
|
+
margin-left: auto;
|
|
59
|
+
margin-right: auto;
|
|
60
|
+
}
|
|
61
|
+
.slick-track:before,
|
|
62
|
+
.slick-track:after
|
|
63
|
+
{
|
|
64
|
+
display: table;
|
|
65
|
+
|
|
66
|
+
content: '';
|
|
67
|
+
}
|
|
68
|
+
.slick-track:after
|
|
69
|
+
{
|
|
70
|
+
clear: both;
|
|
71
|
+
}
|
|
72
|
+
.slick-loading .slick-track
|
|
73
|
+
{
|
|
74
|
+
visibility: hidden;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.slick-slide
|
|
78
|
+
{
|
|
79
|
+
display: none;
|
|
80
|
+
float: left;
|
|
81
|
+
|
|
82
|
+
height: 100%;
|
|
83
|
+
min-height: 1px;
|
|
84
|
+
}
|
|
85
|
+
[dir='rtl'] .slick-slide
|
|
86
|
+
{
|
|
87
|
+
float: right;
|
|
88
|
+
}
|
|
89
|
+
.slick-slide.slick-loading img
|
|
90
|
+
{
|
|
91
|
+
display: none;
|
|
92
|
+
}
|
|
93
|
+
.slick-slide .topic-title img {
|
|
94
|
+
display: inline-block
|
|
95
|
+
}
|
|
96
|
+
.slick-slide.dragging img
|
|
97
|
+
{
|
|
98
|
+
pointer-events: none;
|
|
99
|
+
}
|
|
100
|
+
.slick-initialized .slick-slide
|
|
101
|
+
{
|
|
102
|
+
display: block;
|
|
103
|
+
}
|
|
104
|
+
.slick-loading .slick-slide
|
|
105
|
+
{
|
|
106
|
+
visibility: hidden;
|
|
107
|
+
}
|
|
108
|
+
.slick-vertical .slick-slide
|
|
109
|
+
{
|
|
110
|
+
display: block;
|
|
111
|
+
|
|
112
|
+
height: auto;
|
|
113
|
+
|
|
114
|
+
border: 1px solid transparent;
|
|
115
|
+
}
|
|
116
|
+
.slick-arrow.slick-hidden {
|
|
117
|
+
display: none;
|
|
118
|
+
}
|