node_modules
.bin
@ampproject
@babel
@discoveryjs
@gar
@istanbuljs
@jridgewell
@leichtgewicht
@npmcli
@riotjs
@tootallnate
@types
@ungap
@webassemblyjs
@webpack-cli
@xtuc
abab
abbrev
accepts
acorn
acorn-globals
acorn-import-assertions
acorn-walk
agent-base
agentkeepalive
aggregate-error
ajv
ajv-formats
ajv-keywords
ansi-colors
ansi-html-community
ansi-regex
ansi-styles
anymatch
append-transform
aproba
archy
are-we-there-yet
argparse
array-flatten
arrify
assertion-error
ast-types
async-foreach
asynckit
babel-plugin-dynamic-import-node
babel-plugin-polyfill-corejs2
babel-plugin-polyfill-corejs3
babel-plugin-polyfill-regenerator
balanced-match
batch
bianco.attr
bianco.dom-to-array
bianco.events
bianco.query
big.js
binary-extensions
body-parser
bonjour-service
boolbase
brace-expansion
braces
browser-process-hrtime
browser-stdout
browserslist
buffer-from
bytes
cacache
caching-transform
call-bind
camel-case
camelcase
camelcase-keys
caniuse-lite
chai
chalk
check-error
chokidar
chownr
chrome-trace-event
clean-css
lib
optimizer
options
reader
apply-source-maps.js
extract-import-url-and-media.js
input-source-map-tracker.js
is-allowed-resource.js
load-original-sources.js
load-remote-resource.js
match-data-uri.js
normalize-path.js
read-sources.js
rebase-local-map.js
rebase-remote-map.js
rebase.js
restore-import.js
rewrite-url.js
tokenizer
utils
writer
clean.js
History.md
LICENSE
README.md
index.js
package.json
clean-stack
cliui
clone-deep
color-convert
color-name
color-support
colorette
combined-stream
commander
commondir
compressible
compression
concat-map
connect-history-api-fallback
console-control-strings
content-disposition
content-type
convert-source-map
cookie
cookie-signature
core-js-compat
core-util-is
cross-spawn
css-select
css-what
cssesc
cssom
cssstyle
cumpa
curri
data-urls
debug
decamelize
decamelize-keys
decimal.js
deep-eql
deep-is
default-gateway
default-require-extensions
define-lazy-prop
define-properties
delayed-stream
delegates
depd
destroy
detect-node
diff
dns-equal
dns-packet
dom-converter
dom-nodes
dom-serializer
domelementtype
domexception
domhandler
domutils
dot-case
ee-first
electron-to-chromium
emoji-regex
emojis-list
encodeurl
encoding
enhanced-resolve
entities
env-paths
envinfo
err-code
erre
error-ex
es-module-lexer
es6-error
escalade
escape-html
escape-string-regexp
escodegen
eslint-scope
esm
esprima
esrecurse
estraverse
esutils
etag
eventemitter3
events
execa
express
fast-deep-equal
fast-json-stable-stringify
fast-levenshtein
fastest-levenshtein
faye-websocket
fill-range
finalhandler
find-up
flat
follow-redirects
foreground-child
form-data
forwarded
fresh
fromentries
fs-minipass
fs-monkey
fs.realpath
function-bind
gauge
gaze
gensync
get-caller-file
get-func-name
get-intrinsic
get-package-type
get-stdin
get-stream
glob
glob-parent
glob-to-regexp
globals
globule
graceful-fs
growl
handle-thing
hard-rejection
has
has-flag
has-property-descriptors
has-symbols
has-unicode
hasha
he
hosted-git-info
hpack.js
html-encoding-sniffer
html-entities
html-escaper
html-minifier-terser
html-webpack-plugin
htmlparser2
http-cache-semantics
http-deceiver
http-errors
http-parser-js
http-proxy
http-proxy-agent
http-proxy-middleware
https-proxy-agent
human-signals
humanize-ms
iconv-lite
imurmurhash
indent-string
infer-owner
inflight
inherits
interpret
ip
ipaddr.js
is-arrayish
is-binary-path
is-core-module
is-docker
is-extglob
is-fullwidth-code-point
is-glob
is-lambda
is-number
is-plain-obj
is-plain-object
is-potential-custom-element-name
is-stream
is-typedarray
is-windows
is-wsl
isarray
isexe
isobject
istanbul-lib-coverage
istanbul-lib-hook
istanbul-lib-instrument
istanbul-lib-processinfo
istanbul-lib-report
istanbul-lib-source-maps
istanbul-reports
jest-worker
js-base64
js-tokens
js-yaml
jsdom
jsdom-global
jsesc
json-parse-even-better-errors
json-schema-traverse
json5
kind-of
levn
lines-and-columns
loader-runner
locate-path
lodash
lodash.debounce
lodash.flattendeep
log-symbols
loupe
lower-case
lru-cache
make-fetch-happen
map-obj
media-typer
memfs
meow
merge-descriptors
merge-stream
methods
micromatch
mime
mime-db
mime-types
mimic-fn
min-indent
minimalistic-assert
minimatch
minimist-options
minipass
minipass-collect
minipass-fetch
minipass-flush
minipass-pipeline
minipass-sized
minizlib
mkdirp
mocha
ms
multicast-dns
nan
nanoid
negotiator
neo-async
no-case
node-forge
node-gyp
node-preload
node-releases
node-sass
nopt
normalize-package-data
normalize-path
npm-run-path
npmlog
nth-check
nwsapi
nyc
object-inspect
object-keys
object.assign
obuf
on-finished
on-headers
once
onetime
open
optionator
p-limit
p-locate
p-map
p-retry
p-try
package-hash
param-case
parse-json
parse5
parseurl
pascal-case
path-exists
path-is-absolute
path-key
path-parse
path-to-regexp
pathval
picocolors
picomatch
pirates
prelude-ls
pretty-error
process-nextick-args
process-on-spawn
promise-inflight
promise-retry
proxy-addr
psl
punycode
qs
quick-lru
randombytes
range-parser
raw-body
rawth
read-pkg
read-pkg-up
readable-stream
readdirp
recast
rechoir
redent
regenerate
regenerate-unicode-properties
regenerator-runtime
regenerator-transform
regexpu-core
regjsgen
regjsparser
relateurl
release-zalgo
renderkid
require-directory
require-from-string
require-main-filename
requires-port
resolve
retry
rimraf
riot
ruit
safe-buffer
safer-buffer
sass-graph
saxes
schema-utils
scss-tokenizer
select-hose
selfsigned
semver
send
serialize-javascript
serve-index
serve-static
set-blocking
setprototypeof
shallow-clone
shebang-command
shebang-regex
side-channel
signal-exit
smart-buffer
sockjs
socks
socks-proxy-agent
source-map
source-map-support
spawn-wrap
spdx-correct
spdx-exceptions
spdx-expression-parse
spdx-license-ids
spdy
spdy-transport
sprintf-js
ssri
statuses
stdout-stream
string-width
string_decoder
strip-ansi
strip-final-newline
strip-indent
strip-json-comments
supports-color
symbol-tree
tapable
tar
terser
terser-webpack-plugin
test-exclude
thunky
to-fast-properties
to-regex-range
toidentifier
tough-cookie
tr46
trim-newlines
true-case-path
tslib
type-check
type-detect
type-fest
type-is
typedarray-to-buffer
unicode-canonical-property-names-ecmascript
unicode-match-property-ecmascript
unicode-match-property-value-ecmascript
unicode-property-aliases-ecmascript
unique-filename
unique-slug
universalify
unpipe
update-browserslist-db
uri-js
util-deprecate
utila
utils-merge
uuid
validate-npm-package-license
vary
w3c-hr-time
w3c-xmlserializer
watchpack
wbuf
webidl-conversions
webpack
webpack-cli
webpack-dev-middleware
webpack-dev-server
webpack-merge
webpack-sources
websocket-driver
websocket-extensions
whatwg-encoding
whatwg-mimetype
whatwg-url
which
which-module
wide-align
wildcard
word-wrap
workerpool
wrap-ansi
wrappy
write-file-atomic
ws
xml-name-validator
xmlchars
y18n
yallist
yargs
yargs-parser
yargs-unparser
yocto-queue
.package-lock.json
src
LICENSE
package-lock.json
package.json
readme.md
webpack.config.js
341 lines
13 KiB
JavaScript
341 lines
13 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
|
|
var applySourceMaps = require('./apply-source-maps');
|
|
var extractImportUrlAndMedia = require('./extract-import-url-and-media');
|
|
var isAllowedResource = require('./is-allowed-resource');
|
|
var loadOriginalSources = require('./load-original-sources');
|
|
var normalizePath = require('./normalize-path');
|
|
var rebase = require('./rebase');
|
|
var rebaseLocalMap = require('./rebase-local-map');
|
|
var rebaseRemoteMap = require('./rebase-remote-map');
|
|
var restoreImport = require('./restore-import');
|
|
|
|
var tokenize = require('../tokenizer/tokenize');
|
|
var Token = require('../tokenizer/token');
|
|
var Marker = require('../tokenizer/marker');
|
|
var hasProtocol = require('../utils/has-protocol');
|
|
var isImport = require('../utils/is-import');
|
|
var isRemoteResource = require('../utils/is-remote-resource');
|
|
|
|
var UNKNOWN_URI = 'uri:unknown';
|
|
var FILE_RESOURCE_PROTOCOL = 'file://';
|
|
|
|
function readSources(input, context, callback) {
|
|
return doReadSources(input, context, function(tokens) {
|
|
return applySourceMaps(tokens, context, function() {
|
|
return loadOriginalSources(context, function() { return callback(tokens); });
|
|
});
|
|
});
|
|
}
|
|
|
|
function doReadSources(input, context, callback) {
|
|
if (typeof input == 'string') {
|
|
return fromString(input, context, callback);
|
|
} if (Buffer.isBuffer(input)) {
|
|
return fromString(input.toString(), context, callback);
|
|
} if (Array.isArray(input)) {
|
|
return fromArray(input, context, callback);
|
|
} if (typeof input == 'object') {
|
|
return fromHash(input, context, callback);
|
|
}
|
|
}
|
|
|
|
function fromString(input, context, callback) {
|
|
context.source = undefined;
|
|
context.sourcesContent[undefined] = input;
|
|
context.stats.originalSize += input.length;
|
|
|
|
return fromStyles(input, context, { inline: context.options.inline }, callback);
|
|
}
|
|
|
|
function fromArray(input, context, callback) {
|
|
var inputAsImports = input.reduce(function(accumulator, uriOrHash) {
|
|
if (typeof uriOrHash === 'string') {
|
|
return addStringSource(uriOrHash, accumulator);
|
|
}
|
|
return addHashSource(uriOrHash, context, accumulator);
|
|
}, []);
|
|
|
|
return fromStyles(inputAsImports.join(''), context, { inline: ['all'] }, callback);
|
|
}
|
|
|
|
function fromHash(input, context, callback) {
|
|
var inputAsImports = addHashSource(input, context, []);
|
|
return fromStyles(inputAsImports.join(''), context, { inline: ['all'] }, callback);
|
|
}
|
|
|
|
function addStringSource(input, imports) {
|
|
imports.push(restoreAsImport(normalizeUri(input)));
|
|
return imports;
|
|
}
|
|
|
|
function addHashSource(input, context, imports) {
|
|
var uri;
|
|
var normalizedUri;
|
|
var source;
|
|
|
|
for (uri in input) {
|
|
source = input[uri];
|
|
normalizedUri = normalizeUri(uri);
|
|
|
|
imports.push(restoreAsImport(normalizedUri));
|
|
|
|
context.sourcesContent[normalizedUri] = source.styles;
|
|
|
|
if (source.sourceMap) {
|
|
trackSourceMap(source.sourceMap, normalizedUri, context);
|
|
}
|
|
}
|
|
|
|
return imports;
|
|
}
|
|
|
|
function normalizeUri(uri) {
|
|
var currentPath = path.resolve('');
|
|
var absoluteUri;
|
|
var relativeToCurrentPath;
|
|
var normalizedUri;
|
|
|
|
if (isRemoteResource(uri)) {
|
|
return uri;
|
|
}
|
|
|
|
absoluteUri = path.isAbsolute(uri)
|
|
? uri
|
|
: path.resolve(uri);
|
|
relativeToCurrentPath = path.relative(currentPath, absoluteUri);
|
|
normalizedUri = normalizePath(relativeToCurrentPath);
|
|
|
|
return normalizedUri;
|
|
}
|
|
|
|
function trackSourceMap(sourceMap, uri, context) {
|
|
var parsedMap = typeof sourceMap == 'string'
|
|
? JSON.parse(sourceMap)
|
|
: sourceMap;
|
|
var rebasedMap = isRemoteResource(uri)
|
|
? rebaseRemoteMap(parsedMap, uri)
|
|
: rebaseLocalMap(parsedMap, uri || UNKNOWN_URI, context.options.rebaseTo);
|
|
|
|
context.inputSourceMapTracker.track(uri, rebasedMap);
|
|
}
|
|
|
|
function restoreAsImport(uri) {
|
|
return restoreImport('url(' + uri + ')', '') + Marker.SEMICOLON;
|
|
}
|
|
|
|
function fromStyles(styles, context, parentInlinerContext, callback) {
|
|
var tokens;
|
|
var rebaseConfig = {};
|
|
|
|
if (!context.source) {
|
|
rebaseConfig.fromBase = path.resolve('');
|
|
rebaseConfig.toBase = context.options.rebaseTo;
|
|
} else if (isRemoteResource(context.source)) {
|
|
rebaseConfig.fromBase = context.source;
|
|
rebaseConfig.toBase = context.source;
|
|
} else if (path.isAbsolute(context.source)) {
|
|
rebaseConfig.fromBase = path.dirname(context.source);
|
|
rebaseConfig.toBase = context.options.rebaseTo;
|
|
} else {
|
|
rebaseConfig.fromBase = path.dirname(path.resolve(context.source));
|
|
rebaseConfig.toBase = context.options.rebaseTo;
|
|
}
|
|
|
|
tokens = tokenize(styles, context);
|
|
tokens = rebase(tokens, context.options.rebase, context.validator, rebaseConfig);
|
|
|
|
return allowsAnyImports(parentInlinerContext.inline)
|
|
? inline(tokens, context, parentInlinerContext, callback)
|
|
: callback(tokens);
|
|
}
|
|
|
|
function allowsAnyImports(inline) {
|
|
return !(inline.length == 1 && inline[0] == 'none');
|
|
}
|
|
|
|
function inline(tokens, externalContext, parentInlinerContext, callback) {
|
|
var inlinerContext = {
|
|
afterContent: false,
|
|
callback: callback,
|
|
errors: externalContext.errors,
|
|
externalContext: externalContext,
|
|
fetch: externalContext.options.fetch,
|
|
inlinedStylesheets: parentInlinerContext.inlinedStylesheets || externalContext.inlinedStylesheets,
|
|
inline: parentInlinerContext.inline,
|
|
inlineRequest: externalContext.options.inlineRequest,
|
|
inlineTimeout: externalContext.options.inlineTimeout,
|
|
isRemote: parentInlinerContext.isRemote || false,
|
|
localOnly: externalContext.localOnly,
|
|
outputTokens: [],
|
|
rebaseTo: externalContext.options.rebaseTo,
|
|
sourceTokens: tokens,
|
|
warnings: externalContext.warnings
|
|
};
|
|
|
|
return doInlineImports(inlinerContext);
|
|
}
|
|
|
|
function doInlineImports(inlinerContext) {
|
|
var token;
|
|
var i, l;
|
|
|
|
for (i = 0, l = inlinerContext.sourceTokens.length; i < l; i++) {
|
|
token = inlinerContext.sourceTokens[i];
|
|
|
|
if (token[0] == Token.AT_RULE && isImport(token[1])) {
|
|
inlinerContext.sourceTokens.splice(0, i);
|
|
return inlineStylesheet(token, inlinerContext);
|
|
} if (token[0] == Token.AT_RULE || token[0] == Token.COMMENT) {
|
|
inlinerContext.outputTokens.push(token);
|
|
} else {
|
|
inlinerContext.outputTokens.push(token);
|
|
inlinerContext.afterContent = true;
|
|
}
|
|
}
|
|
|
|
inlinerContext.sourceTokens = [];
|
|
return inlinerContext.callback(inlinerContext.outputTokens);
|
|
}
|
|
|
|
function inlineStylesheet(token, inlinerContext) {
|
|
var uriAndMediaQuery = extractImportUrlAndMedia(token[1]);
|
|
var uri = uriAndMediaQuery[0];
|
|
var mediaQuery = uriAndMediaQuery[1];
|
|
var metadata = token[2];
|
|
|
|
return isRemoteResource(uri)
|
|
? inlineRemoteStylesheet(uri, mediaQuery, metadata, inlinerContext)
|
|
: inlineLocalStylesheet(uri, mediaQuery, metadata, inlinerContext);
|
|
}
|
|
|
|
function inlineRemoteStylesheet(uri, mediaQuery, metadata, inlinerContext) {
|
|
var isAllowed = isAllowedResource(uri, true, inlinerContext.inline);
|
|
var originalUri = uri;
|
|
var isLoaded = uri in inlinerContext.externalContext.sourcesContent;
|
|
var isRuntimeResource = !hasProtocol(uri);
|
|
|
|
if (inlinerContext.inlinedStylesheets.indexOf(uri) > -1) {
|
|
inlinerContext.warnings.push('Ignoring remote @import of "' + uri + '" as it has already been imported.');
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
} if (inlinerContext.localOnly && inlinerContext.afterContent) {
|
|
inlinerContext.warnings.push('Ignoring remote @import of "' + uri + '" as no callback given and after other content.');
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
} if (isRuntimeResource) {
|
|
inlinerContext.warnings.push('Skipping remote @import of "' + uri + '" as no protocol given.');
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1));
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
} if (inlinerContext.localOnly && !isLoaded) {
|
|
inlinerContext.warnings.push('Skipping remote @import of "' + uri + '" as no callback given.');
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1));
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
} if (!isAllowed && inlinerContext.afterContent) {
|
|
inlinerContext.warnings.push('Ignoring remote @import of "' + uri + '" as resource is not allowed and after other content.');
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
} if (!isAllowed) {
|
|
inlinerContext.warnings.push('Skipping remote @import of "' + uri + '" as resource is not allowed.');
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1));
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
return doInlineImports(inlinerContext);
|
|
}
|
|
|
|
inlinerContext.inlinedStylesheets.push(uri);
|
|
|
|
function whenLoaded(error, importedStyles) {
|
|
if (error) {
|
|
inlinerContext.errors.push('Broken @import declaration of "' + uri + '" - ' + error);
|
|
|
|
return process.nextTick(function() {
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1));
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
doInlineImports(inlinerContext);
|
|
});
|
|
}
|
|
|
|
inlinerContext.inline = inlinerContext.externalContext.options.inline;
|
|
inlinerContext.isRemote = true;
|
|
|
|
inlinerContext.externalContext.source = originalUri;
|
|
inlinerContext.externalContext.sourcesContent[uri] = importedStyles;
|
|
inlinerContext.externalContext.stats.originalSize += importedStyles.length;
|
|
|
|
return fromStyles(importedStyles, inlinerContext.externalContext, inlinerContext, function(importedTokens) {
|
|
importedTokens = wrapInMedia(importedTokens, mediaQuery, metadata);
|
|
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(importedTokens);
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
|
|
return doInlineImports(inlinerContext);
|
|
});
|
|
}
|
|
|
|
return isLoaded
|
|
? whenLoaded(null, inlinerContext.externalContext.sourcesContent[uri])
|
|
: inlinerContext.fetch(uri, inlinerContext.inlineRequest, inlinerContext.inlineTimeout, whenLoaded);
|
|
}
|
|
|
|
function inlineLocalStylesheet(uri, mediaQuery, metadata, inlinerContext) {
|
|
var protocolLessUri = uri.replace(FILE_RESOURCE_PROTOCOL, '');
|
|
var currentPath = path.resolve('');
|
|
var absoluteUri = path.isAbsolute(protocolLessUri)
|
|
? path.resolve(currentPath, protocolLessUri[0] == '/' ? protocolLessUri.substring(1) : protocolLessUri)
|
|
: path.resolve(inlinerContext.rebaseTo, protocolLessUri);
|
|
var relativeToCurrentPath = path.relative(currentPath, absoluteUri);
|
|
var importedStyles;
|
|
var isAllowed = isAllowedResource(protocolLessUri, false, inlinerContext.inline);
|
|
var normalizedPath = normalizePath(relativeToCurrentPath);
|
|
var isLoaded = normalizedPath in inlinerContext.externalContext.sourcesContent;
|
|
|
|
if (inlinerContext.inlinedStylesheets.indexOf(absoluteUri) > -1) {
|
|
inlinerContext.warnings.push('Ignoring local @import of "' + protocolLessUri + '" as it has already been imported.');
|
|
} else if (isAllowed && !isLoaded && (!fs.existsSync(absoluteUri) || !fs.statSync(absoluteUri).isFile())) {
|
|
inlinerContext.errors.push('Ignoring local @import of "' + protocolLessUri + '" as resource is missing.');
|
|
} else if (!isAllowed && inlinerContext.afterContent) {
|
|
inlinerContext.warnings.push('Ignoring local @import of "' + protocolLessUri + '" as resource is not allowed and after other content.');
|
|
} else if (inlinerContext.afterContent) {
|
|
inlinerContext.warnings.push('Ignoring local @import of "' + protocolLessUri + '" as after other content.');
|
|
} else if (!isAllowed) {
|
|
inlinerContext.warnings.push('Skipping local @import of "' + protocolLessUri + '" as resource is not allowed.');
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1));
|
|
} else {
|
|
importedStyles = isLoaded
|
|
? inlinerContext.externalContext.sourcesContent[normalizedPath]
|
|
: fs.readFileSync(absoluteUri, 'utf-8');
|
|
|
|
inlinerContext.inlinedStylesheets.push(absoluteUri);
|
|
inlinerContext.inline = inlinerContext.externalContext.options.inline;
|
|
|
|
inlinerContext.externalContext.source = normalizedPath;
|
|
inlinerContext.externalContext.sourcesContent[normalizedPath] = importedStyles;
|
|
inlinerContext.externalContext.stats.originalSize += importedStyles.length;
|
|
|
|
return fromStyles(importedStyles, inlinerContext.externalContext, inlinerContext, function(importedTokens) {
|
|
importedTokens = wrapInMedia(importedTokens, mediaQuery, metadata);
|
|
|
|
inlinerContext.outputTokens = inlinerContext.outputTokens.concat(importedTokens);
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
|
|
return doInlineImports(inlinerContext);
|
|
});
|
|
}
|
|
|
|
inlinerContext.sourceTokens = inlinerContext.sourceTokens.slice(1);
|
|
|
|
return doInlineImports(inlinerContext);
|
|
}
|
|
|
|
function wrapInMedia(tokens, mediaQuery, metadata) {
|
|
if (mediaQuery) {
|
|
return [[Token.NESTED_BLOCK, [[Token.NESTED_BLOCK_SCOPE, '@media ' + mediaQuery, metadata]], tokens]];
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
module.exports = readSources;
|