Team Ai
Datasetpublic

Brunobkr/llama.cpp_AlgMor24_github

ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.

sourceHugging Faceupdated 2mo agoView on Hugging Face
0likes3.1kdownloads
index.js944 linesDownload Raw Back to commonjs
1"use strict";2Object.defineProperty(exports, "__esModule", { value: true });3exports.jack = exports.Jack = exports.isConfigOption = exports.isConfigOptionOfType = exports.isConfigType = void 0;4const node_util_1 = require("node:util");5const min_1 = require("@isaacs/cliui/min");6const node_path_1 = require("node:path");7const isConfigType = (t) => typeof t === 'string' &&8    (t === 'string' || t === 'number' || t === 'boolean');9exports.isConfigType = isConfigType;10const isValidValue = (v, type, multi) => {11    if (multi) {12        if (!Array.isArray(v))13            return false;14        return !v.some((v) => !isValidValue(v, type, false));15    }16    if (Array.isArray(v))17        return false;18    return typeof v === type;19};20const isValidOption = (v, vo) => !!vo &&21    (Array.isArray(v) ? v.every(x => isValidOption(x, vo)) : vo.includes(v));22/**23 * Determine whether an unknown object is a {@link ConfigOption} based only24 * on its `type` and `multiple` property25 */26const isConfigOptionOfType = (o, type, multi) => !!o &&27    typeof o === 'object' &&28    'type' in o &&29    (0, exports.isConfigType)(o.type) &&30    o.type === type &&31    !!o.multiple === multi;32exports.isConfigOptionOfType = isConfigOptionOfType;33/**34 * Determine whether an unknown object is a {@link ConfigOption} based on35 * it having all valid properties36 */37const isConfigOption = (o, type, multi) => (0, exports.isConfigOptionOfType)(o, type, multi) &&38    undefOrType(o.short, 'string') &&39    undefOrType(o.description, 'string') &&40    undefOrType(o.hint, 'string') &&41    undefOrType(o.validate, 'function') &&42    (o.type === 'boolean' ?43        o.validOptions === undefined44        : undefOrTypeArray(o.validOptions, o.type)) &&45    (o.default === undefined || isValidValue(o.default, type, multi));46exports.isConfigOption = isConfigOption;47const isHeading = (r) => r.type === 'heading';48const isDescription = (r) => r.type === 'description';49const width = Math.min(process?.stdout?.columns ?? 80, 80);50// indentation spaces from heading level51const indent = (n) => (n - 1) * 2;52const toEnvKey = (pref, key) => [pref, key.replace(/[^a-zA-Z0-9]+/g, ' ')]53    .join(' ')54    .trim()55    .toUpperCase()56    .replace(/ /g, '_');57const toEnvVal = (value, delim = '\n') => {58    const str = typeof value === 'string' ? value59        : typeof value === 'boolean' ?60            value ? '1'61                : '0'62            : typeof value === 'number' ? String(value)63                : Array.isArray(value) ?64                    value.map((v) => toEnvVal(v)).join(delim)65                    : /* c8 ignore start */ undefined;66    if (typeof str !== 'string') {67        throw new Error(`could not serialize value to environment: ${JSON.stringify(value)}`, { cause: { code: 'JACKSPEAK' } });68    }69    /* c8 ignore stop */70    return str;71};72const fromEnvVal = (env, type, multiple, delim = '\n') => (multiple ?73    env ? env.split(delim).map(v => fromEnvVal(v, type, false))74        : []75    : type === 'string' ? env76        : type === 'boolean' ? env === '1'77            : +env.trim());78const undefOrType = (v, t) => v === undefined || typeof v === t;79const undefOrTypeArray = (v, t) => v === undefined || (Array.isArray(v) && v.every(x => typeof x === t));80// print the value type, for error message reporting81const valueType = (v) => typeof v === 'string' ? 'string'82    : typeof v === 'boolean' ? 'boolean'83        : typeof v === 'number' ? 'number'84            : Array.isArray(v) ?85                `${joinTypes([...new Set(v.map(v => valueType(v)))])}[]`86                : `${v.type}${v.multiple ? '[]' : ''}`;87const joinTypes = (types) => types.length === 1 && typeof types[0] === 'string' ?88    types[0]89    : `(${types.join('|')})`;90const validateFieldMeta = (field, fieldMeta) => {91    if (fieldMeta) {92        if (field.type !== undefined && field.type !== fieldMeta.type) {93            throw new TypeError(`invalid type`, {94                cause: {95                    found: field.type,96                    wanted: [fieldMeta.type, undefined],97                },98            });99        }100        if (field.multiple !== undefined &&101            !!field.multiple !== fieldMeta.multiple) {102            throw new TypeError(`invalid multiple`, {103                cause: {104                    found: field.multiple,105                    wanted: [fieldMeta.multiple, undefined],106                },107            });108        }109        return fieldMeta;110    }111    if (!(0, exports.isConfigType)(field.type)) {112        throw new TypeError(`invalid type`, {113            cause: {114                found: field.type,115                wanted: ['string', 'number', 'boolean'],116            },117        });118    }119    return {120        type: field.type,121        multiple: !!field.multiple,122    };123};124const validateField = (o, type, multiple) => {125    const validateValidOptions = (def, validOptions) => {126        if (!undefOrTypeArray(validOptions, type)) {127            throw new TypeError('invalid validOptions', {128                cause: {129                    found: validOptions,130                    wanted: valueType({ type, multiple: true }),131                },132            });133        }134        if (def !== undefined && validOptions !== undefined) {135            const valid = Array.isArray(def) ?136                def.every(v => validOptions.includes(v))137                : validOptions.includes(def);138            if (!valid) {139                throw new TypeError('invalid default value not in validOptions', {140                    cause: {141                        found: def,142                        wanted: validOptions,143                    },144                });145            }146        }147    };148    if (o.default !== undefined &&149        !isValidValue(o.default, type, multiple)) {150        throw new TypeError('invalid default value', {151            cause: {152                found: o.default,153                wanted: valueType({ type, multiple }),154            },155        });156    }157    if ((0, exports.isConfigOptionOfType)(o, 'number', false) ||158        (0, exports.isConfigOptionOfType)(o, 'number', true)) {159        validateValidOptions(o.default, o.validOptions);160    }161    else if ((0, exports.isConfigOptionOfType)(o, 'string', false) ||162        (0, exports.isConfigOptionOfType)(o, 'string', true)) {163        validateValidOptions(o.default, o.validOptions);164    }165    else if ((0, exports.isConfigOptionOfType)(o, 'boolean', false) ||166        (0, exports.isConfigOptionOfType)(o, 'boolean', true)) {167        if (o.hint !== undefined) {168            throw new TypeError('cannot provide hint for flag');169        }170        if (o.validOptions !== undefined) {171            throw new TypeError('cannot provide validOptions for flag');172        }173    }174    return o;175};176const toParseArgsOptionsConfig = (options) => {177    return Object.entries(options).reduce((acc, [longOption, o]) => {178        const p = {179            type: 'string',180            multiple: !!o.multiple,181            ...(typeof o.short === 'string' ? { short: o.short } : undefined),182        };183        const setNoBool = () => {184            if (!longOption.startsWith('no-') && !options[`no-${longOption}`]) {185                acc[`no-${longOption}`] = {186                    type: 'boolean',187                    multiple: !!o.multiple,188                };189            }190        };191        const setDefault = (def, fn) => {192            if (def !== undefined) {193                p.default = fn(def);194            }195        };196        if ((0, exports.isConfigOption)(o, 'number', false)) {197            setDefault(o.default, String);198        }199        else if ((0, exports.isConfigOption)(o, 'number', true)) {200            setDefault(o.default, d => d.map(v => String(v)));201        }202        else if ((0, exports.isConfigOption)(o, 'string', false) ||203            (0, exports.isConfigOption)(o, 'string', true)) {204            setDefault(o.default, v => v);205        }206        else if ((0, exports.isConfigOption)(o, 'boolean', false) ||207            (0, exports.isConfigOption)(o, 'boolean', true)) {208            p.type = 'boolean';209            setDefault(o.default, v => v);210            setNoBool();211        }212        acc[longOption] = p;213        return acc;214    }, {});215};216/**217 * Class returned by the {@link jack} function and all configuration218 * definition methods.  This is what gets chained together.219 */220class Jack {221    #configSet;222    #shorts;223    #options;224    #fields = [];225    #env;226    #envPrefix;227    #allowPositionals;228    #usage;229    #usageMarkdown;230    constructor(options = {}) {231        this.#options = options;232        this.#allowPositionals = options.allowPositionals !== false;233        this.#env =234            this.#options.env === undefined ? process.env : this.#options.env;235        this.#envPrefix = options.envPrefix;236        // We need to fib a little, because it's always the same object, but it237        // starts out as having an empty config set.  Then each method that adds238        // fields returns `this as Jack<C & { ...newConfigs }>`239        this.#configSet = Object.create(null);240        this.#shorts = Object.create(null);241    }242    /**243     * Resulting definitions, suitable to be passed to Node's `util.parseArgs`,244     * but also including `description` and `short` fields, if set.245     */246    get definitions() {247        return this.#configSet;248    }249    /** map of `{ <short>: <long> }` strings for each short name defined */250    get shorts() {251        return this.#shorts;252    }253    /**254     * options passed to the {@link Jack} constructor255     */256    get jackOptions() {257        return this.#options;258    }259    /**260     * the data used to generate {@link Jack#usage} and261     * {@link Jack#usageMarkdown} content.262     */263    get usageFields() {264        return this.#fields;265    }266    /**267     * Set the default value (which will still be overridden by env or cli)268     * as if from a parsed config file. The optional `source` param, if269     * provided, will be included in error messages if a value is invalid or270     * unknown.271     */272    setConfigValues(values, source = '') {273        try {274            this.validate(values);275        }276        catch (er) {277            if (source && er instanceof Error) {278                /* c8 ignore next */279                const cause = typeof er.cause === 'object' ? er.cause : {};280                er.cause = { ...cause, path: source };281                Error.captureStackTrace(er, this.setConfigValues);282            }283            throw er;284        }285        for (const [field, value] of Object.entries(values)) {286            const my = this.#configSet[field];287            // already validated, just for TS's benefit288            /* c8 ignore start */289            if (!my) {290                throw new Error('unexpected field in config set: ' + field, {291                    cause: {292                        code: 'JACKSPEAK',293                        found: field,294                    },295                });296            }297            /* c8 ignore stop */298            my.default = value;299        }300        return this;301    }302    /**303     * Parse a string of arguments, and return the resulting304     * `{ values, positionals }` object.305     *306     * If an {@link JackOptions#envPrefix} is set, then it will read default307     * values from the environment, and write the resulting values back308     * to the environment as well.309     *310     * Environment values always take precedence over any other value, except311     * an explicit CLI setting.312     */313    parse(args = process.argv) {314        this.loadEnvDefaults();315        const p = this.parseRaw(args);316        this.applyDefaults(p);317        this.writeEnv(p);318        return p;319    }320    loadEnvDefaults() {321        if (this.#envPrefix) {322            for (const [field, my] of Object.entries(this.#configSet)) {323                const ek = toEnvKey(this.#envPrefix, field);324                const env = this.#env[ek];325                if (env !== undefined) {326                    my.default = fromEnvVal(env, my.type, !!my.multiple, my.delim);327                }328            }329        }330    }331    applyDefaults(p) {332        for (const [field, c] of Object.entries(this.#configSet)) {333            if (c.default !== undefined && !(field in p.values)) {334                //@ts-ignore335                p.values[field] = c.default;336            }337        }338    }339    /**340     * Only parse the command line arguments passed in.341     * Does not strip off the `node script.js` bits, so it must be just the342     * arguments you wish to have parsed.343     * Does not read from or write to the environment, or set defaults.344     */345    parseRaw(args) {346        if (args === process.argv) {347            args = args.slice(process._eval !== undefined ? 1 : 2);348        }349        const result = (0, node_util_1.parseArgs)({350            args,351            options: toParseArgsOptionsConfig(this.#configSet),352            // always strict, but using our own logic353            strict: false,354            allowPositionals: this.#allowPositionals,355            tokens: true,356        });357        const p = {358            values: {},359            positionals: [],360        };361        for (const token of result.tokens) {362            if (token.kind === 'positional') {363                p.positionals.push(token.value);364                if (this.#options.stopAtPositional ||365                    this.#options.stopAtPositionalTest?.(token.value)) {366                    p.positionals.push(...args.slice(token.index + 1));367                    break;368                }369            }370            else if (token.kind === 'option') {371                let value = undefined;372                if (token.name.startsWith('no-')) {373                    const my = this.#configSet[token.name];374                    const pname = token.name.substring('no-'.length);375                    const pos = this.#configSet[pname];376                    if (pos &&377                        pos.type === 'boolean' &&378                        (!my ||379                            (my.type === 'boolean' && !!my.multiple === !!pos.multiple))) {380                        value = false;381                        token.name = pname;382                    }383                }384                const my = this.#configSet[token.name];385                if (!my) {386                    throw new Error(`Unknown option '${token.rawName}'. ` +387                        `To specify a positional argument starting with a '-', ` +388                        `place it at the end of the command after '--', as in ` +389                        `'-- ${token.rawName}'`, {390                        cause: {391                            code: 'JACKSPEAK',392                            found: token.rawName + (token.value ? `=${token.value}` : ''),393                        },394                    });395                }396                if (value === undefined) {397                    if (token.value === undefined) {398                        if (my.type !== 'boolean') {399                            throw new Error(`No value provided for ${token.rawName}, expected ${my.type}`, {400                                cause: {401                                    code: 'JACKSPEAK',402                                    name: token.rawName,403                                    wanted: valueType(my),404                                },405                            });406                        }407                        value = true;408                    }409                    else {410                        if (my.type === 'boolean') {411                            throw new Error(`Flag ${token.rawName} does not take a value, received '${token.value}'`, { cause: { code: 'JACKSPEAK', found: token } });412                        }413                        if (my.type === 'string') {414                            value = token.value;415                        }416                        else {417                            value = +token.value;418                            if (value !== value) {419                                throw new Error(`Invalid value '${token.value}' provided for ` +420                                    `'${token.rawName}' option, expected number`, {421                                    cause: {422                                        code: 'JACKSPEAK',423                                        name: token.rawName,424                                        found: token.value,425                                        wanted: 'number',426                                    },427                                });428                            }429                        }430                    }431                }432                if (my.multiple) {433                    const pv = p.values;434                    const tn = pv[token.name] ?? [];435                    pv[token.name] = tn;436                    tn.push(value);437                }438                else {439                    const pv = p.values;440                    pv[token.name] = value;441                }442            }443        }444        for (const [field, value] of Object.entries(p.values)) {445            const valid = this.#configSet[field]?.validate;446            const validOptions = this.#configSet[field]?.validOptions;447            const cause = validOptions && !isValidOption(value, validOptions) ?448                { name: field, found: value, validOptions }449                : valid && !valid(value) ? { name: field, found: value }450                    : undefined;451            if (cause) {452                throw new Error(`Invalid value provided for --${field}: ${JSON.stringify(value)}`, { cause: { ...cause, code: 'JACKSPEAK' } });453            }454        }455        return p;456    }457    /**458     * do not set fields as 'no-foo' if 'foo' exists and both are bools459     * just set foo.460     */461    #noNoFields(f, val, s = f) {462        if (!f.startsWith('no-') || typeof val !== 'boolean')463            return;464        const yes = f.substring('no-'.length);465        // recurse so we get the core config key we care about.466        this.#noNoFields(yes, val, s);467        if (this.#configSet[yes]?.type === 'boolean') {468            throw new Error(`do not set '${s}', instead set '${yes}' as desired.`, { cause: { code: 'JACKSPEAK', found: s, wanted: yes } });469        }470    }471    /**472     * Validate that any arbitrary object is a valid configuration `values`473     * object.  Useful when loading config files or other sources.474     */475    validate(o) {476        if (!o || typeof o !== 'object') {477            throw new Error('Invalid config: not an object', {478                cause: { code: 'JACKSPEAK', found: o },479            });480        }481        const opts = o;482        for (const field in o) {483            const value = opts[field];484            /* c8 ignore next - for TS */485            if (value === undefined)486                continue;487            this.#noNoFields(field, value);488            const config = this.#configSet[field];489            if (!config) {490                throw new Error(`Unknown config option: ${field}`, {491                    cause: { code: 'JACKSPEAK', found: field },492                });493            }494            if (!isValidValue(value, config.type, !!config.multiple)) {495                throw new Error(`Invalid value ${valueType(value)} for ${field}, expected ${valueType(config)}`, {496                    cause: {497                        code: 'JACKSPEAK',498                        name: field,499                        found: value,500                        wanted: valueType(config),501                    },502                });503            }504            const cause = config.validOptions && !isValidOption(value, config.validOptions) ?505                { name: field, found: value, validOptions: config.validOptions }506                : config.validate && !config.validate(value) ?507                    { name: field, found: value }508                    : undefined;509            if (cause) {510                throw new Error(`Invalid config value for ${field}: ${JSON.stringify(value)}`, {511                    cause: { ...cause, code: 'JACKSPEAK' },512                });513            }514        }515    }516    writeEnv(p) {517        if (!this.#env || !this.#envPrefix)518            return;519        for (const [field, value] of Object.entries(p.values)) {520            const my = this.#configSet[field];521            this.#env[toEnvKey(this.#envPrefix, field)] = toEnvVal(value, my?.delim);522        }523    }524    /**525     * Add a heading to the usage output banner526     */527    heading(text, level, { pre = false } = {}) {528        if (level === undefined) {529            level = this.#fields.some(r => isHeading(r)) ? 2 : 1;530        }531        this.#fields.push({ type: 'heading', text, level, pre });532        return this;533    }534    /**535     * Add a long-form description to the usage output at this position.536     */537    description(text, { pre } = {}) {538        this.#fields.push({ type: 'description', text, pre });539        return this;540    }541    /**542     * Add one or more number fields.543     */544    num(fields) {545        return this.#addFieldsWith(fields, 'number', false);546    }547    /**548     * Add one or more multiple number fields.549     */550    numList(fields) {551        return this.#addFieldsWith(fields, 'number', true);552    }553    /**554     * Add one or more string option fields.555     */556    opt(fields) {557        return this.#addFieldsWith(fields, 'string', false);558    }559    /**560     * Add one or more multiple string option fields.561     */562    optList(fields) {563        return this.#addFieldsWith(fields, 'string', true);564    }565    /**566     * Add one or more flag fields.567     */568    flag(fields) {569        return this.#addFieldsWith(fields, 'boolean', false);570    }571    /**572     * Add one or more multiple flag fields.573     */574    flagList(fields) {575        return this.#addFieldsWith(fields, 'boolean', true);576    }577    /**578     * Generic field definition method. Similar to flag/flagList/number/etc,579     * but you must specify the `type` (and optionally `multiple` and `delim`)580     * fields on each one, or Jack won't know how to define them.581     */582    addFields(fields) {583        return this.#addFields(this, fields);584    }585    #addFieldsWith(fields, type, multiple) {586        return this.#addFields(this, fields, {587            type,588            multiple,589        });590    }591    #addFields(next, fields, opt) {592        Object.assign(next.#configSet, Object.fromEntries(Object.entries(fields).map(([name, field]) => {593            this.#validateName(name, field);594            const { type, multiple } = validateFieldMeta(field, opt);595            const value = { ...field, type, multiple };596            validateField(value, type, multiple);597            next.#fields.push({ type: 'config', name, value });598            return [name, value];599        })));600        return next;601    }602    #validateName(name, field) {603        if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(name)) {604            throw new TypeError(`Invalid option name: ${name}, ` +605                `must be '-' delimited ASCII alphanumeric`);606        }607        if (this.#configSet[name]) {608            throw new TypeError(`Cannot redefine option ${name}`);609        }610        if (this.#shorts[name]) {611            throw new TypeError(`Cannot redefine option ${name}, already ` +612                `in use for ${this.#shorts[name]}`);613        }614        if (field.short) {615            if (!/^[a-zA-Z0-9]$/.test(field.short)) {616                throw new TypeError(`Invalid ${name} short option: ${field.short}, ` +617                    'must be 1 ASCII alphanumeric character');618            }619            if (this.#shorts[field.short]) {620                throw new TypeError(`Invalid ${name} short option: ${field.short}, ` +621                    `already in use for ${this.#shorts[field.short]}`);622            }623            this.#shorts[field.short] = name;624            this.#shorts[name] = name;625        }626    }627    /**628     * Return the usage banner for the given configuration629     */630    usage() {631        if (this.#usage)632            return this.#usage;633        let headingLevel = 1;634        //@ts-ignore635        const ui = (0, min_1.cliui)({ width });636        const first = this.#fields[0];637        let start = first?.type === 'heading' ? 1 : 0;638        if (first?.type === 'heading') {639            ui.div({640                padding: [0, 0, 0, 0],641                text: normalize(first.text),642            });643        }644        ui.div({ padding: [0, 0, 0, 0], text: 'Usage:' });645        if (this.#options.usage) {646            ui.div({647                text: this.#options.usage,648                padding: [0, 0, 0, 2],649            });650        }651        else {652            const cmd = (0, node_path_1.basename)(String(process.argv[1]));653            const shortFlags = [];654            const shorts = [];655            const flags = [];656            const opts = [];657            for (const [field, config] of Object.entries(this.#configSet)) {658                if (config.short) {659                    if (config.type === 'boolean')660                        shortFlags.push(config.short);661                    else662                        shorts.push([config.short, config.hint || field]);663                }664                else {665                    if (config.type === 'boolean')666                        flags.push(field);667                    else668                        opts.push([field, config.hint || field]);669                }670            }671            const sf = shortFlags.length ? ' -' + shortFlags.join('') : '';672            const so = shorts.map(([k, v]) => ` --${k}=<${v}>`).join('');673            const lf = flags.map(k => ` --${k}`).join('');674            const lo = opts.map(([k, v]) => ` --${k}=<${v}>`).join('');675            const usage = `${cmd}${sf}${so}${lf}${lo}`.trim();676            ui.div({677                text: usage,678                padding: [0, 0, 0, 2],679            });680        }681        ui.div({ padding: [0, 0, 0, 0], text: '' });682        const maybeDesc = this.#fields[start];683        if (maybeDesc && isDescription(maybeDesc)) {684            const print = normalize(maybeDesc.text, maybeDesc.pre);685            start++;686            ui.div({ padding: [0, 0, 0, 0], text: print });687            ui.div({ padding: [0, 0, 0, 0], text: '' });688        }689        const { rows, maxWidth } = this.#usageRows(start);690        // every heading/description after the first gets indented by 2691        // extra spaces.692        for (const row of rows) {693            if (row.left) {694                // If the row is too long, don't wrap it695                // Bump the right-hand side down a line to make room696                const configIndent = indent(Math.max(headingLevel, 2));697                if (row.left.length > maxWidth - 3) {698                    ui.div({ text: row.left, padding: [0, 0, 0, configIndent] });699                    ui.div({ text: row.text, padding: [0, 0, 0, maxWidth] });700                }701                else {702                    ui.div({703                        text: row.left,704                        padding: [0, 1, 0, configIndent],705                        width: maxWidth,706                    }, { padding: [0, 0, 0, 0], text: row.text });707                }708                if (row.skipLine) {709                    ui.div({ padding: [0, 0, 0, 0], text: '' });710                }711            }712            else {713                if (isHeading(row)) {714                    const { level } = row;715                    headingLevel = level;716                    // only h1 and h2 have bottom padding717                    // h3-h6 do not718                    const b = level <= 2 ? 1 : 0;719                    ui.div({ ...row, padding: [0, 0, b, indent(level)] });720                }721                else {722                    ui.div({ ...row, padding: [0, 0, 1, indent(headingLevel + 1)] });723                }724            }725        }726        return (this.#usage = ui.toString());727    }728    /**729     * Return the usage banner markdown for the given configuration730     */731    usageMarkdown() {732        if (this.#usageMarkdown)733            return this.#usageMarkdown;734        const out = [];735        let headingLevel = 1;736        const first = this.#fields[0];737        let start = first?.type === 'heading' ? 1 : 0;738        if (first?.type === 'heading') {739            out.push(`# ${normalizeOneLine(first.text)}`);740        }741        out.push('Usage:');742        if (this.#options.usage) {743            out.push(normalizeMarkdown(this.#options.usage, true));744        }745        else {746            const cmd = (0, node_path_1.basename)(String(process.argv[1]));747            const shortFlags = [];748            const shorts = [];749            const flags = [];750            const opts = [];751            for (const [field, config] of Object.entries(this.#configSet)) {752                if (config.short) {753                    if (config.type === 'boolean')754                        shortFlags.push(config.short);755                    else756                        shorts.push([config.short, config.hint || field]);757                }758                else {759                    if (config.type === 'boolean')760                        flags.push(field);761                    else762                        opts.push([field, config.hint || field]);763                }764            }765            const sf = shortFlags.length ? ' -' + shortFlags.join('') : '';766            const so = shorts.map(([k, v]) => ` --${k}=<${v}>`).join('');767            const lf = flags.map(k => ` --${k}`).join('');768            const lo = opts.map(([k, v]) => ` --${k}=<${v}>`).join('');769            const usage = `${cmd}${sf}${so}${lf}${lo}`.trim();770            out.push(normalizeMarkdown(usage, true));771        }772        const maybeDesc = this.#fields[start];773        if (maybeDesc && isDescription(maybeDesc)) {774            out.push(normalizeMarkdown(maybeDesc.text, maybeDesc.pre));775            start++;776        }777        const { rows } = this.#usageRows(start);778        // heading level in markdown is number of # ahead of text779        for (const row of rows) {780            if (row.left) {781                out.push('#'.repeat(headingLevel + 1) +782                    ' ' +783                    normalizeOneLine(row.left, true));784                if (row.text)785                    out.push(normalizeMarkdown(row.text));786            }787            else if (isHeading(row)) {788                const { level } = row;789                headingLevel = level;790                out.push(`${'#'.repeat(headingLevel)} ${normalizeOneLine(row.text, row.pre)}`);791            }792            else {793                out.push(normalizeMarkdown(row.text, !!row.pre));794            }795        }796        return (this.#usageMarkdown = out.join('\n\n') + '\n');797    }798    #usageRows(start) {799        // turn each config type into a row, and figure out the width of the800        // left hand indentation for the option descriptions.801        const maxMax = Math.max(12, Math.min(26, Math.floor(width / 3)));802        let maxWidth = 8;803        let prev = undefined;804        const rows = [];805        for (const field of this.#fields.slice(start)) {806            if (field.type !== 'config') {807                if (prev?.type === 'config')808                    prev.skipLine = true;809                prev = undefined;810                field.text = normalize(field.text, !!field.pre);811                rows.push(field);812                continue;813            }814            const { value } = field;815            const desc = value.description || '';816            const mult = value.multiple ? 'Can be set multiple times' : '';817            const opts = value.validOptions?.length ?818                'Valid options: ' +819                    value.validOptions.map(v => JSON.stringify(v)).join(', ')820                : '';821            const dmDelim = desc.includes('\n') ? '\n\n' : '\n';822            const extra = [opts, mult].join(dmDelim).trim();823            const text = (normalize(desc) + dmDelim + extra).trim();824            const hint = value.hint ||825                (value.type === 'number' ? 'n'826                    : value.type === 'string' ? field.name827                        : undefined);828            const short = !value.short ? ''829                : value.type === 'boolean' ? `-${value.short} `830                    : `-${value.short}<${hint}> `;831            const left = value.type === 'boolean' ?832                `${short}--${field.name}`833                : `${short}--${field.name}=<${hint}>`;834            const row = { text, left, type: 'config' };835            if (text.length > width - maxMax) {836                row.skipLine = true;837            }838            if (prev && left.length > maxMax)839                prev.skipLine = true;840            prev = row;841            const len = left.length + 4;842            if (len > maxWidth && len < maxMax) {843                maxWidth = len;844            }845            rows.push(row);846        }847        return { rows, maxWidth };848    }849    /**850     * Return the configuration options as a plain object851     */852    toJSON() {853        return Object.fromEntries(Object.entries(this.#configSet).map(([field, def]) => [854            field,855            {856                type: def.type,857                ...(def.multiple ? { multiple: true } : {}),858                ...(def.delim ? { delim: def.delim } : {}),859                ...(def.short ? { short: def.short } : {}),860                ...(def.description ?861                    { description: normalize(def.description) }862                    : {}),863                ...(def.validate ? { validate: def.validate } : {}),864                ...(def.validOptions ? { validOptions: def.validOptions } : {}),865                ...(def.default !== undefined ? { default: def.default } : {}),866                ...(def.hint ? { hint: def.hint } : {}),867            },868        ]));869    }870    /**871     * Custom printer for `util.inspect`872     */873    [node_util_1.inspect.custom](_, options) {874        return `Jack ${(0, node_util_1.inspect)(this.toJSON(), options)}`;875    }876}877exports.Jack = Jack;878/**879 * Main entry point. Create and return a {@link Jack} object.880 */881const jack = (options = {}) => new Jack(options);882exports.jack = jack;883// Unwrap and un-indent, so we can wrap description884// strings however makes them look nice in the code.885const normalize = (s, pre = false) => {886    if (pre)887        // prepend a ZWSP to each line so cliui doesn't strip it.888        return s889            .split('\n')890            .map(l => `\u200b${l}`)891            .join('\n');892    return s893        .split(/^\s*```\s*$/gm)894        .map((s, i) => {895        if (i % 2 === 1) {896            if (!s.trim()) {897                return `\`\`\`\n\`\`\`\n`;898            }899            // outdent the ``` blocks, but preserve whitespace otherwise.900            const split = s.split('\n');901            // throw out the \n at the start and end902            split.pop();903            split.shift();904            const si = split.reduce((shortest, l) => {905                /* c8 ignore next */906                const ind = l.match(/^\s*/)?.[0] ?? '';907                if (ind.length)908                    return Math.min(ind.length, shortest);909                else910                    return shortest;911            }, Infinity);912            /* c8 ignore next */913            const i = isFinite(si) ? si : 0;914            return ('\n```\n' +915                split.map(s => `\u200b${s.substring(i)}`).join('\n') +916                '\n```\n');917        }918        return (s919            // remove single line breaks, except for lists920            .replace(/([^\n])\n[ \t]*([^\n])/g, (_, $1, $2) => !/^[-*]/.test($2) ? `${$1} ${$2}` : `${$1}\n${$2}`)921            // normalize mid-line whitespace922            .replace(/([^\n])[ \t]+([^\n])/g, '$1 $2')923            // two line breaks are enough924            .replace(/\n{3,}/g, '\n\n')925            // remove any spaces at the start of a line926            .replace(/\n[ \t]+/g, '\n')927            .trim());928    })929        .join('\n');930};931// normalize for markdown printing, remove leading spaces on lines932const normalizeMarkdown = (s, pre = false) => {933    const n = normalize(s, pre).replace(/\\/g, '\\\\');934    return pre ?935        `\`\`\`\n${n.replace(/\u200b/g, '')}\n\`\`\``936        : n.replace(/\n +/g, '\n').trim();937};938const normalizeOneLine = (s, pre = false) => {939    const n = normalize(s, pre)940        .replace(/[\s\u200b]+/g, ' ')941        .trim();942    return pre ? `\`${n}\`` : n;943};944//# sourceMappingURL=index.js.map
Brunobkr/llama.cpp_AlgMor24_github · Team Ai