🐛 Update: Added support for the 'find' command in settings.local.json. Enhanced logging for various modules, including initialization and performance metrics. Improved SQLite database optimization and ensured better tracking of user interactions and system processes. 📚

This commit is contained in:
2025-06-14 16:26:43 +02:00
parent ee54bc273c
commit 89037861e3
2472 changed files with 691099 additions and 1 deletions

646
network-visualization/node_modules/serve-index/index.js generated vendored Normal file
View File

@@ -0,0 +1,646 @@
/*!
* serve-index
* Copyright(c) 2011 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var accepts = require('accepts');
var createError = require('http-errors');
var debug = require('debug')('serve-index');
var escapeHtml = require('escape-html');
var fs = require('fs')
, path = require('path')
, normalize = path.normalize
, sep = path.sep
, extname = path.extname
, join = path.join;
var Batch = require('batch');
var mime = require('mime-types');
var parseUrl = require('parseurl');
var resolve = require('path').resolve;
/**
* Module exports.
* @public
*/
module.exports = serveIndex;
/*!
* Icon cache.
*/
var cache = {};
/*!
* Default template.
*/
var defaultTemplate = join(__dirname, 'public', 'directory.html');
/*!
* Stylesheet.
*/
var defaultStylesheet = join(__dirname, 'public', 'style.css');
/**
* Media types and the map for content negotiation.
*/
var mediaTypes = [
'text/html',
'text/plain',
'application/json'
];
var mediaType = {
'text/html': 'html',
'text/plain': 'plain',
'application/json': 'json'
};
/**
* Serve directory listings with the given `root` path.
*
* See Readme.md for documentation of options.
*
* @param {String} root
* @param {Object} options
* @return {Function} middleware
* @public
*/
function serveIndex(root, options) {
var opts = options || {};
// root required
if (!root) {
throw new TypeError('serveIndex() root path required');
}
// resolve root to absolute and normalize
var rootPath = normalize(resolve(root) + sep);
var filter = opts.filter;
var hidden = opts.hidden;
var icons = opts.icons;
var stylesheet = opts.stylesheet || defaultStylesheet;
var template = opts.template || defaultTemplate;
var view = opts.view || 'tiles';
return function (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
res.statusCode = 'OPTIONS' === req.method ? 200 : 405;
res.setHeader('Allow', 'GET, HEAD, OPTIONS');
res.setHeader('Content-Length', '0');
res.end();
return;
}
// parse URLs
var url = parseUrl(req);
var originalUrl = parseUrl.original(req);
var dir = decodeURIComponent(url.pathname);
var originalDir = decodeURIComponent(originalUrl.pathname);
// join / normalize from root dir
var path = normalize(join(rootPath, dir));
// null byte(s), bad request
if (~path.indexOf('\0')) return next(createError(400));
// malicious path
if ((path + sep).substr(0, rootPath.length) !== rootPath) {
debug('malicious path "%s"', path);
return next(createError(403));
}
// determine ".." display
var showUp = normalize(resolve(path) + sep) !== rootPath;
// check if we have a directory
debug('stat "%s"', path);
fs.stat(path, function(err, stat){
if (err && err.code === 'ENOENT') {
return next();
}
if (err) {
err.status = err.code === 'ENAMETOOLONG'
? 414
: 500;
return next(err);
}
if (!stat.isDirectory()) return next();
// fetch files
debug('readdir "%s"', path);
fs.readdir(path, function(err, files){
if (err) return next(err);
if (!hidden) files = removeHidden(files);
if (filter) files = files.filter(function(filename, index, list) {
return filter(filename, index, list, path);
});
files.sort();
// content-negotiation
var accept = accepts(req);
var type = accept.type(mediaTypes);
// not acceptable
if (!type) return next(createError(406));
serveIndex[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet);
});
});
};
};
/**
* Respond with text/html.
*/
serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path, view, template, stylesheet) {
var render = typeof template !== 'function'
? createHtmlRender(template)
: template
if (showUp) {
files.unshift('..');
}
// stat all files
stat(path, files, function (err, stats) {
if (err) return next(err);
// combine the stats into the file list
var fileList = files.map(function (file, i) {
return { name: file, stat: stats[i] };
});
// sort file list
fileList.sort(fileSort);
// read stylesheet
fs.readFile(stylesheet, 'utf8', function (err, style) {
if (err) return next(err);
// create locals for rendering
var locals = {
directory: dir,
displayIcons: Boolean(icons),
fileList: fileList,
path: path,
style: style,
viewName: view
};
// render html
render(locals, function (err, body) {
if (err) return next(err);
send(res, 'text/html', body)
});
});
});
};
/**
* Respond with application/json.
*/
serveIndex.json = function _json(req, res, files) {
send(res, 'application/json', JSON.stringify(files))
};
/**
* Respond with text/plain.
*/
serveIndex.plain = function _plain(req, res, files) {
send(res, 'text/plain', (files.join('\n') + '\n'))
};
/**
* Map html `files`, returning an html unordered list.
* @private
*/
function createHtmlFileList(files, dir, useIcons, view) {
var html = '<ul id="files" class="view-' + escapeHtml(view) + '">'
+ (view == 'details' ? (
'<li class="header">'
+ '<span class="name">Name</span>'
+ '<span class="size">Size</span>'
+ '<span class="date">Modified</span>'
+ '</li>') : '');
html += files.map(function (file) {
var classes = [];
var isDir = file.stat && file.stat.isDirectory();
var path = dir.split('/').map(function (c) { return encodeURIComponent(c); });
if (useIcons) {
classes.push('icon');
if (isDir) {
classes.push('icon-directory');
} else {
var ext = extname(file.name);
var icon = iconLookup(file.name);
classes.push('icon');
classes.push('icon-' + ext.substring(1));
if (classes.indexOf(icon.className) === -1) {
classes.push(icon.className);
}
}
}
path.push(encodeURIComponent(file.name));
var date = file.stat && file.name !== '..'
? file.stat.mtime.toLocaleDateString() + ' ' + file.stat.mtime.toLocaleTimeString()
: '';
var size = file.stat && !isDir
? file.stat.size
: '';
return '<li><a href="'
+ escapeHtml(normalizeSlashes(normalize(path.join('/'))))
+ '" class="' + escapeHtml(classes.join(' ')) + '"'
+ ' title="' + escapeHtml(file.name) + '">'
+ '<span class="name">' + escapeHtml(file.name) + '</span>'
+ '<span class="size">' + escapeHtml(size) + '</span>'
+ '<span class="date">' + escapeHtml(date) + '</span>'
+ '</a></li>';
}).join('\n');
html += '</ul>';
return html;
}
/**
* Create function to render html.
*/
function createHtmlRender(template) {
return function render(locals, callback) {
// read template
fs.readFile(template, 'utf8', function (err, str) {
if (err) return callback(err);
var body = str
.replace(/\{style\}/g, locals.style.concat(iconStyle(locals.fileList, locals.displayIcons)))
.replace(/\{files\}/g, createHtmlFileList(locals.fileList, locals.directory, locals.displayIcons, locals.viewName))
.replace(/\{directory\}/g, escapeHtml(locals.directory))
.replace(/\{linked-path\}/g, htmlPath(locals.directory));
callback(null, body);
});
};
}
/**
* Sort function for with directories first.
*/
function fileSort(a, b) {
// sort ".." to the top
if (a.name === '..' || b.name === '..') {
return a.name === b.name ? 0
: a.name === '..' ? -1 : 1;
}
return Number(b.stat && b.stat.isDirectory()) - Number(a.stat && a.stat.isDirectory()) ||
String(a.name).toLocaleLowerCase().localeCompare(String(b.name).toLocaleLowerCase());
}
/**
* Map html `dir`, returning a linked path.
*/
function htmlPath(dir) {
var parts = dir.split('/');
var crumb = new Array(parts.length);
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part) {
parts[i] = encodeURIComponent(part);
crumb[i] = '<a href="' + escapeHtml(parts.slice(0, i + 1).join('/')) + '">' + escapeHtml(part) + '</a>';
}
}
return crumb.join(' / ');
}
/**
* Get the icon data for the file name.
*/
function iconLookup(filename) {
var ext = extname(filename);
// try by extension
if (icons[ext]) {
return {
className: 'icon-' + ext.substring(1),
fileName: icons[ext]
};
}
var mimetype = mime.lookup(ext);
// default if no mime type
if (mimetype === false) {
return {
className: 'icon-default',
fileName: icons.default
};
}
// try by mime type
if (icons[mimetype]) {
return {
className: 'icon-' + mimetype.replace('/', '-'),
fileName: icons[mimetype]
};
}
var suffix = mimetype.split('+')[1];
if (suffix && icons['+' + suffix]) {
return {
className: 'icon-' + suffix,
fileName: icons['+' + suffix]
};
}
var type = mimetype.split('/')[0];
// try by type only
if (icons[type]) {
return {
className: 'icon-' + type,
fileName: icons[type]
};
}
return {
className: 'icon-default',
fileName: icons.default
};
}
/**
* Load icon images, return css string.
*/
function iconStyle(files, useIcons) {
if (!useIcons) return '';
var i;
var list = [];
var rules = {};
var selector;
var selectors = {};
var style = '';
for (i = 0; i < files.length; i++) {
var file = files[i];
var isDir = file.stat && file.stat.isDirectory();
var icon = isDir
? { className: 'icon-directory', fileName: icons.folder }
: iconLookup(file.name);
var iconName = icon.fileName;
selector = '#files .' + icon.className + ' .name';
if (!rules[iconName]) {
rules[iconName] = 'background-image: url(data:image/png;base64,' + load(iconName) + ');'
selectors[iconName] = [];
list.push(iconName);
}
if (selectors[iconName].indexOf(selector) === -1) {
selectors[iconName].push(selector);
}
}
for (i = 0; i < list.length; i++) {
iconName = list[i];
style += selectors[iconName].join(',\n') + ' {\n ' + rules[iconName] + '\n}\n';
}
return style;
}
/**
* Load and cache the given `icon`.
*
* @param {String} icon
* @return {String}
* @api private
*/
function load(icon) {
if (cache[icon]) return cache[icon];
return cache[icon] = fs.readFileSync(__dirname + '/public/icons/' + icon, 'base64');
}
/**
* Normalizes the path separator from system separator
* to URL separator, aka `/`.
*
* @param {String} path
* @return {String}
* @api private
*/
function normalizeSlashes(path) {
return path.split(sep).join('/');
};
/**
* Filter "hidden" `files`, aka files
* beginning with a `.`.
*
* @param {Array} files
* @return {Array}
* @api private
*/
function removeHidden(files) {
return files.filter(function(file){
return '.' != file[0];
});
}
/**
* Send a response.
* @private
*/
function send (res, type, body) {
// security header for content sniffing
res.setHeader('X-Content-Type-Options', 'nosniff')
// standard headers
res.setHeader('Content-Type', type + '; charset=utf-8')
res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8'))
// body
res.end(body, 'utf8')
}
/**
* Stat all files and return array of stat
* in same order.
*/
function stat(dir, files, cb) {
var batch = new Batch();
batch.concurrency(10);
files.forEach(function(file){
batch.push(function(done){
fs.stat(join(dir, file), function(err, stat){
if (err && err.code !== 'ENOENT') return done(err);
// pass ENOENT as null stat, not error
done(null, stat || null);
});
});
});
batch.end(cb);
}
/**
* Icon map.
*/
var icons = {
// base icons
'default': 'page_white.png',
'folder': 'folder.png',
// generic mime type icons
'image': 'image.png',
'text': 'page_white_text.png',
'video': 'film.png',
// generic mime suffix icons
'+json': 'page_white_code.png',
'+xml': 'page_white_code.png',
'+zip': 'box.png',
// specific mime type icons
'application/font-woff': 'font.png',
'application/javascript': 'page_white_code_red.png',
'application/json': 'page_white_code.png',
'application/msword': 'page_white_word.png',
'application/pdf': 'page_white_acrobat.png',
'application/postscript': 'page_white_vector.png',
'application/rtf': 'page_white_word.png',
'application/vnd.ms-excel': 'page_white_excel.png',
'application/vnd.ms-powerpoint': 'page_white_powerpoint.png',
'application/vnd.oasis.opendocument.presentation': 'page_white_powerpoint.png',
'application/vnd.oasis.opendocument.spreadsheet': 'page_white_excel.png',
'application/vnd.oasis.opendocument.text': 'page_white_word.png',
'application/x-7z-compressed': 'box.png',
'application/x-sh': 'application_xp_terminal.png',
'application/x-font-ttf': 'font.png',
'application/x-msaccess': 'page_white_database.png',
'application/x-shockwave-flash': 'page_white_flash.png',
'application/x-sql': 'page_white_database.png',
'application/x-tar': 'box.png',
'application/x-xz': 'box.png',
'application/xml': 'page_white_code.png',
'application/zip': 'box.png',
'image/svg+xml': 'page_white_vector.png',
'text/css': 'page_white_code.png',
'text/html': 'page_white_code.png',
'text/less': 'page_white_code.png',
// other, extension-specific icons
'.accdb': 'page_white_database.png',
'.apk': 'box.png',
'.app': 'application_xp.png',
'.as': 'page_white_actionscript.png',
'.asp': 'page_white_code.png',
'.aspx': 'page_white_code.png',
'.bat': 'application_xp_terminal.png',
'.bz2': 'box.png',
'.c': 'page_white_c.png',
'.cab': 'box.png',
'.cfm': 'page_white_coldfusion.png',
'.clj': 'page_white_code.png',
'.cc': 'page_white_cplusplus.png',
'.cgi': 'application_xp_terminal.png',
'.cpp': 'page_white_cplusplus.png',
'.cs': 'page_white_csharp.png',
'.db': 'page_white_database.png',
'.dbf': 'page_white_database.png',
'.deb': 'box.png',
'.dll': 'page_white_gear.png',
'.dmg': 'drive.png',
'.docx': 'page_white_word.png',
'.erb': 'page_white_ruby.png',
'.exe': 'application_xp.png',
'.fnt': 'font.png',
'.gam': 'controller.png',
'.gz': 'box.png',
'.h': 'page_white_h.png',
'.ini': 'page_white_gear.png',
'.iso': 'cd.png',
'.jar': 'box.png',
'.java': 'page_white_cup.png',
'.jsp': 'page_white_cup.png',
'.lua': 'page_white_code.png',
'.lz': 'box.png',
'.lzma': 'box.png',
'.m': 'page_white_code.png',
'.map': 'map.png',
'.msi': 'box.png',
'.mv4': 'film.png',
'.otf': 'font.png',
'.pdb': 'page_white_database.png',
'.php': 'page_white_php.png',
'.pl': 'page_white_code.png',
'.pkg': 'box.png',
'.pptx': 'page_white_powerpoint.png',
'.psd': 'page_white_picture.png',
'.py': 'page_white_code.png',
'.rar': 'box.png',
'.rb': 'page_white_ruby.png',
'.rm': 'film.png',
'.rom': 'controller.png',
'.rpm': 'box.png',
'.sass': 'page_white_code.png',
'.sav': 'controller.png',
'.scss': 'page_white_code.png',
'.srt': 'page_white_text.png',
'.tbz2': 'box.png',
'.tgz': 'box.png',
'.tlz': 'box.png',
'.vb': 'page_white_code.png',
'.vbs': 'page_white_code.png',
'.xcf': 'page_white_picture.png',
'.xlsx': 'page_white_excel.png',
'.yaws': 'page_white_code.png'
};