{Rewriter, INVERSES, UNFINISHED} = require './rewriter'
The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt matches against the beginning of the source code. When a match is found, a token is produced, we consume the match, and start again. Tokens are in the form:
[tag, value, locationData]
where locationData is {first_line, first_column, last_line, last_column, last_line_exclusive, last_column_exclusive}, which is a
format that can be fed directly into Jison. These
are read by jison in the parser.lexer
function defined in coffeescript.coffee.
{Rewriter, INVERSES, UNFINISHED} = require './rewriter'
Import the helpers we need.
{count, starts, compact, repeat, invertLiterate, merge,
attachCommentsToNode, locationDataToString, throwSyntaxError
replaceUnicodeCodePointEscapes, flatten, parseNumber} = require './helpers'
The Lexer class reads a stream of CoffeeScript and divvies it up into tagged tokens. Some potential ambiguity in the grammar has been avoided by pushing some extra smarts into the Lexer.
exports.Lexer = class Lexer
tokenize is the Lexer’s main method. Scan by attempting to match tokens one at a time, using a regular expression anchored at the start of the remaining code, or a custom recursive token-matching method (for interpolations). When the next token has been recorded, we move forward within the code past the token, and begin again.
Each tokenizing method is responsible for returning the number of characters it has consumed.
Before returning the token stream, run it through the Rewriter.
tokenize: (code, opts = {}) ->
@literate = opts.literate # Are we lexing literate CoffeeScript?
@indent = 0 # The current indentation level.
@baseIndent = 0 # The overall minimum indentation level.
@continuationLineAdditionalIndent = 0 # The over-indentation at the current level.
@outdebt = 0 # The under-outdentation at the current level.
@indents = [] # The stack of all current indentation levels.
@indentLiteral = '' # The indentation.
@ends = [] # The stack for pairing up tokens.
@tokens = [] # Stream of parsed tokens in the form `['TYPE', value, location data]`.
@seenFor = no # Used to recognize `FORIN`, `FOROF` and `FORFROM` tokens.
@seenImport = no # Used to recognize `IMPORT FROM? AS?` tokens.
@seenExport = no # Used to recognize `EXPORT FROM? AS?` tokens.
@importSpecifierList = no # Used to identify when in an `IMPORT {...} FROM? ...`.
@exportSpecifierList = no # Used to identify when in an `EXPORT {...} FROM? ...`.
@jsxDepth = 0 # Used to optimize JSX checks, how deep in JSX we are.
@jsxObjAttribute = {} # Used to detect if JSX attributes is wrapped in {} (<div {props...} />).
@chunkLine =
opts.line or 0 # The start line for the current @chunk.
@chunkColumn =
opts.column or 0 # The start column of the current @chunk.
@chunkOffset =
opts.offset or 0 # The start offset for the current @chunk.
@locationDataCompensations =
opts.locationDataCompensations or {} # The location data compensations for the current @chunk.
code = @clean code # The stripped, cleaned original source code.
At every position, run through this list of attempted matches,
short-circuiting if any of them succeed. Their order determines precedence:
@literalToken
is the fallback catch-all.
i = 0
while @chunk = code[i..]
consumed = \
@identifierToken() or
@commentToken() or
@whitespaceToken() or
@lineToken() or
@stringToken() or
@numberToken() or
@jsxToken() or
@regexToken() or
@jsToken() or
@literalToken()
Update position.
[@chunkLine, @chunkColumn, @chunkOffset] = @getLineAndColumnFromChunk consumed
i += consumed
return {@tokens, index: i} if opts.untilBalanced and @ends.length is 0
@closeIndentation()
@error "missing #{end.tag}", (end.origin ? end)[2] if end = @ends.pop()
return @tokens if opts.rewrite is off
(new Rewriter).rewrite @tokens
Preprocess the code to remove leading and trailing whitespace, carriage returns, etc. If we’re lexing literate CoffeeScript, strip external Markdown by removing all lines that aren’t indented by at least four spaces or a tab.
clean: (code) ->
thusFar = 0
if code.charCodeAt(0) is BOM
code = code.slice 1
@locationDataCompensations[0] = 1
thusFar += 1
if WHITESPACE.test code
code = "\n#{code}"
@chunkLine--
@locationDataCompensations[0] ?= 0
@locationDataCompensations[0] -= 1
code = code
.replace /\r/g, (match, offset) =>
@locationDataCompensations[thusFar + offset] = 1
''
.replace TRAILING_SPACES, ''
code = invertLiterate code if @literate
code
Matches identifying literals: variables, keywords, method names, etc.
Check to ensure that JavaScript reserved words aren’t being used as
identifiers. Because CoffeeScript reserves a handful of keywords that are
allowed in JavaScript, we’re careful not to tag them as keywords when
referenced as property names here, so you can still do jQuery.is()
even
though is
means ===
otherwise.
identifierToken: ->
inJSXTag = @atJSXTag()
regex = if inJSXTag then JSX_ATTRIBUTE else IDENTIFIER
return 0 unless match = regex.exec @chunk
[input, id, colon] = match
Preserve length of id for location data
idLength = id.length
poppedToken = undefined
if id is 'own' and @tag() is 'FOR'
@token 'OWN', id
return id.length
if id is 'from' and @tag() is 'YIELD'
@token 'FROM', id
return id.length
if id is 'as' and @seenImport
if @value() is '*'
<EMAIL_ADDRESS>- 1][0] = 'IMPORT_ALL'
else if @value(yes) in COFFEE_KEYWORDS
prev = @prev()
[prev[0], prev[1]] = ['IDENTIFIER', @value(yes)]
if @tag() in ['DEFAULT', 'IMPORT_ALL', 'IDENTIFIER']
@token 'AS', id
return id.length
if id is 'as' and @seenExport
if @tag() in ['IDENTIFIER', 'DEFAULT']
@token 'AS', id
return id.length
if @value(yes) in COFFEE_KEYWORDS
prev = @prev()
[prev[0], prev[1]] = ['IDENTIFIER', @value(yes)]
@token 'AS', id
return id.length
if id is 'default' and @seenExport and @tag() in ['EXPORT', 'AS']
@token 'DEFAULT', id
return id.length
if id is 'assert' and (@seenImport or @seenExport) and @tag() is 'STRING'
@token 'ASSERT', id
return id.length
if id is 'do' and regExSuper = /^(\s*super)(?!\(\))/.exec @chunk[3...]
@token 'SUPER', 'super'
@token 'CALL_START', '('
@token 'CALL_END', ')'
[input, sup] = regExSuper
return sup.length + 3
prev = @prev()
tag =
if colon or prev? and
(prev[0] in ['.', '?.', '::', '?::'] or
not prev.spaced and prev[0] is '@')
'PROPERTY'
else
'IDENTIFIER'
tokenData = {}
if tag is 'IDENTIFIER' and (id in JS_KEYWORDS or id in COFFEE_KEYWORDS) and
not (@exportSpecifierList and id in COFFEE_KEYWORDS)
tag = id.toUpperCase()
if tag is 'WHEN' and @tag() in LINE_BREAK
tag = 'LEADING_WHEN'
else if tag is 'FOR'
@seenFor = {endsLength: @ends.length}
else if tag is 'UNLESS'
tag = 'IF'
else if tag is 'IMPORT'
@seenImport = yes
else if tag is 'EXPORT'
@seenExport = yes
else if tag in UNARY
tag = 'UNARY'
else if tag in RELATION
if tag isnt 'INSTANCEOF' and @seenFor
tag = 'FOR' + tag
@seenFor = no
else
tag = 'RELATION'
if @value() is '!'
poppedToken = @tokens.pop()
tokenData.invert = poppedToken.data?.original ? poppedToken[1]
else if tag is 'IDENTIFIER' and @seenFor and id is 'from' and
isForFrom(prev)
tag = 'FORFROM'
@seenFor = no
Throw an error on attempts to use get
or set
as keywords, or
what CoffeeScript would normally interpret as calls to functions named
get
or set
, i.e. get({foo: function () {}})
.
else if tag is 'PROPERTY' and prev
if prev.spaced and prev[0] in CALLABLE and /^[gs]et$/.test(prev[1]) and
@tokens.length > 1 and<EMAIL_ADDRESS>- 2][0] not in ['.', '?.', '@']
@error "'#{prev[1]}' cannot be used as a keyword, or as a function call
without parentheses", prev[2]
else if prev[0] is '.' and @tokens.length > 1 and (prevprev =<EMAIL_ADDRESS>- 2])[0] is 'UNARY' and prevprev[1] is 'new'
prevprev[0] = 'NEW_TARGET'
else if prev[0] is '.' and @tokens.length > 1 and (prevprev =<EMAIL_ADDRESS>- 2])[0] is 'IMPORT' and prevprev[1] is 'import'
@seenImport = no
prevprev[0] = 'IMPORT_META'
else if @tokens.length > 2
prevprev =<EMAIL_ADDRESS>- 2]
if prev[0] in ['@', 'THIS'] and prevprev and prevprev.spaced and
/^[gs]et$/.test(prevprev[1]) and
<EMAIL_ADDRESS>- 3][0] not in ['.', '?.', '@']
@error "'#{prevprev[1]}' cannot be used as a keyword, or as a
function call without parentheses", prevprev[2]
if tag is 'IDENTIFIER' and id in RESERVED and not inJSXTag
@error "reserved word '#{id}'", length: id.length
unless tag is 'PROPERTY' or @exportSpecifierList or @importSpecifierList
if id in COFFEE_ALIASES
alias = id
id = COFFEE_ALIAS_MAP[id]
tokenData.original = alias
tag = switch id
when '!' then 'UNARY'
when '==', '!=' then 'COMPARE'
when 'true', 'false' then 'BOOL'
when 'break', 'continue', \
'debugger' then 'STATEMENT'
when '&&', '||' then id
else tag
tagToken = @token tag, id, length: idLength, data: tokenData
tagToken.origin = [tag, alias, tagToken[2]] if alias
if poppedToken
[tagToken[2].first_line, tagToken[2].first_column, tagToken[2].range[0]] =
[poppedToken[2].first_line, poppedToken[2].first_column, poppedToken[2].range[0]]
if colon
colonOffset = input.lastIndexOf if inJSXTag then '=' else ':'
colonToken = @token ':', ':', offset: colonOffset
colonToken.jsxColon = yes if inJSXTag # used by rewriter
if inJSXTag and tag is 'IDENTIFIER' and prev[0] isnt ':'
@token ',', ',', length: 0, origin: tagToken, generated: yes
input.length
Matches numbers, including decimals, hex, and exponential notation. Be careful not to interfere with ranges in progress.
numberToken: ->
return 0 unless match = NUMBER.exec @chunk
number = match[0]
lexedLength = number.length
switch
when /^0[BOX]/.test number
@error "radix prefix in '#{number}' must be lowercase", offset: 1
when /^0\d*[89]/.test number
@error "decimal literal '#{number}' must not be prefixed with '0'", length: lexedLength
when /^0\d+/.test number
@error "octal literal '#{number}' must be prefixed with '0o'", length: lexedLength
parsedValue = parseNumber number
tokenData = {parsedValue}
tag = if parsedValue is Infinity then 'INFINITY' else 'NUMBER'
if tag is 'INFINITY'
tokenData.original = number
@token tag, number,
length: lexedLength
data: tokenData
lexedLength
Matches strings, including multiline strings, as well as heredocs, with or without interpolation.
stringToken: ->
[quote] = STRING_START.exec(@chunk) || []
return 0 unless quote
If the preceding token is from
and this is an import or export statement,
properly tag the from
.
prev = @prev()
if prev and @value() is 'from' and (@seenImport or @seenExport)
prev[0] = 'FROM'
regex = switch quote
when "'" then STRING_SINGLE
when '"' then STRING_DOUBLE
when "'''" then HEREDOC_SINGLE
when '"""' then HEREDOC_DOUBLE
{tokens, index: end} = @matchWithInterpolations regex, quote
heredoc = quote.length is 3
if heredoc
Find the smallest indentation. It will be removed from all lines later.
indent = null
doc = (token[1] for token, i in tokens when token[0] is 'NEOSTRING').join '#{}'
while match = HEREDOC_INDENT.exec doc
attempt = match[1]
indent = attempt if indent is null or 0 < attempt.length < indent.length
delimiter = quote.charAt(0)
@mergeInterpolationTokens tokens, {quote, indent, endOffset: end}, (value) =>
@validateUnicodeCodePointEscapes value, delimiter: quote
if @atJSXTag()
@token ',', ',', length: 0, origin: @prev, generated: yes
end
Matches and consumes comments. The comments are taken out of the token stream and saved for later, to be reinserted into the output after everything has been parsed and the JavaScript code generated.
commentToken: (chunk = @chunk, {heregex, returnCommentTokens = no, offsetInChunk = 0} = {}) ->
return 0 unless match = chunk.match COMMENT
[commentWithSurroundingWhitespace, hereLeadingWhitespace, hereComment, hereTrailingWhitespace, lineComment] = match
contents = null
Does this comment follow code on the same line?
leadingNewline = /^\s*\n+\s*#/.test commentWithSurroundingWhitespace
if hereComment
matchIllegal = HERECOMMENT_ILLEGAL.exec hereComment
if matchIllegal
@error "block comments cannot contain #{matchIllegal[0]}",
offset: '###'.length + matchIllegal.index, length: matchIllegal[0].length
Parse indentation or outdentation as if this block comment didn’t exist.
chunk = chunk.replace "####{hereComment}###", ''
Remove leading newlines, like Rewriter::removeLeadingNewlines
, to
avoid the creation of unwanted TERMINATOR
tokens.
chunk = chunk.replace /^\n+/, ''
@lineToken {chunk}
Pull out the ###-style comment’s content, and format it.
content = hereComment
contents = [{
content
length: commentWithSurroundingWhitespace.length - hereLeadingWhitespace.length - hereTrailingWhitespace.length
leadingWhitespace: hereLeadingWhitespace
}]
else
The COMMENT
regex captures successive line comments as one token.
Remove any leading newlines before the first comment, but preserve
blank lines between line comments.
leadingNewlines = ''
content = lineComment.replace /^(\n*)/, (leading) ->
leadingNewlines = leading
''
precedingNonCommentLines = ''
hasSeenFirstCommentLine = no
contents =
content.split '\n'
.map (line, index) ->
unless line.indexOf('#') > -1
precedingNonCommentLines += "\n#{line}"
return
leadingWhitespace = ''
content = line.replace /^([ |\t]*)#/, (_, whitespace) ->
leadingWhitespace = whitespace
''
comment = {
content
length: '#'.length + content.length
leadingWhitespace: "#{unless hasSeenFirstCommentLine then leadingNewlines else ''}#{precedingNonCommentLines}#{leadingWhitespace}"
precededByBlankLine: !!precedingNonCommentLines
}
hasSeenFirstCommentLine = yes
precedingNonCommentLines = ''
comment
.filter (comment) -> comment
getIndentSize = ({leadingWhitespace, nonInitial}) ->
lastNewlineIndex = leadingWhitespace.lastIndexOf '\n'
if hereComment? or not nonInitial
return null unless lastNewlineIndex > -1
else
lastNewlineIndex ?= -1
leadingWhitespace.length - 1 - lastNewlineIndex
commentAttachments = for {content, length, leadingWhitespace, precededByBlankLine}, i in contents
nonInitial = i isnt 0
leadingNewlineOffset = if nonInitial then 1 else 0
offsetInChunk += leadingNewlineOffset + leadingWhitespace.length
indentSize = getIndentSize {leadingWhitespace, nonInitial}
noIndent = not indentSize? or indentSize is -1
commentAttachment = {
content
here: hereComment?
newLine: leadingNewline or nonInitial # Line comments after the first one start new lines, by definition.
locationData: @makeLocationData {offsetInChunk, length}
precededByBlankLine
indentSize
indented: not noIndent and indentSize > @indent
outdented: not noIndent and indentSize < @indent
}
commentAttachment.heregex = yes if heregex
offsetInChunk += length
commentAttachment
prev = @prev()
unless prev
If there’s no previous token, create a placeholder token to attach this comment to; and follow with a newline.
commentAttachments[0].newLine = yes
@lineToken chunk: @chunk[commentWithSurroundingWhitespace.length..], offset: commentWithSurroundingWhitespace.length # Set the indent.
placeholderToken = @makeToken 'JS', '', offset: commentWithSurroundingWhitespace.length, generated: yes
placeholderToken.comments = commentAttachments
@tokens.push placeholderToken
@newlineToken commentWithSurroundingWhitespace.length
else
attachCommentsToNode commentAttachments, prev
return commentAttachments if returnCommentTokens
commentWithSurroundingWhitespace.length
Matches JavaScript interpolated directly into the source via backticks.
jsToken: ->
return 0 unless @chunk.charAt(0) is '`' and
(match = (matchedHere = HERE_JSTOKEN.exec(@chunk)) or JSTOKEN.exec(@chunk))
Convert escaped backticks to backticks, and escaped backslashes just before escaped backticks to backslashes
script = match[1]
{length} = match[0]
@token 'JS', script, {length, data: {here: !!matchedHere}}
length
Matches regular expression literals, as well as multiline extended ones. Lexing regular expressions is difficult to distinguish from division, so we borrow some basic heuristics from JavaScript and Ruby.
regexToken: ->
switch
when match = REGEX_ILLEGAL.exec @chunk
@error "regular expressions cannot begin with #{match[2]}",
offset: match.index + match[1].length
when match = @matchWithInterpolations HEREGEX, '///'
{tokens, index} = match
comments = []
while matchedComment = HEREGEX_COMMENT.exec @chunk[0...index]
{index: commentIndex} = matchedComment
[fullMatch, leadingWhitespace, comment] = matchedComment
comments.push {comment, offsetInChunk: commentIndex + leadingWhitespace.length}
commentTokens = flatten(
for commentOpts in comments
@commentToken commentOpts.comment, Object.assign commentOpts, heregex: yes, returnCommentTokens: yes
)
when match = REGEX.exec @chunk
[regex, body, closed] = match
@validateEscapes body, isRegex: yes, offsetInChunk: 1
index = regex.length
prev = @prev()
if prev
if prev.spaced and prev[0] in CALLABLE
return 0 if not closed or POSSIBLY_DIVISION.test regex
else if prev[0] in NOT_REGEX
return 0
@error 'missing / (unclosed regex)' unless closed
else
return 0
[flags] = REGEX_FLAGS.exec @chunk[index..]
end = index + flags.length
origin = @makeToken 'REGEX', null, length: end
switch
when not VALID_FLAGS.test flags
@error "invalid regular expression flags #{flags}", offset: index, length: flags.length
when regex or tokens.length is 1
delimiter = if body then '/' else '///'
body ?= tokens[0][1]
@validateUnicodeCodePointEscapes body, {delimiter}
@token 'REGEX', "/#{body}/#{flags}", {length: end, origin, data: {delimiter}}
else
@token 'REGEX_START', '(', {length: 0, origin, generated: yes}
@token 'IDENTIFIER', 'RegExp', length: 0, generated: yes
@token 'CALL_START', '(', length: 0, generated: yes
@mergeInterpolationTokens tokens, {double: yes, heregex: {flags}, endOffset: end - flags.length, quote: '///'}, (str) =>
@validateUnicodeCodePointEscapes str, {delimiter}
if flags
@token ',', ',', offset: index - 1, length: 0, generated: yes
@token 'STRING', '"' + flags + '"', offset: index, length: flags.length
@token ')', ')', offset: end, length: 0, generated: yes
@token 'REGEX_END', ')', offset: end, length: 0, generated: yes
Explicitly attach any heregex comments to the REGEX/REGEX_END token.
if commentTokens?.length
addTokenData<EMAIL_ADDRESS>- 1],
heregexCommentTokens: commentTokens
end
Matches newlines, indents, and outdents, and determines which is which. If we can detect that the current line is continued onto the next line, then the newline is suppressed:
elements
.each( ... )
.map( ... )
Keeps track of the level of indentation, because a single outdent token can close multiple indents, so we need to know how far in we happen to be.
lineToken: ({chunk = @chunk, offset = 0} = {}) ->
return 0 unless match = MULTI_DENT.exec chunk
indent = match[0]
prev = @prev()
backslash = prev?[0] is '\\'
@seenFor = no unless (backslash or @seenFor?.endsLength < @ends.length) and @seenFor
@seenImport = no unless (backslash and @seenImport) or @importSpecifierList
@seenExport = no unless (backslash and @seenExport) or @exportSpecifierList
size = indent.length - 1 - indent.lastIndexOf '\n'
noNewlines = @unfinished()
newIndentLiteral = if size > 0 then indent[-size..] else ''
unless /^(.?)\1*$/.exec newIndentLiteral
@error 'mixed indentation', offset: indent.length
return indent.length
minLiteralLength = Math.min newIndentLiteral.length, @indentLiteral.length
if newIndentLiteral[...minLiteralLength] isnt @indentLiteral[...minLiteralLength]
@error 'indentation mismatch', offset: indent.length
return indent.length
if size - @continuationLineAdditionalIndent is @indent
if noNewlines then @suppressNewlines() else @newlineToken offset
return indent.length
if size > @indent
if noNewlines
@continuationLineAdditionalIndent = size - @indent unless backslash
if @continuationLineAdditionalIndent
prev.continuationLineIndent = @indent + @continuationLineAdditionalIndent
@suppressNewlines()
return indent.length
unless @tokens.length
@baseIndent = @indent = size
@indentLiteral = newIndentLiteral
return indent.length
diff = size - @indent + @outdebt
@token 'INDENT', diff, offset: offset + indent.length - size, length: size
@indents.push diff
@ends.push {tag: 'OUTDENT'}
@outdebt = @continuationLineAdditionalIndent = 0
@indent = size
@indentLiteral = newIndentLiteral
else if size < @baseIndent
@error 'missing indentation', offset: offset + indent.length
else
endsContinuationLineIndentation = @continuationLineAdditionalIndent > 0
@continuationLineAdditionalIndent = 0
@outdentToken {moveOut: @indent - size, noNewlines, outdentLength: indent.length, offset, indentSize: size, endsContinuationLineIndentation}
indent.length
Record an outdent token or multiple tokens, if we happen to be moving back inwards past several recorded indents. Sets new @indent value.
outdentToken: ({moveOut, noNewlines, outdentLength = 0, offset = 0, indentSize, endsContinuationLineIndentation}) ->
decreasedIndent = @indent - moveOut
while moveOut > 0
lastIndent =<EMAIL_ADDRESS>- 1]
if not lastIndent
@outdebt = moveOut = 0
else if @outdebt and moveOut <= @outdebt
@outdebt -= moveOut
moveOut = 0
else
dent = @indents.pop() + @outdebt
if outdentLength and @chunk[outdentLength] in INDENTABLE_CLOSERS
decreasedIndent -= dent - moveOut
moveOut = dent
@outdebt = 0
pair might call outdentToken, so preserve decreasedIndent
@pair 'OUTDENT'
@token 'OUTDENT', moveOut, length: outdentLength, indentSize: indentSize + moveOut - dent
moveOut -= dent
@outdebt -= moveOut if dent
@suppressSemicolons()
unless @tag() is 'TERMINATOR' or noNewlines
terminatorToken = @token 'TERMINATOR', '\n', offset: offset + outdentLength, length: 0
terminatorToken.endsContinuationLineIndentation = {preContinuationLineIndent: @indent} if endsContinuationLineIndentation
@indent = decreasedIndent
@indentLiteral = @indentLiteral[...decreasedIndent]
this
Matches and consumes non-meaningful whitespace. Tag the previous token as being “spaced”, because there are some cases where it makes a difference.
whitespaceToken: ->
return 0 unless (match = WHITESPACE.exec @chunk) or
(nline = @chunk.charAt(0) is '\n')
prev = @prev()
prev[if match then 'spaced' else 'newLine'] = true if prev
if match then match[0].length else 0
Generate a newline token. Consecutive newlines get merged together.
newlineToken: (offset) ->
@suppressSemicolons()
@token 'TERMINATOR', '\n', {offset, length: 0} unless @tag() is 'TERMINATOR'
this
Use a \
at a line-ending to suppress the newline.
The slash is removed here once its job is done.
suppressNewlines: ->
prev = @prev()
if prev[1] is '\\'
if prev.comments and @tokens.length > 1
@tokens.length
should be at least 2 (some code, then \
).
If something puts a \
after nothing, they deserve to lose any
comments that trail it.
attachCommentsToNode prev.comments<EMAIL_ADDRESS>- 2]
@tokens.pop()
this
jsxToken: ->
firstChar = @chunk[0]
Check the previous token to detect if attribute is spread.
prevChar = if @tokens.length > 0 then<EMAIL_ADDRESS>- 1][0] else ''
if firstChar is '<'
match =<EMAIL_ADDRESS>or<EMAIL_ADDRESS>return 0 unless match and (
@jsxDepth > 0 or
Not the right hand side of an unspaced comparison (i.e. a<b
).
not (prev = @prev()) or
prev.spaced or
prev[0] not in COMPARABLE_LEFT_SIDE
)
[input, id] = match
fullId = id
if '.' in id
[id, properties...] = id.split '.'
else
properties = []
tagToken = @token 'JSX_TAG', id,
length: id.length + 1
data:
openingBracketToken: @makeToken '<', '<'
tagNameToken: @makeToken 'IDENTIFIER', id, offset: 1
offset = id.length + 1
for property in properties
@token '.', '.', {offset}
offset += 1
@token 'PROPERTY', property, {offset}
offset += property.length
@token 'CALL_START', '(', generated: yes
@token '[', '[', generated: yes
@ends.push {tag: '/>', origin: tagToken, name: id, properties}
@jsxDepth++
return fullId.length + 1
else if jsxTag = @atJSXTag()
if @chunk[...2] is '/>' # Self-closing tag.
@pair '/>'
@token ']', ']',
length: 2
generated: yes
@token 'CALL_END', ')',
length: 2
generated: yes
data:
selfClosingSlashToken: @makeToken '/', '/'
closingBracketToken: @makeToken '>', '>', offset: 1
@jsxDepth--
return 2
else if firstChar is '{'
if prevChar is ':'
This token represents the start of a JSX attribute value
that’s an expression (e.g. the {b}
in <div a={b} />
).
Our grammar represents the beginnings of expressions as (
tokens, so make this into a (
token that displays as {
.
token = @token '(', '{'
@jsxObjAttribute[@jsxDepth] = no
tag attribute name as JSX
addTokenData<EMAIL_ADDRESS>- 3],
jsx: yes
else
token = @token '{', '{'
@jsxObjAttribute[@jsxDepth] = yes
@ends.push {tag: '}', origin: token}
return 1
else if firstChar is '>' # end of opening tag
Ignore terminators inside a tag.
{origin: openingTagToken} = @pair '/>' # As if the current tag was self-closing.
@token ']', ']',
generated: yes
data:
closingBracketToken: @makeToken '>', '>'
@token ',', 'JSX_COMMA', generated: yes
{tokens, index: end} =
@matchWithInterpolations INSIDE_JSX, '>', '</', JSX_INTERPOLATION
@mergeInterpolationTokens tokens, {endOffset: end, jsx: yes}, (value) =>
@validateUnicodeCodePointEscapes value, delimiter: '>'
match =<EMAIL_ADDRESS>or<EMAIL_ADDRESS>if not match or match[1] isnt "#{jsxTag.name}#{(".#{property}" for property in jsxTag.properties).join ''}"
@error "expected corresponding JSX closing tag for #{jsxTag.name}",
jsxTag.origin.data.tagNameToken[2]
[, fullTagName] = match
afterTag = end + fullTagName.length
if @chunk[afterTag] isnt '>'
@error "missing closing > after tag name", offset: afterTag, length: 1
-2/+2 for the opening </
and +1 for the closing >
.
endToken = @token 'CALL_END', ')',
offset: end - 2
length: fullTagName.length + 3
generated: yes
data:
closingTagOpeningBracketToken: @makeToken '<', '<', offset: end - 2
closingTagSlashToken: @makeToken '/', '/', offset: end - 1
TODO: individual tokens for complex tag name? eg < / A . B >
closingTagNameToken: @makeToken 'IDENTIFIER', fullTagName, offset: end
closingTagClosingBracketToken: @makeToken '>', '>', offset: end + fullTagName.length
make the closing tag location data more easily accessible to the grammar
addTokenData openingTagToken, endToken.data
@jsxDepth--
return afterTag + 1
else
return 0
else if @atJSXTag 1
if firstChar is '}'
@pair firstChar
if @jsxObjAttribute[@jsxDepth]
@token '}', '}'
@jsxObjAttribute[@jsxDepth] = no
else
@token ')', '}'
@token ',', ',', generated: yes
return 1
else
return 0
else
return 0
atJSXTag: (depth = 0) ->
return no if @jsxDepth is 0
i = @ends.length - 1
i-- while @ends[i]?.tag is 'OUTDENT' or depth-- > 0 # Ignore indents.
last = @ends[i]
last?.tag is '/>' and last
We treat all other single characters as a token. E.g.: ( ) , . !
Multi-character operators are also literal tokens, so that Jison can assign
the proper order of operations. There are some symbols that we tag specially
here. ;
and newlines are both treated as a TERMINATOR
, we distinguish
parentheses that indicate a method call from regular parentheses, and so on.
literalToken: ->
if match = OPERATOR.exec @chunk
[value] = match
@tagParameters() if CODE.test value
else
value = @chunk.charAt 0
tag = value
prev = @prev()
if prev and value in ['=', COMPOUND_ASSIGN...]
skipToken = false
if value is '=' and prev[1] in ['||', '&&'] and not prev.spaced
prev[0] = 'COMPOUND_ASSIGN'
prev[1] += '='
prev.data.original += '=' if prev.data?.original
prev[2].range = [
prev[2].range[0]
prev[2].range[1] + 1
]
prev[2].last_column += 1
prev[2].last_column_exclusive += 1
prev =<EMAIL_ADDRESS>- 2]
skipToken = true
if prev and prev[0] isnt 'PROPERTY'
origin = prev.origin ? prev
message = isUnassignable prev[1], origin[1]
@error message, origin[2] if message
return value.length if skipToken
if value is '(' and prev?[0] is 'IMPORT'
prev[0] = 'DYNAMIC_IMPORT'
if value is '{' and @seenImport
@importSpecifierList = yes
else if @importSpecifierList and value is '}'
@importSpecifierList = no
else if value is '{' and prev?[0] is 'EXPORT'
@exportSpecifierList = yes
else if @exportSpecifierList and value is '}'
@exportSpecifierList = no
if value is ';'
@error 'unexpected ;' if prev?[0] in ['=', UNFINISHED...]
@seenFor = @seenImport = @seenExport = no
tag = 'TERMINATOR'
else if value is '*' and prev?[0] is 'EXPORT'
tag = 'EXPORT_ALL'
else if value in MATH then tag = 'MATH'
else if value in COMPARE then tag = 'COMPARE'
else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
else if value in UNARY then tag = 'UNARY'
else if value in UNARY_MATH then tag = 'UNARY_MATH'
else if value in SHIFT then tag = 'SHIFT'
else if value is '?' and prev?.spaced then tag = 'BIN?'
else if prev
if value is '(' and not prev.spaced and prev[0] in CALLABLE
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
tag = 'CALL_START'
else if value is '[' and ((prev[0] in INDEXABLE and not prev.spaced) or
(prev[0] is '::')) # `.prototype` can’t be a method you can call.
tag = 'INDEX_START'
switch prev[0]
when '?' then prev[0] = 'INDEX_SOAK'
token = @makeToken tag, value
switch value
when '(', '{', '[' then @ends.push {tag: INVERSES[value], origin: token}
when ')', '}', ']' then @pair value
@tokens.push @makeToken tag, value
value.length
A source of ambiguity in our grammar used to be parameter lists in function definitions versus argument lists in function calls. Walk backwards, tagging parameters specially in order to make things easier for the parser.
tagParameters: ->
return @tagDoIife() if @tag() isnt ')'
stack = []
{tokens} = this
i = tokens.length
paramEndToken = tokens[--i]
paramEndToken[0] = 'PARAM_END'
while tok = tokens[--i]
switch tok[0]
when ')'
stack.push tok
when '(', 'CALL_START'
if stack.length then stack.pop()
else if tok[0] is '('
tok[0] = 'PARAM_START'
return @tagDoIife i - 1
else
paramEndToken[0] = 'CALL_END'
return this
this
Tag do
followed by a function differently than do
followed by eg an
identifier to allow for different grammar precedence
tagDoIife: (tokenIndex) ->
tok = @tokens[tokenIndex ? @tokens.length - 1]
return this unless tok?[0] is 'DO'
tok[0] = 'DO_IIFE'
this
Close up all remaining open blocks at the end of the file.
closeIndentation: ->
@outdentToken moveOut: @indent, indentSize: 0
Match the contents of a delimited token and expand variables and expressions inside it using Ruby-like notation for substitution of arbitrary expressions.
"Hello #{name.capitalize()}."
If it encounters an interpolation, this method will recursively create a new
Lexer and tokenize until the {
of #{
is balanced with a }
.
regex
matches the contents of a token (but not delimiter
, and not
#{
if interpolations are desired).delimiter
is the delimiter of the token. Examples are '
, "
, '''
,
"""
and ///
.closingDelimiter
is different from delimiter
only in JSXinterpolators
matches the start of an interpolation, for JSX it’s both
{
and <
(i.e. nested JSX tag)This method allows us to have strings within interpolations within strings, ad infinitum.
matchWithInterpolations: (regex, delimiter, closingDelimiter = delimiter, interpolators = /^#\{/) ->
tokens = []
offsetInChunk = delimiter.length
return null unless @chunk[...offsetInChunk] is delimiter
str = @chunk[offsetInChunk..]
loop
[strPart] = regex.exec str
@validateEscapes strPart, {isRegex: delimiter.charAt(0) is '/', offsetInChunk}
Push a fake 'NEOSTRING'
token, which will get turned into a real string later.
tokens.push @makeToken 'NEOSTRING', strPart, offset: offsetInChunk
str = str[strPart.length..]
offsetInChunk += strPart.length
break unless match = interpolators.exec str
[interpolator] = match
To remove the #
in #{
.
interpolationOffset = interpolator.length - 1
[line, column, offset] = @getLineAndColumnFromChunk offsetInChunk + interpolationOffset
rest = str[interpolationOffset..]
{tokens: nested, index} =
new Lexer().tokenize rest, {line, column, offset, untilBalanced: on, @locationDataCompensations}
Account for the #
in #{
.
index += interpolationOffset
braceInterpolator = str[index - 1] is '}'
if braceInterpolator
Turn the leading and trailing {
and }
into parentheses. Unnecessary
parentheses will be removed later.
[open, ..., close] = nested
open[0] = 'INTERPOLATION_START'
open[1] = '('
open[2].first_column -= interpolationOffset
open[2].range = [
open[2].range[0] - interpolationOffset
open[2].range[1]
]
close[0] = 'INTERPOLATION_END'
close[1] = ')'
close.origin = ['', 'end of interpolation', close[2]]
Remove leading 'TERMINATOR'
(if any).
nested.splice 1, 1 if nested[1]?[0] is 'TERMINATOR'
Remove trailing 'INDENT'/'OUTDENT'
pair (if any).
nested.splice -3, 2 if nested[nested.length - 3]?[0] is 'INDENT' and nested[nested.length - 2][0] is 'OUTDENT'
unless braceInterpolator
We are not using {
and }
, so wrap the interpolated tokens instead.
open = @makeToken 'INTERPOLATION_START', '(', offset: offsetInChunk, length: 0, generated: yes
close = @makeToken 'INTERPOLATION_END', ')', offset: offsetInChunk + index, length: 0, generated: yes
nested = [open, nested..., close]
Push a fake 'TOKENS'
token, which will get turned into real tokens later.
tokens.push ['TOKENS', nested]
str = str[index..]
offsetInChunk += index
unless str[...closingDelimiter.length] is closingDelimiter
@error "missing #{closingDelimiter}", length: delimiter.length
{tokens, index: offsetInChunk + closingDelimiter.length}
Merge the array tokens
of the fake token types 'TOKENS'
and 'NEOSTRING'
(as returned by matchWithInterpolations
) into the token stream. The value
of 'NEOSTRING'
s are converted using fn
and turned into strings using
options
first.
mergeInterpolationTokens: (tokens, options, fn) ->
{quote, indent, double, heregex, endOffset, jsx} = options
if tokens.length > 1
lparen = @token 'STRING_START', '(', length: quote?.length ? 0, data: {quote}, generated: not quote?.length
firstIndex = @tokens.length
$ = tokens.length - 1
for token, i in tokens
[tag, value] = token
switch tag
when 'TOKENS'
There are comments (and nothing else) in this interpolation.
if value.length is 2 and (value[0].comments or value[1].comments)
placeholderToken = @makeToken 'JS', '', generated: yes
Use the same location data as the first parenthesis.
placeholderToken[2] = value[0][2]
for val in value when val.comments
placeholderToken.comments ?= []
placeholderToken.comments.push val.comments...
value.splice 1, 0, placeholderToken
Push all the tokens in the fake 'TOKENS'
token. These already have
sane location data.
locationToken = value[0]
tokensToPush = value
when 'NEOSTRING'
Convert 'NEOSTRING'
into 'STRING'
.
converted = fn.call this, token[1], i
addTokenData token, initialChunk: yes if i is 0
addTokenData token, finalChunk: yes if i is $
addTokenData token, {indent, quote, double}
addTokenData token, {heregex} if heregex
addTokenData token, {jsx} if jsx
token[0] = 'STRING'
token[1] = '"' + converted + '"'
if tokens.length is 1 and quote?
token[2].first_column -= quote.length
if token[1].substr(-2, 1) is '\n'
token[2].last_line += 1
token[2].last_column = quote.length - 1
else
token[2].last_column += quote.length
token[2].last_column -= 1 if token[1].length is 2
token[2].last_column_exclusive += quote.length
token[2].range = [
token[2].range[0] - quote.length
token[2].range[1] + quote.length
]
locationToken = token
tokensToPush = [token]
@tokens.push tokensToPush...
if lparen
[..., lastToken] = tokens
lparen.origin = ['STRING', null,
first_line: lparen[2].first_line
first_column: lparen[2].first_column
last_line: lastToken[2].last_line
last_column: lastToken[2].last_column
last_line_exclusive: lastToken[2].last_line_exclusive
last_column_exclusive: lastToken[2].last_column_exclusive
range: [
lparen[2].range[0]
lastToken[2].range[1]
]
]
lparen[2] = lparen.origin[2] unless quote?.length
rparen = @token 'STRING_END', ')', offset: endOffset - (quote ? '').length, length: quote?.length ? 0, generated: not quote?.length
Pairs up a closing token, ensuring that all listed pairs of tokens are correctly balanced throughout the course of the token stream.
pair: (tag) ->
[..., prev] = @ends
unless tag is wanted = prev?.tag
@error "unmatched #{tag}" unless 'OUTDENT' is wanted
[..., lastIndent] = @indents
@outdentToken moveOut: lastIndent, noNewlines: true
return @pair tag
@ends.pop()
Compensate for the things we strip out initially (e.g. carriage returns) so that location data stays accurate with respect to the original source file.
getLocationDataCompensation: (start, end) ->
totalCompensation = 0
initialEnd = end
current = start
while current <= end
break if current is end and start isnt initialEnd
compensation = @locationDataCompensations[current]
if compensation?
totalCompensation += compensation
end += compensation
current++
return totalCompensation
Returns the line and column number from an offset into the current chunk.
offset
is a number of characters into @chunk
.
getLineAndColumnFromChunk: (offset) ->
compensation = @getLocationDataCompensation @chunkOffset, @chunkOffset + offset
if offset is 0
return [@chunkLine, @chunkColumn + compensation, @chunkOffset + compensation]
if offset >= @chunk.length
string = @chunk
else
string = @chunk[..offset-1]
lineCount = count string, '\n'
column = @chunkColumn
if lineCount > 0
[..., lastLine] = string.split '\n'
column = lastLine.length
previousLinesCompensation = @getLocationDataCompensation @chunkOffset, @chunkOffset + offset - column
Don’t recompensate for initially inserted newline.
previousLinesCompensation = 0 if previousLinesCompensation < 0
columnCompensation = @getLocationDataCompensation(
@chunkOffset + offset + previousLinesCompensation - column
@chunkOffset + offset + previousLinesCompensation
)
else
column += string.length
columnCompensation = compensation
[@chunkLine + lineCount, column + columnCompensation, @chunkOffset + offset + compensation]
makeLocationData: ({ offsetInChunk, length }) ->
locationData = range: []
[locationData.first_line, locationData.first_column, locationData.range[0]] =
@getLineAndColumnFromChunk offsetInChunk
Use length - 1 for the final offset - we’re supplying the last_line and the last_column, so if last_column == first_column, then we’re looking at a character of length 1.
lastCharacter = if length > 0 then (length - 1) else 0
[locationData.last_line, locationData.last_column, endOffset] =
@getLineAndColumnFromChunk offsetInChunk + lastCharacter
[locationData.last_line_exclusive, locationData.last_column_exclusive] =
@getLineAndColumnFromChunk offsetInChunk + lastCharacter + (if length > 0 then 1 else 0)
locationData.range[1] = if length > 0 then endOffset + 1 else endOffset
locationData
Same as token
, except this just returns the token without adding it
to the results.
makeToken: (tag, value, {offset: offsetInChunk = 0, length = value.length, origin, generated, indentSize} = {}) ->
token = [tag, value, @makeLocationData {offsetInChunk, length}]
token.origin = origin if origin
token.generated = yes if generated
token.indentSize = indentSize if indentSize?
token
Add a token to the results.
offset
is the offset into the current @chunk
where the token starts.
length
is the length of the token in the @chunk
, after the offset. If
not specified, the length of value
will be used.
Returns the new token.
token: (tag, value, {offset, length, origin, data, generated, indentSize} = {}) ->
token = @makeToken tag, value, {offset, length, origin, generated, indentSize}
addTokenData token, data if data
@tokens.push token
token
Peek at the last tag in the token stream.
tag: ->
[..., token] = @tokens
token?[0]
Peek at the last value in the token stream.
value: (useOrigin = no) ->
[..., token] = @tokens
if useOrigin and token?.origin?
token.origin[1]
else
token?[1]
Get the previous token in the token stream.
prev: ->
<EMAIL_ADDRESS>- 1]
Are we in the midst of an unfinished expression?
unfinished: ->
LINE_CONTINUER.test(@chunk) or
@tag() in UNFINISHED
validateUnicodeCodePointEscapes: (str, options) ->
replaceUnicodeCodePointEscapes str, merge options, {@error}
Validates escapes in strings and regexes.
validateEscapes: (str, options = {}) ->
invalidEscapeRegex =
if options.isRegex
REGEX_INVALID_ESCAPE
else
STRING_INVALID_ESCAPE
match = invalidEscapeRegex.exec str
return unless match
[[], before, octal, hex, unicodeCodePoint, unicode] = match
message =
if octal
"octal escape sequences are not allowed"
else
"invalid escape sequence"
invalidEscape = "\\#{octal or hex or unicodeCodePoint or unicode}"
@error "#{message} #{invalidEscape}",
offset: (options.offsetInChunk ? 0) + match.index + before.length
length: invalidEscape.length
suppressSemicolons: ->
while @value() is ';'
@tokens.pop()
@error 'unexpected ;' if @prev()?[0] in ['=', UNFINISHED...]
Throws an error at either a given offset from the current chunk or at the
location of a token (token[2]
).
error: (message, options = {}) =>
location =
if 'first_line' of options
options
else
[first_line, first_column] = @getLineAndColumnFromChunk options.offset ? 0
{first_line, first_column, last_column: first_column + (options.length ? 1) - 1}
throwSyntaxError message, location
isUnassignable = (name, displayName = name) -> switch
when name in [JS_KEYWORDS..., COFFEE_KEYWORDS...]
"keyword '#{displayName}' can't be assigned"
when name in STRICT_PROSCRIBED
"'#{displayName}' can't be assigned"
when name in RESERVED
"reserved word '#{displayName}' can't be assigned"
else
false
exports.isUnassignable = isUnassignable
from
isn’t a CoffeeScript keyword, but it behaves like one in import
and
export
statements (handled above) and in the declaration line of a for
loop. Try to detect when from
is a variable identifier and when it is this
“sometimes” keyword.
isForFrom = (prev) ->
for i from iterable
if prev[0] is 'IDENTIFIER'
yes
for from…
else if prev[0] is 'FOR'
no
for {from}…
, for [from]…
, for {a, from}…
, for {a: from}…
else if prev[1] in ['{', '[', ',', ':']
no
else
yes
addTokenData = (token, data) ->
Object.assign (token.data ?= {}), data
Keywords that CoffeeScript shares in common with JavaScript.
JS_KEYWORDS = [
'true', 'false', 'null', 'this'
'new', 'delete', 'typeof', 'in', 'instanceof'
'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'await'
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
'class', 'extends', 'super'
'import', 'export', 'default'
]
CoffeeScript-only keywords.
COFFEE_KEYWORDS = [
'undefined', 'Infinity', 'NaN'
'then', 'unless', 'until', 'loop', 'of', 'by', 'when'
]
COFFEE_ALIAS_MAP =
and : '&&'
or : '||'
is : '=='
isnt : '!='
not : '!'
yes : 'true'
no : 'false'
on : 'true'
off : 'false'
COFFEE_ALIASES = (key for key of COFFEE_ALIAS_MAP)
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
The list of keywords that are reserved by JavaScript, but not used, or are used by CoffeeScript internally. We throw an error when these are encountered, to avoid having a JavaScript error at runtime.
RESERVED = [
'case', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
'native', 'implements', 'interface', 'package', 'private'
'protected', 'public', 'static'
]
STRICT_PROSCRIBED = ['arguments', 'eval']
The superset of both JavaScript keywords and reserved words, none of which may be used as identifiers or properties.
exports.JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED)
The character code of the nasty Microsoft madness otherwise known as the BOM.
BOM = 65279
Token matching regexes.
IDENTIFIER = /// ^
(?!\d)
( (?: (?!\s)[$\w\x7f-\uffff] )+ )
( [^\n\S]* : (?!:) )? # Is this a property name?
///
Like IDENTIFIER
, but includes -
s
JSX_IDENTIFIER_PART = /// (?: (?!\s)[\-$\w\x7f-\uffff] )+ ///.source
In https://facebook.github.io/jsx/ spec, JSXElementName can be
JSXIdentifier, JSXNamespacedName (JSXIdentifier : JSXIdentifier), or
JSXMemberExpression (two or more JSXIdentifier connected by .
s).
JSX_IDENTIFIER = /// ^
(?![\d<]) # Must not start with `<`.
( #{JSX_IDENTIFIER_PART}
(?: \s* : \s* #{JSX_IDENTIFIER_PART} # JSXNamespacedName
| (?: \s* \. \s* #{JSX_IDENTIFIER_PART} )+ # JSXMemberExpression
)? )
///
Fragment: <></>
JSX_FRAGMENT_IDENTIFIER = /// ^
()> # Ends immediately with `>`.
///
In https://facebook.github.io/jsx/ spec, JSXAttributeName can be either JSXIdentifier or JSXNamespacedName which is JSXIdentifier : JSXIdentifier
JSX_ATTRIBUTE = /// ^
(?!\d)
( #{JSX_IDENTIFIER_PART}
(?: \s* : \s* #{JSX_IDENTIFIER_PART} # JSXNamespacedName
)? )
( [^\S]* = (?!=) )? # Is this an attribute with a value?
///
NUMBER = ///
^ 0b[01](?:_?[01])*n? | # binary
^ 0o[0-7](?:_?[0-7])*n? | # octal
^ 0x[\da-f](?:_?[\da-f])*n? | # hex
^ \d+(?:_\d+)*n | # decimal bigint
^ (?:\d+(?:_\d+)*)? \.? \d+(?:_\d+)* # decimal
(?:e[+-]? \d+(?:_\d+)* )?
decimal without support for numeric literal separators for reference: \d*.?\d+ (?:e[+-]?\d+)?
///i
OPERATOR = /// ^ (
?: [-=]> # function
| [-+*/%<>&|^!?=]= # compound assign / compare
| >>>=? # zero-fill right shift
| ([-+:])\1 # doubles
| ([&|<>*/%])\2=? # logic / shift / power / floor division / modulo
| \?(\.|::) # soak access
| \.{2,3} # range or splat
) ///
WHITESPACE = /^[^\n\S]+/
COMMENT = /^(\s*)###([^#][\s\S]*?)(?:###([^\n\S]*)|###$)|^((?:\s*#(?!##[^#]).*)+)/
CODE = /^[-=]>/
MULTI_DENT = /^(?:\n[^\n\S]*)+/
JSTOKEN = ///^ `(?!``) ((?: [^`\\] | \\[\s\S] )*) ` ///
HERE_JSTOKEN = ///^ ``` ((?: [^`\\] | \\[\s\S] | `(?!``) )*) ``` ///
String-matching-regexes.
STRING_START = /^(?:'''|"""|'|")/
STRING_SINGLE = /// ^(?: [^\\'] | \\[\s\S] )* ///
STRING_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | \#(?!\{) )* ///
HEREDOC_SINGLE = /// ^(?: [^\\'] | \\[\s\S] | '(?!'') )* ///
HEREDOC_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | "(?!"") | \#(?!\{) )* ///
INSIDE_JSX = /// ^(?:
[^
\{ # Start of CoffeeScript interpolation.
< # Maybe JSX tag (`<` not allowed even if bare).
]
)* /// # Similar to `HEREDOC_DOUBLE` but there is no escaping.
JSX_INTERPOLATION = /// ^(?:
\{ # CoffeeScript interpolation.
| <(?!/) # JSX opening tag.
)///
HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g
Regex-matching-regexes.
REGEX = /// ^
/ (?!/) ((
?: [^ [ / \n \\ ] # Every other thing.
| \\[^\n] # Anything but newlines escaped.
| \[ # Character class.
(?: \\[^\n] | [^ \] \n \\ ] )*
\]
)*) (/)?
///
REGEX_FLAGS = /^\w*/
VALID_FLAGS = /^(?!.*(.).*\1)[gimsuy]*$/
HEREGEX = /// ^
(?:
Match any character, except those that need special handling below.
[^\\/#\s]
Match \
followed by any character.
| \\[\s\S]
Match any /
except ///
.
| /(?!//)
Match #
which is not part of interpolation, e.g. #{}
.
| \#(?!\{)
Comments consume everything until the end of the line, including ///
.
| \s+(?:#(?!\{).*)?
)*
///
HEREGEX_COMMENT = /(\s+)(#(?!{).*)/gm
REGEX_ILLEGAL = /// ^ ( / | /{3}\s*) (\*) ///
POSSIBLY_DIVISION = /// ^ /=?\s ///
Other regexes.
HERECOMMENT_ILLEGAL = /\*\//
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | \??:: ) ///
STRING_INVALID_ESCAPE = ///
( (?:^|[^\\]) (?:\\\\)* ) # Make sure the escape isn’t escaped.
\\ (
?: (0\d|[1-7]) # octal escape
| (x(?![\da-fA-F]{2}).{0,2}) # hex escape
| (u\{(?![\da-fA-F]{1,}\})[^}]*\}?) # unicode code point escape
| (u(?!\{|[\da-fA-F]{4}).{0,4}) # unicode escape
)
///
REGEX_INVALID_ESCAPE = ///
( (?:^|[^\\]) (?:\\\\)* ) # Make sure the escape isn’t escaped.
\\ (
?: (0\d) # octal escape
| (x(?![\da-fA-F]{2}).{0,2}) # hex escape
| (u\{(?![\da-fA-F]{1,}\})[^}]*\}?) # unicode code point escape
| (u(?!\{|[\da-fA-F]{4}).{0,4}) # unicode escape
)
///
TRAILING_SPACES = /\s+$/
Compound assignment tokens.
COMPOUND_ASSIGN = [
'-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>='
'&=', '^=', '|=', '**=', '//=', '%%='
]
Unary tokens.
UNARY = ['NEW', 'TYPEOF', 'DELETE']
UNARY_MATH = ['!', '~']
Bit-shifting tokens.
SHIFT = ['<<', '>>', '>>>']
Comparison tokens.
COMPARE = ['==', '!=', '<', '>', '<=', '>=']
Mathematical tokens.
MATH = ['*', '/', '%', '//', '%%']
Relational tokens that are negatable with not
prefix.
RELATION = ['IN', 'OF', 'INSTANCEOF']
Boolean tokens.
BOOL = ['TRUE', 'FALSE']
Tokens which could legitimately be invoked or indexed. An opening parentheses or bracket following these tokens will be recorded as the start of a function invocation or indexing operation.
CALLABLE = ['IDENTIFIER', 'PROPERTY', ')', ']', '?', '@', 'THIS', 'SUPER', 'DYNAMIC_IMPORT']
INDEXABLE = CALLABLE.concat [
'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END'
'BOOL', 'NULL', 'UNDEFINED', '}', '::'
]
Tokens which can be the left-hand side of a less-than comparison, i.e. a<b
.
COMPARABLE_LEFT_SIDE = ['IDENTIFIER', ')', ']', 'NUMBER']
Tokens which a regular expression will never immediately follow (except spaced CALLABLEs in some cases), but which a division operator can.
See: http://www-archive.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
NOT_REGEX = INDEXABLE.concat ['++', '--']
Tokens that, when immediately preceding a WHEN
, indicate that the WHEN
occurs at the start of a line. We disambiguate these from trailing whens to
avoid an ambiguity in the grammar.
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
Additional indent in front of these is ignored.
INDENTABLE_CLOSERS = [')', '}', ']']


How to play: Use your arrow keys to move the tiles. When two tiles with the same number touch, they merge into one! You win if you make a tile with the value 2048. You lose if the board gets full and you have no more valid moves.
Board Size: You can set the dimensions of the board by entering a number from 3-10 in the Board Size text box and clicking Submit.
Extra Life: Merge two extra life tiles to gain an extra life. In case you lose, a life will automatically be spent to clear some of the board and you will be able to continue the game.
Explode: Merge two explode tiles to get a bomb item. Click on the bomb item, then click anywehere on the board to explode a 3x3 area of tiles.
Trim: Merge two trim tiles to get a trim item. Click on the trim item to remove all tiles with values of 2 or 4 from the board.
Next Tile: Each turn, you are shown a preview of the next tile that will be added to the board after you make your next move.
Held Tile: Click Hold to save the Next Tile for later. After waiting at least 3 turns, you can click Hold, then click anywhere on the board to play the held tile onto the board.
This site is made by Akila Kavisinghe, Hassan Jasim, and Jordan Levy for the McMaster University SFWRENG 3XA3 course. Based on 2048 by Gabriele Cirulli.


An e-commerce website selling various tour products, such as tour packages and portable wifi routers.
Check it outAn admin portal for management of chatbot users from various platform such as Facebook, Wechat and AI chat widget
Check it outA webview for chatbot users to collect their needs for itinerary, restaurants and etc.
Check it outAn admin portal for management of bookings and orders by the e-commerce website users
Check it outThe representitive website for introduction of TravelFlan (Partial page implementations and maintenance)
Check it out2018 Asia Open Data Hackathon 2nd place awarded app. It provides searching for nearby lavatories and hospitals, routes from user's location
Check it outA Google Maps API navigation demo originally made for a project with Google Korea. TTS(Text to speech), STT(Speech to text) are supported. Navigation function, get current position button, autocomplete, finding nearby gas stations are included
Check it outA map showing 100 markers on the map for asset tracking.
Check it outA website for social discussion with numerous APIs and libraries. R used for visualization and NodeJS used for async chat. Not officially distributed.
Check it out


We’re sorry our doctor speak English is not enrolled in clinic.
If you are unable to speak Japanese, it may be difficult for you to convey appropriate treatment.
Thank you for your understanding.
If you find English-speaking doc,you can find of Most local governments provide a database of local hospitals and clinics online.
Do you have Japanese insurance? if you don't enrolled in Japanese insulance,we recomended to enroll in Japanese health insurance.Becouse Japanese hospitals and clinic do not accept often.


Liam Payne says new love with Maya Henry is 'real' as he hints past with Cheryl was 'horrendous'
Cheryl Tweedy might want to look away as the former One Direction star reveals 'F***ing s*** got real' with 'best friend' model Maya Henry
by Halina Watts, https://www.mirror.co.uk/authors/halina-watts/Ouch, Cheryl, you might want to look away! Your ex Liam Payne has been opening up about his new love, US model Maya Henry – and it could make grim reading...
The ex-One Direction singer says his romantic past has been “super-horrendous”.
And he appeared to suggest that former Girls Aloud star Cheryl wasn’t the real deal... even though they have a little one together.
Liam says: “I’m really happy right now and things are good. Being in love, how would I describe that? F***ing s*** got real.
"Now that I’ve found someone who’s genuinely my best friend as well as my partner, it’s massively changed things for me.
"She’s just so relaxed about everything. Someone who’s completely got your back with everything is just the wildest thing. I don’t think I’ve really experienced that before in someone.”
Liam, 26, split with Cheryl, 36, in July 2018. They have two-year-old son Bear together.
And he confessed that with “love and relationships” his past has “been super-horrendous so far”, adding: “Honestly, with love, I think you don’t really understand it until it gives you that sting.
“It took a long time for me, something really hurt me, and it made me really appreciate love and people a lot more.”
Speaking about him and Cheryl now, he says: “We’ve put Bear at the forefront. I think we’ve managed to do quite a good job of it so far.”
Over to you, Cheryl!


The Verify Auth Token API lets you verify that a user is signed in to Userbase. This is useful if you want the user to interact with a service separate from Userbase, such as another database, or only serve content to authenticated users for example. It returns successfully if the user is signed in.
curl 'https://v1.userbase.com/v1/admin/auth-tokens/$AUTH_TOKEN' \
-XGET \
-H 'Authorization: Bearer $ACCESS_TOKEN'


Home
The Sales
The Store
order processing
Cookies Stand Company
cookie stand project
Added New Cookie Stand City
City Name Of Cookies
Amman
Cairo
Jaddah
London
Jaddah
Abu Dabi
Alexandria
Aurora
Austin
Orlando
Phoenix
Savannah
Madison
Dayton
Dallas
Texas
Enter Minumum Cookies (between 1 and 25):
Enter Maximum Cookies (between 1 and 100):
Enter The Average Of Cookies (between 1.0 and 10.0):


win 134 src/main.c SDL_Window_Access win; win 172 src/main.c win = SDL_CreateWindow(GAME_TITLE, 0, 0, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); win 173 src/main.c render = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); win 200 src/main.c SDL_DestroyWindow(win);


| highlightUi {rstudioapi} | R Documentation |
This function can be used to highlight UI elements within the RStudio IDE. UI elements can be selected using query selectors; most commonly, one should choose to highlight elements based on their IDs when available.
highlightUi(queries)
queries |
A list of "query" objects. Each query should be a list with
entries |
The tool at:
Help -> Diagnostics -> Show DOM Elements
can be useful for identifying the classes and IDs assigned to the different elements within RStudio.
Elements are selected using the same queries as through the web
querySelectorAll()
API. See
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
for more details.
For example, to highlight the Save icon within the Source pane, one might use:
rstudioapi::highlightUi("#rstudio_tb_savesourcedoc")
In some cases, multiple UI elements need to be highlighted – e.g. if you
want to highlight both a menu button, and a menu item within the menu
displayed after the button is pressed. We'll use the Environment Pane's
Import Dataset button as an example. To highlight the From Text
(readr)
command, you might use:
rstudioapi::highlightUi( list( list(query = "#rstudio_mb_import_dataset", parent = 0L), list(query = "#rstudio_label_from_text_readr_command", parent = 1L) ) )
The highlightUi
function was introduced in RStudio 1.3.658.
## Not run: rstudioapi::highlightUi("#rstudio_workbench_panel_git") # clear current highlights ## Not run: rstudioapi::highlightUi("") # highlight within an RMD ## Not run: rstudioapi::highlightUi(".rstudio_chunk_setup .rstudio_run_chunk") # Optionally provide a callback adjacent to # the queries that will be executed when the # highlighted element is clicked on. ## Not run: rstudioapi::highlightUi( list( list( query="#rstudio_workbench_panel_git", callback="rstudioapi::highlightUi('')" ) ) ) ## End(Not run)


XLSATOMS(1) XLSATOMS(1) NAME xlsatoms - list interned atoms defined on server SYNOPSIS xlsatoms [-options ...] DESCRIPTION Xlsatoms lists the interned atoms. By default, all atoms starting from 1 (the lowest atom value defined by the protocol) are listed until unknown atom is found. If an explicit range is given, xlsatoms will try all atoms in the range, regardless of whether or not any are undefined. OPTIONS -display dpy This option specifies the X server to which to connect. -format string This option specifies a printf-style string used to list each atom <value,name> pair, printed in that order (value is an unsigned long and name is a char *). Xlsatoms will supply a new‐ line at the end of each line. The default is %ld\t%s. -range [low]-[high] This option specifies the range of atom values to check. If low is not given, a value of 1 assumed. If high is not given, xlsatoms will stop at the first undefined atom at or above low. -name string This option specifies the name of an atom to list. If the atom does not exist, a message will be printed on the standard error. SEE ALSO X(7), Xserver(1), xprop(1) ENVIRONMENT DISPLAY to get the default host and display to use. AUTHOR Jim Fulton, MIT X Consortium X Version 11 xlsatoms 1.1.1 XLSATOMS(1)


| Project Status (09/20/2012 - 12:06:23) | |||
| Project File: | system.xmp | Implementation State: | Programming File Generated |
| Module Name: | system |
|
No Errors |
| Product Version: | EDK 14.1 |
|
293 Warnings (38 new) |
| XPS Reports | [-] | ||||
| Report Name | Generated | Errors | Warnings | Infos | |
| Platgen Log File | Thu Sep 20 11:58:26 2012 | 0 | 0 | 24 Infos (1 new) | |
| Simgen Log File | Fri Aug 10 16:21:46 2012 | 0 | 32 Warnings (32 new) | 22 Infos (22 new) | |
| BitInit Log File | |||||
| System Log File | Thu Sep 20 12:06:17 2012 |
| XPS Synthesis Summary (estimated values) | [-] | |||||
| Report | Generated | Flip Flops Used | LUTs Used | BRAMS Used | Errors | |
| system | Thu Sep 20 11:59:06 2012 | 9704 | 13292 | 47 | 0 | |
| system_xps_bram_if_cntlr_1_wrapper | Thu Sep 20 11:58:18 2012 | 156 | 160 | 0 | ||
| system_riffa_0_wrapper | Thu Sep 20 11:58:10 2012 | 415 | 825 | 0 | ||
| system_simpbus_mst_plbv46_adapter_0_wrapper | Thu Sep 20 11:57:59 2012 | 159 | 95 | 0 | ||
| system_simpbus_slv_plbv46_adapter_0_wrapper | Thu Sep 20 11:57:52 2012 | 181 | 52 | 0 | ||
| system_central_notifier_0_wrapper | Thu Sep 20 11:57:44 2012 | 416 | 2252 | 1 | 0 | |
| system_clock_generator_0_wrapper | Thu Sep 20 11:57:21 2012 | 1 | 0 | |||
| system_bram_block_1_wrapper | Tue Sep 4 17:58:57 2012 | 16 | 0 | |||
| system_riffa_example_0_wrapper | Tue Sep 4 17:58:46 2012 | 76 | 78 | 0 | ||
| system_xps_central_dma_0_wrapper | Tue Sep 4 17:57:45 2012 | 562 | 713 | 0 | ||
| system_mb_plb_wrapper | Tue Sep 4 17:57:22 2012 | 163 | 445 | 0 | ||
| system_xps_bram_if_cntlr_0_wrapper | Fri Aug 31 10:45:27 2012 | 156 | 160 | 0 | ||
| system_bram_block_0_wrapper | Fri Aug 31 10:45:19 2012 | 16 | 0 | |||
| system_proc_sys_reset_0_wrapper | Fri Aug 31 10:44:49 2012 | 69 | 53 | 0 | ||
| system_pcie_bridge_wrapper | Fri Aug 31 10:44:11 2012 | 7006 | 8263 | 9 | 0 | |
| system_pcie_bridge_wrapper_fifo_generator_v4_3_fifo_generator_v4_3_xst_1 | Fri Aug 31 10:42:16 2012 | 61 | 96 | 0 |
| Device Utilization Summary (actual values) | [-] | ||||
| Slice Logic Utilization | Used | Available | Utilization | Note(s) | |
| Number of Slice Registers | 9,408 | 69,120 | 13% | ||
| Number used as Flip Flops | 9,407 | ||||
| Number used as Latches | 1 | ||||
| Number of Slice LUTs | 11,868 | 69,120 | 17% | ||
| Number used as logic | 11,492 | 69,120 | 16% | ||
| Number using O6 output only | 10,279 | ||||
| Number using O5 output only | 268 | ||||
| Number using O5 and O6 | 945 | ||||
| Number used as Memory | 337 | 17,920 | 1% | ||
| Number used as Dual Port RAM | 90 | ||||
| Number using O6 output only | 6 | ||||
| Number using O5 and O6 | 84 | ||||
| Number used as Shift Register | 247 | ||||
| Number using O6 output only | 247 | ||||
| Number used as exclusive route-thru | 39 | ||||
| Number of route-thrus | 331 | ||||
| Number using O6 output only | 304 | ||||
| Number using O5 output only | 25 | ||||
| Number using O5 and O6 | 2 | ||||
| Number of occupied Slices | 5,601 | 17,280 | 32% | ||
| Number of LUT Flip Flop pairs used | 14,938 | ||||
| Number with an unused Flip Flop | 5,530 | 14,938 | 37% | ||
| Number with an unused LUT | 3,070 | 14,938 | 20% | ||
| Number of fully used LUT-FF pairs | 6,338 | 14,938 | 42% | ||
| Number of unique control sets | 951 | ||||
| Number of slice register sites lost to control set restrictions |
2,175 | 69,120 | 3% | ||
| Number of bonded IOBs | 2 | 640 | 1% | ||
| Number of LOCed IOBs | 2 | 2 | 100% | ||
| IOB Flip Flops | 1 | ||||
| Number of bonded IPADs | 4 | ||||
| Number of LOCed IPADs | 4 | 4 | 100% | ||
| Number of bonded OPADs | 2 | ||||
| Number of LOCed OPADs | 2 | 2 | 100% | ||
| Number of BlockRAM/FIFO | 48 | 148 | 32% | ||
| Number using BlockRAM only | 48 | ||||
| Number of 36k BlockRAM used | 42 | ||||
| Number of 18k BlockRAM used | 8 | ||||
| Total Memory used (KB) | 1,656 | 5,328 | 31% | ||
| Number of BUFG/BUFGCTRLs | 4 | 32 | 12% | ||
| Number used as BUFGs | 4 | ||||
| Number of BUFDSs | 1 | 8 | 12% | ||
| Number of GTP_DUALs | 1 | 8 | 12% | ||
| Number of PCIEs | 1 | 1 | 100% | ||
| Number of PLL_ADVs | 2 | 6 | 33% | ||
| Average Fanout of Non-Clock Nets | 4.28 |
| Performance Summary | [-] | |||
| Final Timing Score: | 0 (Setup: 0, Hold: 0, Component Switching Limit: 0) | Pinout Data: | Pinout Report | |
| Routing Results: | All Signals Completely Routed | Clock Data: | Clock Report | |
| Timing Constraints: | All Constraints Met |
| Detailed Reports | [-] | |||||
| Report Name | Status | Generated | Errors | Warnings | Infos | |
| Translation Report | Current | Thu Sep 20 11:59:28 2012 | 0 | 64 Warnings (0 new) | 1 Info (1 new) | |
| Map Report | Current | Thu Sep 20 12:02:50 2012 | 0 | 147 Warnings (0 new) | 963 Infos (119 new) | |
| Place and Route Report | Current | Thu Sep 20 12:04:52 2012 | 0 | 77 Warnings (38 new) | 0 | |
| Post-PAR Static Timing Report | Current | Thu Sep 20 12:05:15 2012 | 0 | 0 | 3 Infos (0 new) | |
| Bitgen Report | Current | Thu Sep 20 12:06:17 2012 | 0 | 5 Warnings (0 new) | 0 |
| Secondary Reports | [-] | ||
| Report Name | Status | Generated | |
| WebTalk Report | Out of Date | Tue Sep 4 18:07:28 2012 | |
| WebTalk Log File | Out of Date | Tue Sep 4 18:07:29 2012 |


ML-Ensemble
| author: | Sebastian Flennerhag |
|---|---|
| copyright: | 2017-2018 |
| license: | MIT |
Model selection suite for ensemble learning.
Implements computational graph framework for maximally parallelized cross-validation of an arbitrary set of estimators over an arbitrary set of preprocessing pipelines. Model selection suite features batch randomized grid search and batch benchmarking. Ensembles can be treated as preprocessing pipelines for next-layer model selection.
mlens.model_selection¶
BaseEval¶
-
class
mlens.model_selection.
BaseEval
(verbose=False, array_check=None, **kwargs)[source]¶ Bases:
mlens.parallel.base.IndexMixin
,mlens.parallel.base.BaseBackend
Base Evaluation class.
-
raw_data
¶ Cross validated scores
-
Evaluator¶
-
class
mlens.model_selection.
Evaluator
(scorer, cv=2, shuffle=True, random_state=None, error_score=None, metrics=None, verbose=False, **kwargs)[source]¶ Bases:
mlens.model_selection.model_selection.BaseEval
Model selection across several estimators and preprocessing pipelines.
The
Evaluator
allows users to evaluate several models in one call across a set preprocessing pipelines. The class is useful for comparing a set of estimators, especially when several preprocessing pipelines is to be evaluated. By pre-making all folds and iteratively fitting estimators with different parameter settings, array slicing and preprocessing is kept to a minimum. This can greatly reduced fit time compared to creating pipeline classes for each estimator and pipeline and fitting them one at a time in an Scikit-learnsklearn.model_selection.GridSearch
class.Preprocessing can be done before making any evaluation, and several evaluations can be made on the pre-made folds. Current implementation relies on a randomized grid search, so parameter grids must be specified as SciPy distributions (or a class that accepts an
rvs
method).Changed in version 0.2.0.
Parameters: - scorer (function) –
a scoring function that follows the Scikit-learn API:
score = scorer(estimator, y_true, y_pred)
A user defines scoring function,
score = f(y_true, y_pred)
can be made into a scorer by calling on the ML-Ensemble implementation of Scikit-learn’smake_scorer
. NOTE: do not use Scikit-learn’smake_scorer
if the Evaluator is to be pickled.from mlens.metrics import make_scorer scorer = make_scorer(scoring_function, **kwargs)
- error_score (int, optional) – score to assign when fitting an estimator fails. If
None
, the evaluator will raise an error. - cv (int or obj, default = 2) – cross validation folds to use. Either pass a
KFold
class that obeys the Scikit-learn API. - metrics (list, optional) – list of aggregation metrics to calculate on scores. Default is mean and standard deviation.
- shuffle (bool, default = True) – whether to shuffle input data before creating cv folds.
- random_state (int, optional) – seed for creating folds (if shuffled) and parameter draws
- n_jobs (int, default = -1) – number of CPU cores to use.
- verbose (bool or int, default = False) –
level of printed messages. Levels:
verbose=1
: Message at start and end with total timeverbose=2
: Additional messages for each sub-job (preprocess and evaluation)verbose in [3, 14]
: Additional messages with job completion status at increasing increasing frequencyVerbose >= 15
: prints each job completed as [case].[est].[draw].[fold]
If
verbose>=20
, prints tosys.stderr
, elsesys.stdout
.
-
fit
(X, y, estimators=None, param_dicts=None, n_iter=2, preprocessing=None)[source]¶ Fit
Fit preprocessing if applicable and evaluate estimators if applicable. The method automatically determines whether to only run preprocessing, only evaluation (possibly on previously fitted preprocessing), or both. Calling
fit
will overwrite previously stored data where applicable.Parameters: - X (array-like, shape=[n_samples, n_features]) – input data to preprocess and create folds from.
- y (array-like, shape=[n_samples, ]) – training labels.
- estimators (list or dict, optional) –
set of estimators to use. If no preprocessing is desired or if only on preprocessing pipeline should apply to all, pass a list of estimators. The list can contain elements of named tuples (i.e.
('my_name', my_est)
).If different estimators should be mapped to preprocessing cases, a dictionary that maps estimators to each case should be passed:
{'case_a': list_of_est, ...}
. - param_dicts (dict, optional) –
parameter distribution mapping for estimators. Current implementation only supports randomized grid search. Passed distribution object must have an
rvs
method. Seescipy.stats
for details.There is quite some flexibility in specifying
param_dicts
. If there is no preprocessing, or if all estimators are fitted on all preprocessing cases, theparam_dict
should have keys matching the names of the estimators.estimators = [('name', est), est] param_dicts = {'name': {'param-1': some_distribution}, 'est': {'param-1': some_distribution} }
It is possible to specify different distributions for some or all preprocessing cases:
preprocessing = {'case-1': transformer_list, 'case-2': transformer_list} estimators = [('name', est), est] param_dicts = {'name': {'param-1': some_distribution}, ('case-1', 'est'): {'param-1': some_distribution} ('case-2', 'est'): {'param-1': some_distribution, 'param-2': some_distribution} }
If estimators are mapped on a per-preprocessing case basis as a dictionary,
param_dict
must have key entries of the form(case_name, est_name)
. - n_iter (int) – number of parameter draws to evaluate.
- preprocessing (dict, optional) –
preprocessing cases to consider. Pass a dictionary mapping a case name to a preprocessing pipeline.
preprocessing = {'case_name': transformer_list,}
Returns: self – class instance with stored estimator evaluation results in the
results
attribute.Return type: instance
- scorer (function) –
Benchmark¶
-
class
mlens.model_selection.
Benchmark
(verbose=False, **kwargs)[source]¶ Bases:
mlens.model_selection.model_selection.BaseEval
Benchmark engine without hyper-parameter grid search.
A simplified version of the
Evaluator
that performs a single pass over a set of estimators and preprocessing pipelines for benchmarking purposes.New in version 0.2.0.
Parameters: - verbose (bool, int, optional) – Verbosity during estimation.
- **kwargs (optional) – Optional keyword argument to
BaseBackend
.
-
fit
(X, y, scorer, cv, estimators, preprocessing=None, error_score=None)[source]¶ Run benchmarking job on given data with given estimators.
Fit preprocessing if applicable and evaluate estimators if applicable. The method automatically determines whether to only run preprocessing, only evaluation (possibly on previously fitted preprocessing), or both. Calling
fit
will overwrite previously stored data where applicable.Parameters: - X (array-like, shape=[n_samples, n_features]) – input data to preprocess and create folds from.
- y (array-like, shape=[n_samples, ]) – training labels.
- scorer (function) –
a scoring function that follows the Scikit-learn API:
score = scorer(estimator, y_true, y_pred)
A user defines scoring function,
score = f(y_true, y_pred)
can be made into a scorer by calling on the ML-Ensemble implementation of Scikit-learn’smake_scorer
. NOTE: do not use Scikit-learn’smake_scorer
if the Evaluator is to be pickled.from mlens.metrics import make_scorer scorer = make_scorer(scoring_function, **kwargs)
- error_score (int, optional) – score to assign when fitting an estimator fails. If
None
, the evaluator will raise an error. - cv (int or obj (default = 2)) – cross validation folds to use. Either pass a
KFold
class that obeys the Scikit-learn API. - estimators (list or dict, optional) –
set of estimators to use. If no preprocessing is desired or if only on preprocessing pipeline should apply to all, pass a list of estimators. The list can contain elements of named tuples (i.e.
('my_name', my_est)
).If different estimators should be mapped to preprocessing cases, a dictionary that maps estimators to each case should be passed:
{'case_a': list_of_est, ...}
. - preprocessing (dict, optional) –
preprocessing cases to consider. Pass a dictionary mapping a case name to a preprocessing pipeline.
preprocessing = {'case_name': transformer_list,}
Returns: self – Fitted Benchmark instance. Results available in the
results
attribute.Return type: inst
benchmark¶
-
mlens.model_selection.
benchmark
(X, y, scorer, cv, estimators, preprocessing, error_score=None, **kwargs)[source]¶ Benchmark estimators across preprocessing pipelines.
benchmark()
runs cross validation scoring of a set of estimators, possible against a set of preprocessing pipelines. Equivalent toevl = Benchmark(**kwargs) evl.fit(X, y, scorer, ...)
New in version 0.2.0.
Parameters: - X (array-like, shape=[n_samples, n_features]) – input data to preprocess and create folds from.
- y (array-like, shape=[n_samples, ]) – training labels.
- scorer (function) –
a scoring function that follows the Scikit-learn API:
score = scorer(estimator, y_true, y_pred)
A user defines scoring function,
score = f(y_true, y_pred)
can be made into a scorer by calling on the ML-Ensemble implementation of Scikit-learn’smake_scorer
. NOTE: do not use Scikit-learn’smake_scorer
if the Evaluator is to be pickled.from mlens.metrics import make_scorer scorer = make_scorer(scoring_function, **kwargs)
- error_score (int, optional) – score to assign when fitting an estimator fails. If
None
, the evaluator will raise an error. - cv (int or obj (default = 2)) – cross validation folds to use. Either pass a
KFold
class that obeys the Scikit-learn API. - estimators (list or dict, optional) –
set of estimators to use. If no preprocessing is desired or if only on preprocessing pipeline should apply to all, pass a list of estimators. The list can contain elements of named tuples (i.e.
('my_name', my_est)
).If different estimators should be mapped to preprocessing cases, a dictionary that maps estimators to each case should be passed:
{'case_a': list_of_est, ...}
. - preprocessing (dict, optional) –
preprocessing cases to consider. Pass a dictionary mapping a case name to a preprocessing pipeline.
preprocessing = {'case_name': transformer_list,}
- **kwargs (optional) – Optional arguments to
BaseBackend
.
Returns: results – Summary output that shows data for best mean test scores, such as test and train scores, std, fit times, and params.
Return type:


Sell asset
Supply tokens
Set the token amount as a warranty for this asset
Value:
Gross return rate:
Contract term:
{{asset.value | currency}}
{{asset.grossReturn | percent}}
{{asset.paybackMonths}} months


Currency Converter
Current Rate
€
Base Currency
Select Currency
USD
EUR
Target Currency
Select Currency
USD
EUR
How much would you like to exchange?
You Receive:
Create a currency exchange forecast for the last
{test}
number of weeks.
todays date
End Date


{% extends 'base.html' %} {% load static from staticfiles %} {% block head_title %}Public Data Study{% endblock %} {% block body_main %}
Turn your data into a public resource! The Open Humans: Public Data Sharing study enables you to publicly share the research data you've imported into Open Humans. It is entirely under your control: you'll decide which data sets to share. The data you share in this manner will become publicly available on your Open Humans member profile.
This study is open to Open Humans members who meet our eligibility requirements.
{% if user.is_authenticated %} {% if user.member.public_data_participant.enrolled %}You are currently a participant in this study.
Log in.
When sharing your data, you’ll need to understand that the data may be very identifiable. This means that someone may figure out your identity, even if you don’t share your name. Many members do not attempt to be anonymous, and instead proudly put their name on their Open Humans account and data.
Sharable data sets supported by Open Humans


Bandwidth.Resources.Applications
The Applications resource lets you define call and message handling applications. You write an application on your own servers and have Bandwidth API send events to it by configuring a callback URL.
Summary↑
| create(client, application) | Create an application |
| delete(client, id) | Delete an application |
| find(client, id) | Get information about an application |
| list(client, params \\ []) | Get a list of your applications |
| update(client, id, application) | Make changes to an application |
Functions
Specs:
- create(Client.t, Map.t) :: Client.response
Create an application.
Example:
application = %{ name: "my-awesome-app" }
case Bandwidth.Resources.Applications.create(client, application) do
{:ok, {201, _, _}} -> IO.puts "Application created"
{:error, reason} -> IO.puts "Error: #{reason}"
end
Specs:
- delete(Client.t, binary) :: Client.response
Delete an application.
Example:
case Bandwidth.Resources.Applications.delete(client, "some-application-id") do
{:ok, {200, _, _}} -> IO.puts "Application deleted"
{:error, reason} -> IO.puts "Error: #{reason}"
end
Specs:
- find(Client.t, binary) :: Client.response
Get information about an application.
Example:
case Bandwidth.Resources.Applications.find(client, "some-application-id") do
{:ok, {200, application, _}} -> IO.inspect application
{:ok, {404, _, _}} -> IO.puts "Application not found"
{:error, reason} -> IO.puts "Error: #{reason}"
end
Specs:
- list(Client.t, Client.params) :: Client.response
Get a list of your applications.
Example:
case Bandwidth.Resources.Applications.list(client) do
{:ok, {200, applications, _}} -> IO.inspect applications
{:error, reason} -> IO.puts "Error: #{reason}"
end
Specs:
- update(Client.t, binary, Map.t) :: Client.response
Make changes to an application.
Example:
application = %{ incomingCallUrl: "https://foo.com/calls" }
case Bandwidth.Resources.Applications.update(client, "some-application-id", application) do
{:ok, {200, _, _}} -> IO.puts "Application updated"
{:error, reason} -> IO.puts "Error: #{reason}"
end


Internal Server Error
Apparently we're experiencing an error. But don't worry, we will solve it shortly. Please try after some time.
Home


My Components
react-typescript-datamaps
react-typescript-datamaps is a react wrapper component for the datamaps library - Interactive maps for data visualizations.
- React
- TypeScript
- D3
react-hidden-easter-egg
react-hidden-easter-egg is a react base component that allow you to add easter egg, that will trigger after user typing the secret code.
- React
- Typescript
react-raining-confetti
react-raining-confetti is a react base component that add raining confetti to your application using canvas. with zero dependencies.
- React
- TypeScript


If you need to show validation message as early as a user started to type something, subscribe on form value changes and call markAsTouched on control on first value change


§624-25 Discovery. A civil action in the nature of a bill for discovery may be brought according to the usages and principles of courts of equity, unless the matter is governed by the rules of court. [L 1972, c 143, §1(c)]


About Us
Chap Cafes bring the community together for a meal.
Get Involved
Working with local partners to eradicate homelessness in Claremont.
Learn More
Check back here for upcoming event announcements.
Sample event title: December 10, 2015 at 3:00pm at Claremont, CA
CHAP is a community dedicated to helping neighbors in the Southern California city of Claremont to find their way home.


Copyright © 2003, 2004, 2006 Christoph Pfisterer
Abstract
This is the documentation for disktype, a program to detect the content format of a disk or disk image. It covers installation and usage of the program, but most of all provides background information on the recognized file systems and other formats. That information is useful both for interpreting disktype output and for general reference. Pointers to further documentation are included where possible.
Table of Contents
List of Tables


Here are answers to some of common questions asked of the Meadowside HOA. If you have a question, please contact us
Frequently Asked Questions
How do I get on the neighborhood email list?
We are moving more of the non-critical HOA communications online, so the best way to keep up with what is going on in your community is to be on the neighborhood email list. You can be added by clicking the Contact button on this website and submitting your email address.
How do I join the neighborhood community website?
This website you are on is the public-facing site for Norbeck Manor and contains some general purpose information.
We have a Community website through NextDoor â€“ a company that makes HOA websites. Itâ€™s free and easy to use. It will protect our privacy while providing an online hub for interacting with neighbors and finding important documents and local recommendations. To join, follow this link: https://ro.ble.to/HOAwebsite.
How do I get ___ fixed?
There are lots of different ways to fill in that blank, but there are two main avenues of providing service.
If this issue is between the sidewalks (including streetlamps, trees that need pruning or the state of the sidewalks themselves) the county needs to be contacted. The simpliest way to do that is calling the Montgomery County hotline at 3-1-1 or visiting MC311.com
If the issue is on HOA property, then contact the HOA Board by clicking the Contact button on this website and submitting your request.


A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/


It is our mission to ensure and provide each guest with the best customer service. Being the best also means providing quality authentic food that is made when ordered. Our café strives to provide a relaxing, enjoyable dining experience in a friendly, family oriented environment.
~Gonzales Family
Owners and Founders - Café Santa Rosa
Try Our Popover (Indian Frybread) With Chocolate and Powder Sugar or with Honey and Powder Sugar!


GET Examples
Back to index
Loading ...
Loading ...
Loading ...
Loading ...
Loading ...
Loading ...
Loading ...


--- layout: page title: "Developing Backbone.js Applications" prev: OEBPS/pr01.html next: OEBPS/ch01s02.html book_path: books/developing-backbone-js-applications-addy-osmani--_oeb/ --- {% include JB/setup %} {% raw %}
As JavaScript developers, we are at an interesting point in time where not only do we have mature solutions to help organize the JavaScript powering our applications based on a separation of concerns, but developers looking to build non-trivial projects are almost spoiled for choice for frameworks that can help structure their applications.
Maturity in software (framework) development isn’t simply about how long a framework has been around. It’s about how solid the framework is and more importantly how well it’s evolved to fill its role. Has it become more effective at solving common problems? Does it continue to improve as developers build larger and more complex applications with it?
In this book, I will be covering the popular Backbone.js, which I consider the best of the current family of JavaScript architectural frameworks.
Topics will include MVC theory and how to build applications using Backbone’s models, views, collections and routers. I’ll also be taking you through advanced topics like modular development with Backbone.js and AMD (via RequireJS), how to build applications using modern software stacks (like Node and Express), how to solve the routing problems with Backbone and jQuery Mobile, tips about scaffolding tools, and a lot more.
If this is your first time looking at Backbone.js and you’re still unsure whether or not to give it a try, why not take a look at how a Todo application can be implemented in Backbone and several other popular Javascript frameworks before reading further?
The goal of this book is to create an authoritative and centralized repository of information that can help those developing real-world apps with Backbone. If you come across a section or topic which you think could be improved or expanded on, please feel free to submit a pull-request. It won’t take long and you’ll be helping other developers avoid problems you’ve run into before.
In this section we are going to cover the context into which a framework like Backbone.js fits. Let’s begin our journey into understanding Backbone better with a look at code architecture.
Before exploring any JavaScript frameworks that assist in structuring applications, it can be useful to gain a basic understanding of architectural design patterns. Design patterns are proven solutions to common development problems and can suggest structural approaches to help guide developers in adding some organization to their applications.
Patterns are useful because they’re a set of practices that build upon the collective experience of skilled developers who have repeatedly solved similar problems. Although developers 10 or 20 years ago may not have been using the same programming languages when implementing patterns in their projects, there are many lessons we can learn from their efforts.
In this section, we’re going to review two popular patterns - MVC and MVP. We’ll be exploring in greater detail how Backbone.js implements these patterns shortly to better appreciate where it fits in.


Bianca Negron is a designer & developer living in NYC. She became fascinated with the World Wide Web ever since her mom purchased Apple's Bondi Blue iMac computer (she had a tough time sharing with her sister). Later on, she graduated with a degree in New Media Technology. She currently works with Universal Music Group as a Senior Digital Designer. She is passionate about creating and building meaningful experiences.
When Bianca is not glued to her computer she can be found playing guitar, enjoying some good whiskey with friends, traveling, taking pictures of places/people/things, or attempting to play catch with her cat, Jade.


2016 monthly gross income for top films released in 2016
Pure Flix is a smaller film company only releasing a few films. However it still managed to be one of the
top 25 grossing studios in 2016. the April hit "Godas Not Dead" had a large influence on their Profitability.
Highest Grossing Month for the Studio: April, $16.5 Million
Lowest Grossing Month for the Studio: September, $16.5 Million
Average Grossing Month for the Studio: $16.5 Million
Highest Grossing Individual Film: Godâs Not Dead, $ 28.0 Million
verage Gross For Film: $ 4.4 Million


{% extends "base.html" %} {% block metatags %}
Upload collection of your self photos.
Try our API to get free photos of students.
*Only user with Developer Program can use this API, please refer to this API Terms
May Allah keeps prevent evil attempt from user by accessing the API


Home
Projects
Resume
About me
Contact
CA-Evaluated-System
Bitwise Calculator
Cricket World
Coursera
My Heart
BlueMirrors Projects


hhhh
Since 1989, perfection every time.
Sven's Snowshoe Emporium was founded in 1989 by Sven Jacobssen, a man with a passion for trudging through unsafe surfaces. Since the time he was a small child, Sven dreamed of building an emporium to house the magical shoes that made his hobby possible.


OLYMPICS
DATA
Visualizations
Medals Timeline
Gender & Body Composition
Medals VS GDP
Medals World View - Seasons
Medals World View - Sport
Analysis
Olympic Facts
Olympic Medal Predictions
Medals World View
by Sport
The map shows the top 10 countries that have won the most olympic medals for the selected sport
Enter a sport
Search Results
The bar chart shows the top sports for which the selected country has won most Olympic Medals
Enter a Country
Search Results