Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
gtechmarathon2026.bitkit.dk
httpdocs
node_modules
tailwindcss
src
util
File Content:
normalizeConfig.js
import { flagEnabled } from '../featureFlags' import log, { dim } from './log' export function normalizeConfig(config) { // Quick structure validation /** * type FilePath = string * type RawFile = { raw: string, extension?: string } * type ExtractorFn = (content: string) => Array<string> * type TransformerFn = (content: string) => string * * type Content = * | Array<FilePath | RawFile> * | { * files: Array<FilePath | RawFile>, * extract?: ExtractorFn | { [extension: string]: ExtractorFn } * transform?: TransformerFn | { [extension: string]: TransformerFn } * } */ let valid = (() => { // `config.purge` should not exist anymore if (config.purge) { return false } // `config.content` should exist if (!config.content) { return false } // `config.content` should be an object or an array if ( !Array.isArray(config.content) && !(typeof config.content === 'object' && config.content !== null) ) { return false } // When `config.content` is an array, it should consist of FilePaths or RawFiles if (Array.isArray(config.content)) { return config.content.every((path) => { // `path` can be a string if (typeof path === 'string') return true // `path` can be an object { raw: string, extension?: string } // `raw` must be a string if (typeof path?.raw !== 'string') return false // `extension` (if provided) should also be a string if (path?.extension && typeof path?.extension !== 'string') { return false } return true }) } // When `config.content` is an object if (typeof config.content === 'object' && config.content !== null) { // Only `files`, `relative`, `extract`, and `transform` can exist in `config.content` if ( Object.keys(config.content).some( (key) => !['files', 'relative', 'extract', 'transform'].includes(key) ) ) { return false } // `config.content.files` should exist of FilePaths or RawFiles if (Array.isArray(config.content.files)) { if ( !config.content.files.every((path) => { // `path` can be a string if (typeof path === 'string') return true // `path` can be an object { raw: string, extension?: string } // `raw` must be a string if (typeof path?.raw !== 'string') return false // `extension` (if provided) should also be a string if (path?.extension && typeof path?.extension !== 'string') { return false } return true }) ) { return false } // `config.content.extract` is optional, and can be a Function or a Record<String, Function> if (typeof config.content.extract === 'object') { for (let value of Object.values(config.content.extract)) { if (typeof value !== 'function') { return false } } } else if ( !(config.content.extract === undefined || typeof config.content.extract === 'function') ) { return false } // `config.content.transform` is optional, and can be a Function or a Record<String, Function> if (typeof config.content.transform === 'object') { for (let value of Object.values(config.content.transform)) { if (typeof value !== 'function') { return false } } } else if ( !( config.content.transform === undefined || typeof config.content.transform === 'function' ) ) { return false } // `config.content.relative` is optional and can be a boolean if ( typeof config.content.relative !== 'boolean' && typeof config.content.relative !== 'undefined' ) { return false } } return true } return false })() if (!valid) { log.warn('purge-deprecation', [ 'The `purge`/`content` options have changed in Tailwind CSS v3.0.', 'Update your configuration file to eliminate this warning.', 'https://tailwindcss.com/docs/upgrade-guide#configure-content-sources', ]) } // Normalize the `safelist` config.safelist = (() => { let { content, purge, safelist } = config if (Array.isArray(safelist)) return safelist if (Array.isArray(content?.safelist)) return content.safelist if (Array.isArray(purge?.safelist)) return purge.safelist if (Array.isArray(purge?.options?.safelist)) return purge.options.safelist return [] })() // Normalize the `blocklist` config.blocklist = (() => { let { blocklist } = config if (Array.isArray(blocklist)) { if (blocklist.every((item) => typeof item === 'string')) { return blocklist } log.warn('blocklist-invalid', [ 'The `blocklist` option must be an array of strings.', 'https://tailwindcss.com/docs/content-configuration#discarding-classes', ]) } return [] })() // Normalize prefix option if (typeof config.prefix === 'function') { log.warn('prefix-function', [ 'As of Tailwind CSS v3.0, `prefix` cannot be a function.', 'Update `prefix` in your configuration to be a string to eliminate this warning.', 'https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function', ]) config.prefix = '' } else { config.prefix = config.prefix ?? '' } // Normalize the `content` config.content = { relative: (() => { let { content } = config if (content?.relative) { return content.relative } return flagEnabled(config, 'relativeContentPathsByDefault') })(), files: (() => { let { content, purge } = config if (Array.isArray(purge)) return purge if (Array.isArray(purge?.content)) return purge.content if (Array.isArray(content)) return content if (Array.isArray(content?.content)) return content.content if (Array.isArray(content?.files)) return content.files return [] })(), extract: (() => { let extract = (() => { if (config.purge?.extract) return config.purge.extract if (config.content?.extract) return config.content.extract if (config.purge?.extract?.DEFAULT) return config.purge.extract.DEFAULT if (config.content?.extract?.DEFAULT) return config.content.extract.DEFAULT if (config.purge?.options?.extractors) return config.purge.options.extractors if (config.content?.options?.extractors) return config.content.options.extractors return {} })() let extractors = {} let defaultExtractor = (() => { if (config.purge?.options?.defaultExtractor) { return config.purge.options.defaultExtractor } if (config.content?.options?.defaultExtractor) { return config.content.options.defaultExtractor } return undefined })() if (defaultExtractor !== undefined) { extractors.DEFAULT = defaultExtractor } // Functions if (typeof extract === 'function') { extractors.DEFAULT = extract } // Arrays else if (Array.isArray(extract)) { for (let { extensions, extractor } of extract ?? []) { for (let extension of extensions) { extractors[extension] = extractor } } } // Objects else if (typeof extract === 'object' && extract !== null) { Object.assign(extractors, extract) } return extractors })(), transform: (() => { let transform = (() => { if (config.purge?.transform) return config.purge.transform if (config.content?.transform) return config.content.transform if (config.purge?.transform?.DEFAULT) return config.purge.transform.DEFAULT if (config.content?.transform?.DEFAULT) return config.content.transform.DEFAULT return {} })() let transformers = {} if (typeof transform === 'function') { transformers.DEFAULT = transform } else if (typeof transform === 'object' && transform !== null) { Object.assign(transformers, transform) } return transformers })(), } // Validate globs to prevent bogus globs. // E.g.: `./src/*.{html}` is invalid, the `{html}` should just be `html` for (let file of config.content.files) { if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) { log.warn('invalid-glob-braces', [ `The glob pattern ${dim(file)} in your Tailwind CSS configuration is invalid.`, `Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`, // TODO: Add https://tw.wtf/invalid-glob-braces ]) break } } return config }
Edit
Download
Unzip
Chmod
Delete