Self-hosted audiobook and podcast server
This report summarizes scanner evidence for advplyr/audiobookshelf, a JavaScript project with 14,868 GitHub stars. SynthScan examined 218,902 lines of code across 819 source files, recording 140 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 0.9 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 84 finding(s).
Are imports declared and package/API names verified? 56 finding(s).
Are wrappers, guards, and repeated structures necessary? 16 finding(s).
Which changes need focused human review? 140 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 140 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | test/server/utils/ffmpegHelpers.test.js | 15 | artist: 'John Doe', | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 24 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe']) | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 29 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe']) | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 34 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe', 'John Doe']) | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 34 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe', 'John Doe']) | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 39 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe']) | CODE |
| LOW⚡ | test/server/utils/parsers/parseNameString.test.js | 44 | expect(result.names).to.deep.equal(['John Smith', 'Jane Doe']) | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 405 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 407 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 416 | const bookResults = [{ duration: 21, title: 'The Great Novel', author: 'John Doe' }] // 21 min, diff = 11 min | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 418 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 427 | const bookResults = [{ duration: 16, title: 'The Great Novel', author: 'John Doe' }] // 16 min, diff = 6 min | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 429 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 438 | const bookResults = [{ duration: 14, title: 'The Great Novel', author: 'John Doe' }] // 14 min, diff = 4 min | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 440 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 449 | const bookResults = [{ duration: 11, title: 'The Great Novel', author: 'John Doe' }] // 11 min, diff = 1 min | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 451 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 460 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 462 | const results = await bookFinder.search({ media: {} }, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 469 | const bookResults = [{ title: 'The Great Novel', author: 'John Doe' }] // No duration in book | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 471 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 478 | const bookResults = [{ duration: 10, title: 'Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 484 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'Novel Ex', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 508 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 515 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 524 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 533 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 542 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 554 | const bookResults = [{ duration: 10, title: 'The Great Novel', subtitle: 'A Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 556 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel: A Novel', 'John | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 561 | const bookResults = [{ duration: 10, title: 'The Great Novel', subtitle: 'A Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 563 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 569 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 572 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel - A Novel', 'Jo | CODE |
| LOW⚡ | test/server/finders/BookFinder.test.js | 577 | const bookResults = [{ duration: 10, title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW | test/server/finders/BookFinder.test.js | 589 | const bookResults = [{ title: 'The Great Novel', author: 'John Doe' }] | CODE |
| LOW | test/server/finders/BookFinder.test.js | 591 | const results = await bookFinder.search(libraryItemPerfectDuration, provider, 'The Great Novel', 'John Doe') | CODE |
| LOW | client/cypress/tests/components/cards/AuthorCard.cy.js | 10 | name: 'John Doe', | CODE |
| LOW | client/cypress/tests/components/cards/AuthorCard.cy.js | 79 | .and('have.text', 'John Doe') | CODE |
| LOW | client/cypress/tests/components/cards/AuthorCard.cy.js | 137 | $post: cy.stub().resolves({ updated: false, author: { name: 'John Doe' } }) | CODE |
| LOW | client/cypress/tests/components/cards/AuthorCard.cy.js | 159 | $post: cy.stub().resolves({ updated: true, author: { name: 'John Doe' } }) | CODE |
| LOW | client/cypress/tests/components/cards/AuthorCard.cy.js | 181 | $post: cy.stub().resolves({ updated: true, author: { name: 'John Doe', imagePath: 'path/to/image' } }) | CODE |
| LOW | …ient/cypress/tests/components/cards/NarratorCard.cy.js | 5 | name: 'John Doe', | CODE |
| LOW | …ient/cypress/tests/components/cards/NarratorCard.cy.js | 36 | cy.get('&name').should('have.text', 'John Doe') | CODE |
| LOW | …ient/cypress/tests/components/cards/NarratorCard.cy.js | 47 | let propsData = { narrator: { name: 'John Doe', numBooks: 1 }, width: 200, height: 150 } | CODE |
| LOW⚡ | client/cypress/tests/components/cards/ItemSlider.cy.js | 8 | { name: 'John Doe', numBooks: 5 }, | CODE |
| LOW⚡ | client/cypress/tests/components/cards/ItemSlider.cy.js | 9 | { name: 'Jane Doe', numBooks: 3 }, | CODE |
| LOW⚡ | client/cypress/tests/components/cards/ItemSlider.cy.js | 14 | { id: 1, name: 'John Doe', numBooks: 5 }, | CODE |
| LOW⚡ | client/cypress/tests/components/cards/ItemSlider.cy.js | 15 | { id: 2, name: 'Jane Doe', numBooks: 3 }, | CODE |
| LOW | client/components/ui/TextInput.vue | 3 | <input :id="inputId" :name="inputName" ref="input" v-model="inputValue" :type="actualType" :step="step" :min="min" : | CODE |
| LOW | client/components/ui/TextareaInput.vue | 2 | <textarea ref="input" v-model="inputValue" :rows="rows" :readonly="readonly" :disabled="disabled" :placeholder="placeh | CODE |
| LOW | client/components/ui/EditableText.vue | 2 | <input ref="input" v-model="inputValue" :type="type" :readonly="readonly" :disabled="disabled" :placeholder="placehold | CODE |
| LOW | client/components/ui/VueTrix.vue | 34 | <trix-editor :toolbar="toolbarId" :contenteditable="!disabledEditor" :class="['trix-content']" ref="trix" :input="co | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | docker-compose.yml | 1 | ### EXAMPLE DOCKER COMPOSE ### | COMMENT |
| LOW | docker-compose.yml | 21 | # you are running ABS on | COMMENT |
| LOW | server/providers/FantLab.js | 1 | const axios = require('axios') | COMMENT |
| LOW | server/libs/async/index.js | 1 | // | COMMENT |
| LOW | server/libs/umzug/storage/json.js | 61 | //# sourceMappingURL=json.js.map | COMMENT |
| LOW | …ver/libs/archiver/archiverUtils/stringDecoder/index.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | server/libs/archiver/archiverUtils/minimatch/index.js | 101 | // a{b,c}d -> abd acd | COMMENT |
| LOW | server/libs/archiver/archiverUtils/minimatch/index.js | 281 | if (p === false) return false | COMMENT |
| LOW | server/libs/archiver/archiverUtils/minimatch/index.js | 301 | // - matchOne(b/x/y/z/c, b/**/c) | COMMENT |
| LOW | server/libs/archiver/archiverUtils/minimatch/index.js | 381 | // If the file ends in /, then it can only match a | COMMENT |
| LOW | server/libs/archiver/archiverUtils/minimatch/index.js | 601 | // a right bracket shall lose its special | COMMENT |
| LOW | …r/libs/archiver/archiverUtils/readableStream/stream.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …erUtils/readableStream/internal/streams/passthrough.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 401 | // 2. If that resulting state will trigger a _read, then call _read. | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 541 | // it's in progress. | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 561 | // - No data in the buffer, and the stream is in flowing mode. In this mode | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/writable.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …iverUtils/readableStream/internal/streams/transform.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …iverUtils/readableStream/internal/streams/transform.js | 21 | // a transform stream is a readable/writable stream where you do | COMMENT |
| LOW | …iverUtils/readableStream/internal/streams/transform.js | 41 | // _read(n) is called, it transforms the queued up data, calling the | COMMENT |
| LOW | …rchiverUtils/readableStream/internal/streams/duplex.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | server/libs/archiver/archiverUtils/glob/index.js | 1 | // Approach: | COMMENT |
| LOW | server/libs/archiver/archiverUtils/glob/index.js | 21 | // // by pruning it out, and testing the resulting pattern | COMMENT |
| LOW | server/libs/archiver/archiverUtils/fsRealpath/old.js | 1 | /* istanbul ignore file - tested in node */ | COMMENT |
| LOW | …/lazystream/readable-stream/lib/_stream_passthrough.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …ls/lazystream/readable-stream/lib/_stream_transform.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …ls/lazystream/readable-stream/lib/_stream_transform.js | 21 | COMMENT | |
| LOW | …ls/lazystream/readable-stream/lib/_stream_transform.js | 41 | // In a transform stream, the written data is placed in a buffer. When | COMMENT |
| LOW | …Utils/lazystream/readable-stream/lib/_stream_duplex.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …ils/lazystream/readable-stream/lib/_stream_readable.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …ils/lazystream/readable-stream/lib/_stream_readable.js | 401 | } | COMMENT |
| LOW | …ils/lazystream/readable-stream/lib/_stream_writable.js | 1 | // Copyright Joyent, Inc. and other Node contributors. | COMMENT |
| LOW | …ils/lazystream/readable-stream/lib/_stream_writable.js | 141 | // when 'finish' is emitted | COMMENT |
| LOW | server/libs/libarchive/wasm-module.js | 161 | // void * archive_open( const void * buffer, size_t buffer_size) | COMMENT |
| LOW | server/libs/sanitizeHtml/index.js | 81 | COMMENT | |
| LOW | server/libs/sanitizeHtml/index.js | 381 | // Chrome accepts \ as a substitute for / in the // at the | COMMENT |
| LOW | server/libs/sanitizeHtml/index.js | 421 | } | COMMENT |
| LOW | server/libs/sanitizeHtml/index.js | 441 | // if (!parsed.length) { | COMMENT |
| LOW | server/libs/sanitizeHtml/index.js | 481 | if (a === 'style') { | COMMENT |
| LOW | server/libs/fsExtra/remove/rimraf.js | 61 | // Two possible strategies. | COMMENT |
| LOW | server/finders/BookFinder.js | 461 | */ | COMMENT |
| LOW | client/cypress/support/component.js | 1 | // *********************************************************** | COMMENT |
| LOW | client/cypress/support/commands.js | 1 | // *********************************************** | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | client/components/cards/LazyBookCard.vue | 549 | subitems: this.store.state.libraries.ereaderDevices.map((d) => { | CODE |
| CRITICAL | client/static/libs/marked/index.js | 6 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?de | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | …er/compress-commons/archivers/archive-output-stream.js | 32 | // scaffold only | COMMENT |
| MEDIUM⚡ | …er/compress-commons/archivers/archive-output-stream.js | 36 | // scaffold only | COMMENT |
| MEDIUM⚡ | …er/compress-commons/archivers/archive-output-stream.js | 46 | // scaffold only | COMMENT |
| MEDIUM⚡ | …er/compress-commons/archivers/archive-output-stream.js | 50 | // scaffold only | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | server/managers/MigrationManager.js | 118 | // Step 3: If migration fails, save the failed original and restore the backup | COMMENT |
| LOW⚡ | server/utils/scandir.js | 49 | // Step 1: Filter out non-book-media files in root dir (with depth of 0) | COMMENT |
| LOW⚡ | server/utils/scandir.js | 54 | // Step 2: Separate media files and other files | COMMENT |
| LOW | server/utils/scandir.js | 68 | // Step 3: Group media files (or non-media files if includeNonMediaFiles is true) in library items | COMMENT |
| LOW | server/utils/scandir.js | 102 | // Step 4: Add other files into library item groups | COMMENT |
| LOW | server/utils/queries/libraryItemsBookFilters.js | 852 | // Step 1: Get the first book of every series that hasnt been started yet | COMMENT |
| LOW | server/utils/queries/libraryItemsBookFilters.js | 996 | // Step 3: Map books to library items | COMMENT |
| LOW | …ver/libs/archiver/archiverUtils/stringDecoder/index.js | 233 | // number of bytes available, we need to check if we end on a leading/high | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 840 | // We need to check if there is someone still listening to | COMMENT |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 858 | // We need to check if there is someone still listening to | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | server/utils/podcastUtils.js | 78 | function extractFirstArrayItemString(json, key) { | CODE |
| LOW | server/utils/ffmpegHelpers.js | 302 | async function addCoverAndMetadataToFile(audioFilePath, coverFilePath, metadataFilePath, track, mimeType, progressCB = n | CODE |
| LOW⚡ | server/utils/scandir.js | 48 | function groupFileItemsIntoLibraryItemDirs(mediaType, fileItems, audiobooksOnly, includeNonMediaFiles = false) { | CODE |
| LOW | server/utils/parsers/parseOverdriveMediaMarkers.js | 6 | function cleanOverdriveMediaMarkers(overdriveMediaMarkers) { | CODE |
| LOW | server/utils/parsers/parseOverdriveMediaMarkers.js | 63 | function objectValuesArrayToString(arrayOfObjects) { | CODE |
| LOW | server/libs/nodeStreamZip/index.js | 224 | function readCentralDirectoryComplete() { | CODE |
| LOW | server/libs/requestIp/index.js | 16 | function getClientIpFromXForwardedFor(value) { | CODE |
| LOW | server/libs/umzug/storage/mongodb.js | 4 | function isMongoDBCollectionOptions(arg) { | CODE |
| LOW | …hiverUtils/readableStream/internal/streams/readable.js | 756 | return function pipeOnDrainFunctionResult() { | CODE |
| LOW | server/libs/libarchive/wasm-libarchive.js | 11 | var Module = typeof libarchive !== "undefined" ? libarchive : {}; var moduleOverrides = {}; var key; for (key in M | CODE |
| LOW | server/controllers/LibraryItemController.js | 48 | function ensureUserCanAccessLibraryItemsForBatch(req, res, libraryItems) { | CODE |
| LOW | server/scanner/LibraryScanner.js | 657 | async function findLibraryItemByItemToItemInoMatch(libraryId, fullPath) { | CODE |
| LOW | server/scanner/LibraryScanner.js | 668 | async function findLibraryItemByItemToFileInoMatch(libraryId, fullPath, isSingleMedia) { | CODE |
| LOW | server/scanner/LibraryScanner.js | 690 | async function findLibraryItemByFileToItemInoMatch(libraryId, fullPath, isSingleMedia, itemFiles) { | CODE |
| LOW | client/components/ui/VueTrix.vue | 48 | function enableBreakParagraphOnReturn() { | CODE |
| LOW | client/static/libarchive/wasm-gen/libarchive.js | 8 | var Module = typeof libarchive !== "undefined" ? libarchive : {}; var moduleOverrides = {}; var key; for (key in M | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | server/managers/MigrationManager.js | 118 | // Step 3: If migration fails, save the failed original and restore the backup | COMMENT |
| LOW⚡ | server/utils/scandir.js | 49 | // Step 1: Filter out non-book-media files in root dir (with depth of 0) | COMMENT |
| LOW⚡ | server/utils/scandir.js | 54 | // Step 2: Separate media files and other files | COMMENT |
| LOW | server/utils/scandir.js | 68 | // Step 3: Group media files (or non-media files if includeNonMediaFiles is true) in library items | COMMENT |
| LOW | server/utils/scandir.js | 102 | // Step 4: Add other files into library item groups | COMMENT |
| LOW | server/utils/queries/libraryItemsBookFilters.js | 852 | // Step 1: Get the first book of every series that hasnt been started yet | COMMENT |
| LOW | server/utils/queries/libraryItemsBookFilters.js | 996 | // Step 3: Map books to library items | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | server/libs/libarchive/wasm-module.js | 149 | print(...text) { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | server/utils/parsers/parseOverdriveMediaMarkers.js | 112 | // this allows us to leverage the individual track durations when calculating the start times of chapters in track | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | server/libs/libarchive/wasm-libarchive.js | 11 | var Module = typeof libarchive !== "undefined" ? libarchive : {}; var moduleOverrides = {}; var key; for (key in M | CODE |
| LOW | client/static/libarchive/wasm-gen/libarchive.js | 8 | var Module = typeof libarchive !== "undefined" ? libarchive : {}; var moduleOverrides = {}; var key; for (key in M | CODE |