- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
277 lines
9.4 KiB
JavaScript
277 lines
9.4 KiB
JavaScript
/*!
|
|
* instaFilta
|
|
* Version: 1.4.4
|
|
* Description: jQuery plugin for performing in-page filtering
|
|
* Homepage and documentation: https://github.com/chromawoods/instaFilta
|
|
* Author: Andreas Larsson <andreas@chromawoods.com> (http://chromawoods.com)
|
|
* Contributions: Jaap-Jan Frans
|
|
*/
|
|
;(function($) {
|
|
|
|
|
|
$.fn.instaFilta = function(options) {
|
|
|
|
var _filterTerm = null,
|
|
_filterCategory = null;
|
|
|
|
|
|
/* Default settings. */
|
|
var settings = $.extend({
|
|
|
|
scope: null,
|
|
targets: '.instafilta-target',
|
|
sections: '.instafilta-section',
|
|
categoryDataAttr: 'instafilta-category',
|
|
matchCssClass: 'instafilta-match',
|
|
itemsHideEffect: 'hide',
|
|
itemsHideDuration: 0,
|
|
itemsShowEffect: 'show',
|
|
itemsShowDuration: 0,
|
|
sectionsHideEffect: 'hide',
|
|
sectionsHideDuration: 0,
|
|
sectionsShowEffect: 'show',
|
|
sectionsShowDuration: 0,
|
|
onFilterComplete: null,
|
|
markMatches: false,
|
|
hideEmptySections: true,
|
|
beginsWith: false,
|
|
caseSensitive: false,
|
|
typeDelay: 0,
|
|
useSynonyms: true,
|
|
synonyms: [
|
|
{ src: 'à,á,å,ä,â,ã', dst: 'a' },
|
|
{ src: 'À,Á,Å,Ä,Â,Ã', dst: 'A' },
|
|
{ src: 'è,é,ë,ê', dst: 'e' },
|
|
{ src: 'È,É,Ë,Ê', dst: 'E' },
|
|
{ src: 'ì,í,ï,î', dst: 'i' },
|
|
{ src: 'Ì,Í,Ï,Î', dst: 'I' },
|
|
{ src: 'ò,ó,ö,ô,õ', dst: 'o' },
|
|
{ src: 'Ò,Ó,Ö,Ô,Õ', dst: 'O' },
|
|
{ src: 'ù,ú,ü,û', dst: 'u' },
|
|
{ src: 'Ù,Ú,Ü,Û', dst: 'U' },
|
|
{ src: 'ç', dst: 'c' },
|
|
{ src: 'Ç', dst: 'C' },
|
|
{ src: 'æ', dst: 'ae' }
|
|
]
|
|
}, options);
|
|
|
|
|
|
/* Split synonym src into arrays. */
|
|
if (settings.useSynonyms) {
|
|
for (var i = 0, l = settings.synonyms.length; i < l; i++) {
|
|
settings.synonyms[i].src = settings.synonyms[i].src.split(',');
|
|
}
|
|
}
|
|
|
|
|
|
/* Setup each instaFilta instance. */
|
|
this.each(function() {
|
|
|
|
var typeTimer,
|
|
$targets,
|
|
$sections,
|
|
$scopeElement,
|
|
lastTerm = '';
|
|
|
|
/* Check if this instance should be bound to a scope. */
|
|
if (settings.scope) {
|
|
$scopeElement = $(this).closest(settings.scope);
|
|
$targets = $scopeElement.find(settings.targets);
|
|
$sections = $scopeElement.find(settings.sections);
|
|
}
|
|
|
|
else {
|
|
$targets = $(settings.targets);
|
|
$sections = $(settings.sections);
|
|
}
|
|
|
|
/* Prepare value(s) to match against. */
|
|
$targets.each(function() {
|
|
|
|
$target = $(this), original = $target.text();
|
|
|
|
$target.data('values', (function(s) {
|
|
|
|
var values = [original], normalized = original;
|
|
|
|
if (!settings.useSynonyms) { return values; }
|
|
|
|
for (var i = 0, l = s.length; i < l; i++) {
|
|
|
|
for (var j = 0; j < s[i].src.length; j++) {
|
|
normalized = normalized.replace(s[i].src[j], s[i].dst);
|
|
}
|
|
|
|
}
|
|
|
|
!!(normalized === original) || values.push(normalized);
|
|
|
|
return values;
|
|
|
|
}(settings.synonyms)));
|
|
|
|
});
|
|
|
|
|
|
/* Will hide any sections that don't have data-instafilta-hidden="false" */
|
|
var toggleSections = function() {
|
|
|
|
$sections.each(function() {
|
|
|
|
var $section = $(this);
|
|
|
|
if ($section.find('[data-instafilta-hide="false"]').length) {
|
|
$section[settings.sectionsShowEffect](settings.sectionsShowDuration);
|
|
}
|
|
|
|
else {
|
|
$section[settings.sectionsHideEffect](settings.sectionsHideDuration);
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
/* Apply the results of the filtering process GUI-wise. */
|
|
var toggleResults = function(forceShowAll) {
|
|
|
|
var $matchedItems = (function() {
|
|
return forceShowAll ? $targets.attr('data-instafilta-hide', 'false') : $targets;
|
|
}()).filter('[data-instafilta-hide="false"]')[settings.itemsShowEffect](settings.itemsShowDuration);
|
|
|
|
forceShowAll || $targets.filter('[data-instafilta-hide="true"]')[settings.itemsHideEffect](settings.itemsHideDuration);
|
|
|
|
settings.hideEmptySections && toggleSections();
|
|
|
|
/* Check if a callback function has been provided. */
|
|
if (typeof settings.onFilterComplete === 'function') {
|
|
settings.onFilterComplete.apply(this, [$matchedItems]);
|
|
}
|
|
|
|
return $matchedItems;
|
|
};
|
|
|
|
|
|
/* Reset the filter completely. */
|
|
var showAll = function() {
|
|
return toggleResults(true);
|
|
};
|
|
|
|
|
|
/* Main filtering function. */
|
|
_filterTerm = function(term) {
|
|
|
|
term = settings.caseSensitive ? term : term.toLowerCase();
|
|
|
|
if (lastTerm === term) { return false; }
|
|
else { lastTerm = term; }
|
|
|
|
term || showAll();
|
|
|
|
/* Iterate through associated targets and find matches. */
|
|
$targets.each(function() {
|
|
|
|
var $item = $(this);
|
|
|
|
if (!$item.data('originalText')) {
|
|
$item.data('originalHtml', $item.html());
|
|
$item.data('originalText', $item.data('values')[0]);
|
|
}
|
|
|
|
/* Returns the index at which a match was found. Returns -1 if not found. */
|
|
var matchedIndex = (function(values, t) {
|
|
var index = -1;
|
|
|
|
for (var i = 0; i < values.length; i++) {
|
|
index = (settings.caseSensitive ? values[i] : values[i].toLowerCase()).indexOf(t);
|
|
if (index >= 0) { break; } // We have a match, no need to iterate further.
|
|
}
|
|
|
|
return index;
|
|
}($item.data('values'), term));
|
|
|
|
var originalText = $item.data('originalText'),
|
|
targetText = settings.caseSensitive ? originalText : originalText.toLowerCase(),
|
|
matchedText = null,
|
|
newText = null;
|
|
|
|
/* If we should mark the match, wrap it in a span tag. */
|
|
if (matchedIndex >= 0 && settings.markMatches) {
|
|
matchedText = originalText.substring(matchedIndex, matchedIndex + term.length);
|
|
newText = originalText.replace(matchedText, '<span class="' + settings.matchCssClass + '">' + matchedText + '</span>');
|
|
|
|
$item.html($item.data('originalHtml').replace(originalText, newText));
|
|
}
|
|
|
|
$item.attr('data-instafilta-hide', (settings.beginsWith && matchedIndex !== 0) || matchedIndex < 0 ? 'true' : 'false');
|
|
});
|
|
|
|
return toggleResults();
|
|
};
|
|
|
|
|
|
/* Filter items depending on category data attribute. Categories can be a comma separated
|
|
* string or an array of strings. Shows all targets if categories is falsy. */
|
|
_filterCategory = function(categories, requireAll) {
|
|
|
|
if (!categories || !categories.length) {
|
|
return showAll();
|
|
}
|
|
|
|
if (typeof categories === 'string') {
|
|
categories = categories.split(',');
|
|
}
|
|
|
|
$targets.each(function() {
|
|
|
|
var hideStatus = true,
|
|
matched = 0,
|
|
$item = $(this),
|
|
targetCats = $item.data(settings.categoryDataAttr);
|
|
|
|
if (targetCats) {
|
|
|
|
targetCats = targetCats.split(',');
|
|
|
|
for (var i = 0; i < targetCats.length; i++) {
|
|
for (var j = 0; j < categories.length; j++) {
|
|
if (targetCats[i] === categories[j]) {
|
|
if (requireAll) { matched++; }
|
|
else { hideStatus = false; break; }
|
|
}
|
|
}
|
|
}
|
|
|
|
if (requireAll && matched === categories.length) { hideStatus = false; }
|
|
$item.html($item.data('originalText')).attr('data-instafilta-hide', hideStatus);
|
|
}
|
|
|
|
});
|
|
|
|
return toggleResults();
|
|
};
|
|
|
|
|
|
/* Setup event handlers. */
|
|
$(this).on('keyup', function() {
|
|
var $field = $(this);
|
|
|
|
clearTimeout(typeTimer);
|
|
|
|
typeTimer = setTimeout(function() {
|
|
_filterTerm($field.val());
|
|
}, settings.typeDelay);
|
|
});
|
|
|
|
});
|
|
|
|
|
|
return {
|
|
filterTerm: _filterTerm,
|
|
filterCategory: _filterCategory
|
|
};
|
|
|
|
};
|
|
|
|
}(jQuery)); |