草案 ECMA-426 / 2026年1月27日
源映射格式规范
简介
本 Ecma 标准定义了源映射格式,用于将转译后的源代码映射回原始源代码。
源映射格式有以下目标:
支持源级调试,允许双向映射
支持服务端堆栈跟踪去混淆
原始源 映射格式(v1)由 Joseph Schorr 创建,用于 Closure Inspector 以实现优化的 JavaScript
代码的源级调试(但格式本身与语言无关)。然而,随着使用源映射的项目规模扩大,格式的冗长性逐渐成为问题。v2 格式(Source Map Revision 2
Proposal )通过牺牲一定的简单性和灵活性以减小源映射总体大小而设计。即便经过 v2 版本的改动,源映射文件大小依然限制了它的实用性。v3 格式基于
Pavel Podivilov(Google)提出的建议。
源映射格式不再有版本号,现在固定为"3"。
2023-2024年间,源映射格式被开发为更精确的 Ecma 标准,许多人做出了重要贡献。源映射格式的后续迭代预计将来自 TC39-TG4。
Asumu Takikawa, Nicolò Ribaudo, Jon Kuperman
ECMA-426,第一版,项目编辑
1 范围
本标准定义了源映射格式,被多种开发者工具用于改善编译到 JavaScript、WebAssembly 和 CSS 的代码的调试体验。
2 一致性
符合规范的源映射文档是符合本规范详细结构的 JSON 文档。
符合规范的源映射生成器应生成符合源映射文档规范的文档,并能够被本规范中的算法解码而不报告任何错误(即使某些错误被规范指定为可选)。
符合规范的源映射使用者应实现规范中的算法,用于检索(如适用)和解码源映射文档。符合规范的使用者可以在规范允许算法可选择性报告错误 时,忽略错误或报告错误而不终止。
3 参考资料
下列文献中有些内容或全部内容构成本文件的要求。对于有日期的引用,仅适用于所引用的版本。对于无日期的引用,适用被引用文献的最新版本(包括所有修订)。
3.1 规范性引用
ECMA-262,ECMAScript® 语言规范 。
https://tc39.es/ecma262/
ECMA-404,JSON 数据交换格式 。
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
3.2 补充性引用
IETF RFC 4648,Base16、Base32 和 Base64 数据编码 。
https://datatracker.ietf.org/doc/html/rfc4648
WebAssembly 核心规范 。
https://www.w3.org/TR/wasm-core-2/
WHATWG 编码 。
https://encoding.spec.whatwg.org/
WHATWG 抓取(Fetch) 。
https://fetch.spec.whatwg.org/
WHATWG 基础设施(Infra) 。
https://infra.spec.whatwg.org/
WHATWG URL 。
https://url.spec.whatwg.org/
4 表示法约定
本规范遵循 ECMA-262(表示法约定) 中定义的表示法约定,并在本节中进行了扩展。
4.1 算法约定
4.1.1 隐式补全
本规范中声明的所有抽象操作 都默认返回一个正常补全,类型为 算法声明的返回类型,或一个抛出补全 。例如,一个声明如下的抽象操作:
4.1.1.1 GetTheAnswer ( input )
抽象操作 GetTheAnswer 接受参数 input (一个 整数 ),返回一个整数 。
等价于:
4.1.1.2 GetTheAnswer2 ( input )
抽象操作 GetTheAnswer2 接受参数 input (一个 整数 ),返回正常补全,其值为 整数 ,或一个抛出补全 。
所有返回补全 记录的抽象操作 调用,默认使用ReturnIfAbrupt 宏包裹,除非已经被Completion 显式包裹。例如:
令 result 为 GetTheAnswer (value )。
令 second 为 Completion (GetTheAnswer (value ))。
等价于:
令 result 为 ReturnIfAbrupt (GetTheAnswer (value ))。
令 second 为 Completion (GetTheAnswer (value ))。
4.1.2 可选错误
当某算法可选择性报告错误 时,实现可以选择以下行为之一:
针对不同的可选错误,实现可选择不同的行为。
4.2 语法表示
本规范采用 ECMA-262(语法表示) 中定义的语法表示惯例,并有以下注意事项:
本规范定义的语法终结符为单个码位。这类似于 ECMA-262 的词法语法 ,而不是 ECMA-262 的句法语法 。
本规范不使用语法参数 和前瞻限制 ,以简化语法定义。
5 术语与定义
在本文件范围内,下列术语与定义适用。
生成代码
通过编译器或转译器生成的代码。
原始源
未经过编译器或转译器处理的源代码。
源映射URL
URL ,用于从生成代码 引用源映射的位置。
列
在生成代码 的一行内,以零为起始的偏移量。对于
JavaScript 和 CSS 源映射按 UTF-16 码元计算,对于 WebAssembly 源映射的二进制内容(被表示为单行)则按字节索引计算。
注
这意味着 "A"(拉丁大写字母A)计为1个码元,而
"🔥"(火)计为2个码元。其他内容类型的源映射可能存在差异。
6 base64 VLQ
base64 VLQ 是一种base64 编码的变长数量 ,其中最高位(第6位)为延续位,“数字”以低位在前的顺序编码进字符串,且首个数字的最低位作为符号位。
注1
base64 VLQ
编码所能表示的值仅限于32位,除非出现更大值的应用场景。这意味着超过32位的值是无效的,实现可以拒绝它们。符号位计入限制,但延续位不计入。
注2
字符串 "iB" 表示一个有两个数字的 base64 VLQ。第一个数字 "i" 编码为比特模式
0b100010,其中延续位为 1(VLQ 继续)、符号位为 0(非负)、值位为
0b0001。第二个数字 B 编码为 0b000001,其中延续位为 0,无符号位,值位为
0b00001。该 VLQ 字符串解码的值为数字 17。
注3
字符串 "V" 表示一个有一个数字的 base64 VLQ。此数字 "V" 编码为比特模式 0b010101,其中延续位为
0(不延续)、符号位为 1(负)、值位为 0b1010。该 VLQ 字符串解码的值为数字 -10。
base64 VLQ 遵循下述词法语法:
Vlq ::
VlqDigitList
VlqDigitList ::
TerminalDigit
ContinuationDigit
VlqDigitList
TerminalDigit ::
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
ContinuationDigit ::
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0
1
2
3
4
5
6
7
8
9
+
/
6.1 VLQSignedValue
语法指引操作
VLQSignedValue 无参数,返回一个整数 。其在以下产生式上分段定义:
Vlq :: VlqDigitList
令 unsigned 为 VLQUnsignedValue of VlqDigitList 。
如果 unsigned 取模 2 = 1,令 sign
为 -1。
否则,令 sign 为 1。
令 value 为 向下取整 (unsigned /
2)。
如果 value 是 0 且 sign 是 -1,返回 -231 。
如果 value ≥ 231 ,抛出错误。
返回 sign × value 。
注
步骤
6 中的检查是必要的,因为
unsigned 是
VLQUnsignedValue of
VlqDigitList ,而不是
Vlq 。
6.2 VLQUnsignedValue
语法指引操作
VLQUnsignedValue 无参数,返回一个非负整数 。其在以下产生式上分段定义:
Vlq :: VlqDigitList
令 value 为 VLQUnsignedValue of VlqDigitList 。
如果 value ≥ 232 ,抛出错误。
返回 value 。
VlqDigitList ::
ContinuationDigit
VlqDigitList
令 left 为 VLQUnsignedValue (ContinuationDigit 的值)。
令 right 为 VLQUnsignedValue (VlqDigitList 的值)。
返回 left + right × 25 。
TerminalDigit ::
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
令 digit 为本产生式匹配到的字符。
令 value 为对应 digit 的整数 ,根据 IETF RFC 4648
所定义的base64 编码。
断言 :value < 32。
返回 value 。
ContinuationDigit ::
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0
1
2
3
4
5
6
7
8
9
+
/
令 digit 为本产生式匹配到的字符。
令 value 为对应 digit 的整数 ,根据 IETF RFC 4648
所定义的base64 编码。
断言 :32 ≤
value < 64。
返回 value - 32。
7 JSON值工具
虽然本规范的算法基于ECMA-262内部实现,但其目的是方便非JavaScript平台也能实现。本节包含用于处理JSON值 的工具,将ECMA-262的细节从本文件的其他部分中抽象出来。
JSON值 可以是JSON对象 、JSON数组 、字符串 、数字 、布尔值 ,或null 。
JSON对象 是一个对象 ,其中每个属性:
JSON数组 是一个JSON对象 ,满足:
它有一个键为"length" 的属性,值是数字 ,
其它属性的键都是整数索引 。
7.1 ParseJSON ( string )
抽象操作ParseJSON接受参数string (字符串),返回一个JSON值 。调用时按如下步骤执行:
令result 为Call (%JSON.parse% ,
null , « string »)。
断言 :result 是JSON值 。
返回result 。
编者注
该抽象操作正在ECMA-262规范自身中公开,参见
tc39/ecma262#3540 。
7.2 JSONObjectGet ( object , key )
抽象操作JSONObjectGet接受参数object (JSON对象 )和key (字符串),并返回JSON值 或missing 。返回该key 在object 中对应的值。执行时步骤如下:
若object 没有名为key 的自有属性,则返回missing 。
令prop 为object 中名为key 的自有属性。
返回prop 的[[Value]] 属性。
7.3 JSONArrayIterate ( array )
抽象操作JSONArrayIterate接受参数array (JSON数组 ),返回一个列表 ,元素为JSON值 。返回array 的所有元素,便于算法 "For each"
遍历。执行步骤如下:
令length 为JSONObjectGet (array ,
"length" )。
断言 :length 是非负整数 。
令list 为新的空列表 。
令i 为0。
重复,条件为i < ℝ (length ),
令value 为JSONObjectGet (array ,
ToString (𝔽 (i ))))。
断言 :value 不为missing 。
将value 加入list 。
i 加1。
返回list 。
7.4 StringSplit ( string , separators )
抽象操作StringSplit接受参数string (字符串)和separators (字符串列表),返回一个字符串列表。将string 按separators 中任意分隔符分割为子串。如果有多个分隔符匹配,则以separators 中较前的优先。执行步骤如下:
令parts 为新的空列表。
令strLen 为string 长度。
令lastStart 为0。
令i 为0。
重复,当i < strLen ,
令matched 为false 。
对separators 中的每个字符串sep ,执行:
令sepLen 为sep 长度。
令candidate 为string 从i 到min (i
+ sepLen , strLen )的子串。
如果candidate 等于sep 且matched 为false ,则:
令chunk 为string 从lastStart 到i 的子串。
将chunk 加入parts 。
lastStart 设为i + sepLen 。
i 设为i + sepLen 。
matched 设为true 。
如果matched 为false ,则i 加1。
令chunk 为string 从lastStart 到strLen 的子串。
将chunk 加入parts 。
返回parts 。
8 位置类型
8.1 位置记录
位置记录 是一个由非负行号和非负列号 组成的元组:
表1:位置记录 字段
字段名
值类型
[[Line]]
非负整数
[[Column]]
非负整数
8.2 原始位置记录
原始位置记录 是一个由解码源记录 、非负行号和非负列号 组成的元组。它类似于位置记录 ,但用于描述具体原始源文件 中的源位置。
表2:原始位置记录 字段
字段名
值类型
[[Source]]
解码源记录
[[Line]]
非负整数
[[Column]]
非负整数
8.3 ComparePositions ( first , second )
抽象操作 ComparePositions 接受参数 first (一个 Position
Record 或 Original Position Record ) 和
second
(一个 Position
Record 或 Original Position Record ),返回
lesser 、equal 或 greater 。它根据
first
是否分别出现在 second 之前、相等,或在 second 之后,返回
lesser 、equal 或 greater 。对于
Original Position Records ,其 [[Source]] 字段会被忽略。调用时执行以下步骤:
如果first .[[Line]] < second .[[Line]] ,返回lesser 。
如果first .[[Line]] > second .[[Line]] ,返回greater 。
断言 :first .[[Line]] 等于second .[[Line]] 。
如果first .[[Column]] < second .[[Column]] ,返回lesser 。
如果first .[[Column]] > second .[[Column]] ,返回greater 。
返回equal 。
9 源映射格式
源映射是一个JSON文档,包含一个顶层JSON对象 ,其结构如下:
{
"version" : 3 ,
"file" : "out.js" ,
"sourceRoot" : "" ,
"sources" : [ "foo.js" , "bar.js" ] ,
"sourcesContent" : [ null , null ] ,
"names" : [ "src" , "maps" , "are" , "fun" ] ,
"mappings" : "A,AAAB;;ABCDE" ,
"ignoreList" : [ 0 ]
}
version字段 必须始终为数字3,类型为整数 。如果该字段为其他值,源映射可能会被拒绝。
file字段 是此源映射所关联的生成代码 的可选名称。未指明可以是URL 、相对路径名或仅仅是文件名。源映射生成器可根据实际使用场景自由选择。
sourceRoot字段 是可选的源根字符串,用于在服务器上重新定位源文件或去除sources条目中的重复值。该值会被添加到sources字段 的各个条目前。
sources字段 是被mappings字段 引用的原始源代码列表。每个条目要么是字符串(可能为相对的URL ),要么为null (如果源名称未知)。
sourcesContent字段 是源内容(即原始源代码 )字符串的可选列表,在源码无法托管时使用。内容顺序与sources字段 一致。如果某些原始源代码 需通过名称获得,则条目可以为null 。
names字段 是可供mappings字段 使用的符号名称的可选列表。
mappings字段 是包含编码后映射数据的字符串(参见章节9.2 )。
ignoreList字段 是被视为第三方代码(如框架代码或打包器生成代码 )的文件索引的可选列表。这样开发工具就能避开开发者不想查看或调试的代码,无需事先配置。它参照sources字段 ,列出所有已知第三方源码在源映射中的索引。部分浏览器也可能在没有ignoreList字段时使用已废弃的x_google_ignoreList字段。
9.1 源映射解码
解码后源映射记录 包含如下字段:
表3:解码后源映射记录 字段
字段名称
值类型
[[File]]
字符串或null
[[Sources]]
List ,其中每项为解码后源码记录
[[Mappings]]
List ,其中每项为解码后映射记录
解码后源码记录 包含如下字段:
表4:解码后源码记录 字段
字段名称
值类型
[[URL]]
URL 或
null
[[Content]]
字符串或null
[[Ignored]]
布尔值
9.1.1 ParseSourceMap( string , baseURL )
抽象操作 ParseSourceMap 接受参数 string (一个字符串)和 baseURL
(一个 URL ),
返回一个 已解码源码映射记录 。调用时执行以下步骤:
令 json 为 ParseJSON (string )。
如果 json 不是一个 JSON 对象 ,抛出一个错误。
如果 JSONObjectGet (json ,
"sections" ) 不为 missing ,则
返回 DecodeIndexSourceMap (json ,
baseURL )。
返回 DecodeSourceMap (json ,
baseURL )。
9.1.2 DecodeSourceMap( json , baseURL )
抽象操作 DecodeSourceMap 接受参数 json (一个 JSON 对象 )与
baseURL (一个 URL ),返回一个 已解码源码映射记录 。调用时执行以下步骤:
如果 JSONObjectGet (json ,
"version" ) 不是 3 𝔽 ,可选地报告一个错误 。
令 mappingsField 为 JSONObjectGet (json ,
"mappings" )。
如果 mappingsField 不是字符串 ,抛出一个错误。
如果 JSONObjectGet (json ,
"sources" ) 不是一个 JSON 数组 ,抛出一个错误。
令 fileField 为 GetOptionalString (json ,
"file" )。
令 sourceRootField 为 GetOptionalString (json ,
"sourceRoot" )。
令 sourcesField 为 GetOptionalListOfOptionalStrings (json ,
"sources" )。
令 sourcesContentField 为 GetOptionalListOfOptionalStrings (json ,
"sourcesContent" )。
令 ignoreListField 为 GetOptionalListOfArrayIndexes (json ,
"ignoreList" )。
令 sources 为 DecodeSourceMapSources (baseURL ,
sourceRootField , sourcesField , sourcesContentField ,
ignoreListField )。
令 namesField 为 GetOptionalListOfStrings (json ,
"names" )。
令 mappings 为 DecodeMappings (mappingsField ,
namesField , sources )。
按升序对 mappings 排序,若 Decoded Mapping
Record a 小于 Decoded Mapping
Record b ,如果
ComparePositions (a .[[GeneratedPosition]] , b .[[GeneratedPosition]] ) 的结果为 lesser 。
返回 已解码源码映射记录 { [[File]] : fileField , [[Sources]] :
sources , [[Mappings]] : mappings }。
9.1.2.1 GetOptionalString( object , key )
抽象操作 GetOptionalString 接受参数 object (一个 JSON 对象 )
和 key (一个字符串),并返回一个字符串或 null 。调用时执行以下步骤:
令 value 为 JSONObjectGet (object ,
key )。
如果 value 是字符串 ,返回
value 。
如果 value 不为 missing ,可选地报告一个错误 。
返回 null 。
9.1.2.2 GetOptionalListOfStrings( object ,
key )
抽象操作 GetOptionalListOfStrings 接受参数 object (一个 JSON 对象 )
和 key (一个字符串),返回一个字符串的 列表 。
调用时执行以下步骤:
令 list 为一个新的空 列表 。
令 values 为 JSONObjectGet (object ,
key )。
如果 values 为 missing ,返回 list 。
如果 values 不是一个 JSON 数组 ,则
可选地报告一个错误 。
返回 list 。
对于 JSONArrayIterate (values )
的每个元素 item ,执行
如果 item 是字符串 ,则
将 item 添加到 list 。
否则,
可选地报告一个错误 。
向 list 添加 "" 。
返回 list 。
9.1.2.3 GetOptionalListOfOptionalStrings( object ,
key
)
抽象操作 GetOptionalListOfOptionalStrings 接受参数 object (一个 JSON
对象 )
和 key (一个字符串),返回一个字符串或 null 的 列表 。调用时执行以下步骤:
令 list 为一个新的空 列表 。
令 values 为 JSONObjectGet (object ,
key )。
如果 values 为 missing ,返回 list 。
如果 values 不是一个 JSON 数组 ,则
可选地报告一个错误 。
返回 list 。
对于 JSONArrayIterate (values )
的每个元素 item ,执行
如果 item 是字符串 ,则
将 item 添加到 list 。
否则,
如果 item ≠ null ,可选地报告一个错误 。
向 list 添加 null 。
返回 list 。
9.1.2.4 GetOptionalListOfArrayIndexes(object ,
key )
抽象操作 GetOptionalListOfArrayIndexes 接受参数 object (一个对象)和
key (一个字符串),返回一个非负整数
的 列表 。
调用时执行以下步骤:
令 list 为一个新的空列表 。
令 values 为 JSONObjectGet (object ,
key )。
如果 values 为 missing ,返回 list 。
如果 values 不是一个 JSON 数组 ,则
可选地报告一个错误 。
返回 list 。
对于 JSONArrayIterate (values )
的每个元素 item ,执行
如果 item 是整数类型
Number ,
item ≠ +0 𝔽 ,并且 item ≥
+0 𝔽 ,则
将 ℝ (item )
添加到 list 。
否则,
如果 item ≠ null ,可选地报告一个错误 。
向 list 添加 null 。
返回 list 。
9.2 映射结构
mappings 字段
数据的拆分如下:
每一组代表生成文件中的一行,不同组之间用分号(;)分隔
每个分段用逗号(,)分隔
每个分段由 1、4 或 5 个变长字段组成。
每个分段的字段如下:
该分段代表的 生成代码 行中
列 的零起始下标位置。如果这是第一个分段的第一个字段,或者某行新起始(;)后的第一个分段,则该字段保存完整的
base64
VLQ 。否则,该字段保存的是相对于上一次出现该字段的 base64
VLQ 。注意,这不同于后面的字段,因为该字段的上次值在每行后都会重置。
如有,表示 sources 列表的零起始下标。该字段值为相对于上一次出现该字段的 base64 VLQ ,除非是第一次出现,则直接表示全部值。
如有,表示 原始源码 中的零起始行号。该字段为相对于上一次出现该字段的
base64
VLQ ,如果是第一次出现则为全值。若有源字段时,该字段必须存在。
如有,表示 原始源码 行的
列 的零起始下标。该字段为相对于上一次出现该字段的
base64
VLQ ,如果是第一次出现则为全值。若有源字段时,该字段必须存在。
如有,表示与该分段相关的 names 列表的零起始下标。该字段为相对于上一次出现该字段的 base64 VLQ ,如果是第一次出现则为全值。
注 1
此编码的目的是减小 source map 体积。VLQ 编码相比
Source Map Revision 2
Proposal ,在 Google Calendar 的测试中缩小了 50%。
注 2
只含一个字段的分段用于表示不存在对应
原始源码 代码的
生成代码 映射(即
unmapped),如由编译器生成的代码。含四个字段的分段表示有源码映射但没有名称匹配。含五个字段的分段表示有源码和名称映射。
注 3
曾经考虑过使用 file
偏移,但为避免因平台特定行末导致与原文错位,最终选择了行/column 方案。
解码映射记录(Decoded
Mapping Record) 具有以下字段:
表 5:解码映射记录 的字段
字段名
值类型
[[GeneratedPosition]]
一个 位置记录
[[OriginalPosition]]
一个 原始位置记录 或
null
[[Name]]
字符串 或 null
9.2.1 映射语法
映射字符串必须遵循如下语法:
映射字段 MappingsField :
行列表 LineList
行列表 LineList :
行 Line
行 Line
;
行列表 LineList
行 Line :
映射列表
MappingList 可选
映射列表 MappingList :
映射 Mapping
映射 Mapping
,
映射列表 MappingList
映射 Mapping :
生成列号 GeneratedColumn
生成列号 GeneratedColumn
原始源 OriginalSource
原始行号 OriginalLine
原始列号 OriginalColumn
名称
Name 可选
生成列号 GeneratedColumn
:
Vlq
原始源 OriginalSource :
Vlq
原始行号 OriginalLine :
Vlq
原始列号 OriginalColumn :
Vlq
名称 Name :
Vlq
解码映射状态记录(Decode Mapping State Record) 具有以下字段:
表 6:解码映射状态记录 的字段
字段名
值类型
[[GeneratedLine]]
非负 整数
[[GeneratedColumn]]
非负 整数
[[SourceIndex]]
非负 整数
[[OriginalLine]]
非负 整数
[[OriginalColumn]]
非负 整数
[[NameIndex]]
非负 整数
9.2.1.1 DecodeMappingsField
语法导向操作
DecodeMappingsField 接收以下参数:state (一个 解码映射状态记录 Decode Mapping
State Record )、mappings (一个 字符串列表 ,每项为
解码映射记录 Decoded Mapping
Record )、names (一个 字符串列表 )、sources (一个
列表 ,每项为
解码源记录
Decoded Source
Record )。其定义按下列产生式逐个说明:
LineList :
Line
;
LineList
对 Line 执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
将 state .[[GeneratedLine]] 设为
state .[[GeneratedLine]] + 1。
将 state .[[GeneratedColumn]] 设为 0。
对 LineList 执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
Line : [空]
返回。
MappingList :
Mapping
,
MappingList
对 Mapping 执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
对 MappingList 执行
DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
Mapping :
GeneratedColumn
对 GeneratedColumn
执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
如果 state .[[GeneratedColumn]] < 0,则
可选地报告一个错误 。
返回。
令 position 为新的 位置记录 Position
Record { [[Line]] :
state .[[GeneratedLine]] , [[Column]] : state .[[GeneratedColumn]] }。
令 decodedMapping 为新的 DecodedMappingRecord { [[GeneratedPosition]] : position , [[OriginalPosition]] : null , [[Name]] : null }。
将 decodedMapping 添加到 mappings 。
Mapping :
GeneratedColumn
OriginalSource
OriginalLine
OriginalColumn
Name 可选
对 GeneratedColumn
执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
如果 state .[[GeneratedColumn]] < 0,则
可选地报告一个错误 。
返回。
令 generatedPosition 为新的 位置记录 Position
Record { [[Line]] :
state .[[GeneratedLine]] , [[Column]] : state .[[GeneratedColumn]] }。
对 OriginalSource
执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
对 OriginalLine 执行
DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
对 OriginalColumn
执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
如果 state .[[SourceIndex]] < 0 或
state .[[SourceIndex]] ≥ sources 元素数 或
state .[[OriginalLine]] < 0 或
state .[[OriginalColumn]] < 0,则
可选地报告一个错误 。
令 originalPosition 为 null 。
否则,
令 originalPosition 为新的 原始位置记录 Original Position
Record { [[Source]] :
sources [state .[[SourceIndex]] ],[[Line]] :
state .[[OriginalLine]] ,[[Column]] : state .[[OriginalColumn]] }。
令 name 为 null 。
若存在 Name ,则
对 Name 执行 DecodeMappingsField ,参数为
state 、mappings 、names 和 sources 。
如果 state .[[NameIndex]] < 0 或
state .[[NameIndex]] ≥ names
元素数,可选地报告一个错误 。
否则,令 name 为 names [state .[[NameIndex]] ]。
令 decodedMapping 为新的 DecodedMappingRecord { [[GeneratedPosition]] : generatedPosition ,[[OriginalPosition]] : originalPosition ,[[Name]] : name }。
将 decodedMapping 添加到 mappings 。
GeneratedColumn
:
Vlq
令 relativeColumn 为 Vlq 的 VLQSignedValue 。
将 state .[[GeneratedColumn]] 设为
state .[[GeneratedColumn]] +
relativeColumn 。
OriginalSource :
Vlq
令 relativeSourceIndex 为 Vlq 的 VLQSignedValue 。
将 state .[[SourceIndex]] 设为 state .[[SourceIndex]] + relativeSourceIndex 。
OriginalLine :
Vlq
令 relativeLine 为 Vlq 的 VLQSignedValue 。
将 state .[[OriginalLine]] 设为
state .[[OriginalLine]] +
relativeLine 。
OriginalColumn :
Vlq
令 relativeColumn 为 Vlq 的 VLQSignedValue 。
将 state .[[OriginalColumn]] 设为
state .[[OriginalColumn]] +
relativeColumn 。
Name :
Vlq
令 relativeName 为 Vlq 的 VLQSignedValue 。
将 state .[[NameIndex]] 设为 state .[[NameIndex]] + relativeName 。
9.2.2 DecodeMappings ( rawMappings , names ,
sources )
抽象操作 DecodeMappings 接收参数 rawMappings (一个字符串)、names
(一个字符串的 列表 )、
sources (已解码源记录 的
列表 ),
返回 已解码映射记录
的 列表 。
调用时执行以下步骤:
令 mappings 为一个新的空列表 。
令 mappingsNode 为以 MappingsField 作为 目标符号
解析 rawMappings 时得到的根 解析节点 。
如果解析失败,则
可选地报告一个错误 。
返回 mappings 。
令 state 为新的 解码映射状态记录 ,且所有字段均为 0。
对 mappingsNode 执行 DecodeMappingsField 操作,参数为
state 、mappings 、names 和 sources 。
返回 mappings 。
9.2.3 生成 JavaScript 代码的映射
生成代码 的位置可能具有
映射 条目,这些位置根据 ECMAScript
词法语法 定义为 输入元素 。映射条目应指向以下任一:
由 源文本匹配的
IdentifierName 、PrivateIdentifier 、Punctuator 、DivPunctuator 、RightBracePunctuator 、NumericLiteral
和 RegularExpressionLiteral 的第一个码点。
由 源文本匹配的
Comment 、HashbangComment 、StringLiteral 、Template 、TemplateSubstitutionTail 、WhiteSpace
和 LineTerminator 的任意码点。
9.2.4 生成 JavaScript 代码的名称
若 JavaScript 代码符号满足下列条件,源映射生成器应为该符号生成带 [[Name]] 字段的 映射 条目:
原始源码 语言结构在语义上映射到生成的 JavaScript 代码。
原始源码 语言结构有名称。
此时,该 映射 条目的 [[Name]] 应为 原始源码 语言结构的名称。 [[Name]] 非 null 的 映射 被称为 命名映射 。
注意 1
例如混淆器会重命名函数和变量,或从立即调用函数表达式中移除函数名。
下列枚举列出了 ECMAScript
句法语法 中的产生式,以及源映射生成器应 为其生成命名映射的对应 token 或非终结符(即产生式右侧项)。创建这些 token 的
映射 条目应遵循 9.2.3 。
该枚举应理解为“最低标准”。一般情况下,源映射生成器可自由生成其他命名映射。
注意 2
枚举也包含生成器“可”生成命名映射的 token,而不仅仅是“应”生成的那些。这反映了现有工具实际生成或期望命名映射。重复的命名映射开销很低:names
的索引是相对编码的,因此连续映射同一名称时编码为 0(A)。
BindingIdentifier ,用于
LexicalDeclaration 、VariableStatement 和
FormalParameterList 。
BindingIdentifier ,用于
FunctionDeclaration 、FunctionExpression 、AsyncFunctionDeclaration 、AsyncFunctionExpression 、GeneratorDeclaration 、GeneratorExpression 、AsyncGeneratorDeclaration
和 AsyncGeneratorExpression (如果存在),否则为紧接
FormalParameters 的左括号 (。
无论 BindingIdentifier 是否存在,源映射生成器可选择在左括号为位置生成命名映射。
对于 ArrowFunction 或 AsyncArrowFunction :
当 ArrowFunction 由单一 BindingIdentifier 参数生成,或
AsyncArrowFunction 由
AsyncArrowBindingIdentifier 生成时,=> token。
注意 3
这描述了(异步)箭头函数有单一参数且该参数未被圆括号包裹的情况。
当 ArrowFunction 或 AsyncArrowFunction 由
ArrowFormalParameters 生成时的左括号 (。
源映射生成器亦可选择在 => token 处生成命名映射,以与前述情况一致。
ClassElementName ,用于
MethodDefinition 。包含生成器、异步方法、异步生成器和访问器。若
ClassElementName 为 "constructor" ,则 [[Name]] 应为原始类名(如果适用)。
源映射生成器亦可选择在左括号 ( 处生成命名映射。
源映射生成器可为包含在 Expression 的 IdentifierReference 生成命名映射。
9.3 解析源码
在拼接 sourceRoot 后,如果 sources 不是绝对 URL,则应相对于 source map 解析 sources(就像在 HTML 文档中解析 script 的
src 属性)。
9.3.1 DecodeSourceMapSources ( baseURL ,
sourceRoot , sources , sourcesContent , ignoreList )
抽象操作 DecodeSourceMapSources 接收参数 baseURL (URL )、sourceRoot (字符串或
null )、sources (字符串或 null 的 List )、sourcesContent (字符串或
null 的 List )、ignoreList (非负
整数 的 List ),返回 解码后源码记录 。调用时执行以下步骤:
令 decodedSources 为新的空 List 。
令 sourcesContentCount 为 sourcesContent 的元素个数。
令 sourceUrlPrefix 为 "" 。
如果 sourceRoot ≠ null ,则
如果 sourceRoot 以码点 U+002F (SOLIDUS) 结尾,则
设置 sourceUrlPrefix 为 sourceRoot 。
否则,
设置 sourceUrlPrefix 为 sourceRoot 和
"/" 的字符串拼接 。
令 index 为 0。
当 index < sources 的长度时重复执行:
令 source 为 sources [index ]。
令 decodedSource 为 解码后源码记录 { [[URL]] :null ,[[Content]] :null ,[[Ignored]] :false }。
如果 source ≠ null ,则
将 source 设置为 sourceUrlPrefix 和 source
的字符串拼接 。
令 sourceURL 为 URL 解析 source (以
baseURL 作为基础)。
如果 sourceURL 为 failure ,可选地报告错误 。
否则,将 decodedSource .[[URL]] 设置为
sourceURL 。
如果 ignoreList 包含 index ,则将 decodedSource .[[Ignored]] 设置为 true 。
如果 sourcesContentCount > index ,则将
decodedSource .[[Content]] 设置为
sourcesContent [index ]。
将 decodedSource 添加到 decodedSources 。
返回 decodedSources 。
注意
支持显示源码内容但不支持显示具有同一URL 但内容不同的多个源码的实现,会从对应 URL 的多种内容中任意选取其一。
9.4 扩展
源映射的消费方应忽略任何无法识别的额外属性,而不是因其而拒绝该源映射,这样该格式可以在不破坏现有用户的情况下添加新特性。
10 索引源映射
为支持拼接生成代码 和其他常见后处理,支持源映射的另一种表示方式:
{
"version" : 3 ,
"file" : "app.js" ,
"sections" : [
{
"offset" : { "line" : 0 , "column" : 0 } ,
"map" : {
"version" : 3 ,
"file" : "section.js" ,
"sources" : [ "foo.js" , "bar.js" ] ,
"names" : [ "src" , "maps" , "are" , "fun" ] ,
"mappings" : "AAAA,E;;ABCDE"
}
} ,
{
"offset" : { "line" : 100 , "column" : 10 } ,
"map" : {
"version" : 3 ,
"file" : "another_section.js" ,
"sources" : [ "more.js" ] ,
"names" : [ "more" , "is" , "better" ] ,
"mappings" : "AAAA,E;AACA,C;ABCDE"
}
}
]
}
索引映射遵循标准映射的结构。和常规的源映射一样,文件格式为 JSON,顶层为对象。它共享常规源映射的 version 以及file字段 ,但增加了新的sections字段 。
sections字段 是一个对象数组,每个对象包含如下字段:
offset字段 是一个对象,拥有两个字段
line 和 column,分别表示该引用源映射所代表的生成代码 的偏移量。
map字段 是一个嵌入的完整源映射对象。嵌入的映射不会继承索引映射中的任何值。
sections 应按起始位置排序,并且所表示的区块不能重叠。
10.1 DecodeIndexSourceMap ( json , baseURL )
抽象操作 DecodeIndexSourceMap 接收参数 json (对象)和 baseURL (URL ),返回解码后源映射记录 。调用时执行以下步骤:
令 sectionsField 为 JSONObjectGet (json ,
"sections" ).
断言 :
sectionsField 不为 missing 。
如果 sectionsField 不是一个 JSON 数组 ,则抛出错误。
如果 JSONObjectGet (json ,
"version" )
不为 3 𝔽 ,可选地报告一个错误 。
令 fileField 为 GetOptionalString (json ,
"file" ).
令 sourceMap 为 已解码源码映射记录 { [[File]] : fileField , [[Sources]] : « », [[Mappings]] :
« » }。
令 previousOffsetPosition 为 null 。
令 previousLastMapping 为 null 。
对于 JSON
value section 属于 JSONArrayIterate (sectionsField ),执行
如果 section 不是一个 JSON 对象 ,则
可选地报告一个错误 。
否则,
令 offset 为 JSONObjectGet (section ,
"offset" ).
如果 offset 不是一个 JSON 对象 ,则抛出错误。
令 offsetLine 为 JSONObjectGet (offset ,
"line" ).
令 offsetColumn 为 JSONObjectGet (offset ,
"column" ).
如果 offsetLine 不是一个 整数类型
Number ,则
可选地报告一个错误 。
将 offsetLine 设为 +0 𝔽 。
如果 offsetColumn 不是一个 整数类型
Number ,则
可选地报告一个错误 。
将 offsetColumn 设为 +0 𝔽 。
令 offsetPosition 为新的 位置记录 {
[[Line]] : offsetLine , [[Column]] :
offsetColumn }。
如果 previousOffsetPosition ≠ null ,则
如果 ComparePositions (offsetPosition ,
previousOffsetPosition ) 的结果为
lesser ,可选地报告一个错误 。
如果 previousLastMapping ≠ null ,则
如果 ComparePositions (offsetPosition ,
previousLastMapping .[[GeneratedPosition]] ) 的结果为
lesser ,可选地报告一个错误 。
注:解码算法的这一部分用于检查索引 source map 的 sections
字段 各项是否有序且不重叠。尽管一般期望生成器不会输出有重叠 section 的索引
source map,但 source map 消费者可以只检查 section 偏移有序这一更简单的条件。
令 mapField 为 JSONObjectGet (section ,
"map" ).
如果 mapField 不是一个 JSON 对象 ,则抛出错误。
令 decodedSectionCompletion 为 Completion (DecodeSourceMap (json ,
baseURL ))。
如果 decodedSectionCompletion 是 throw
completion ,则
可选地报告一个错误 。
否则,
令 decodedSection 为
decodedSectionCompletion .[[Value]] 。
对于 已解码源记录
additionalSource 属于 decodedSection .[[Sources]] ,执行
如果 sourceMap .[[Sources]]
不包含
additionalSource ,则
将 additionalSource 添加到
sourceMap .[[Sources]] 。
令 offsetMappings 为一个新的空列表 。
对于 已解码映射记录
mapping 属于
decodedSection .[[Mappings]] ,执行
如果 mapping .[[GeneratedPosition]] .[[Line]] = 0,则
将 mapping .[[GeneratedPosition]] .[[Column]] 设为
mapping .[[GeneratedPosition]] .[[Column]] +
offsetColumn 。
将 mapping .[[GeneratedPosition]] .[[Line]] 设为 mapping .[[GeneratedPosition]] .[[Line]] +
offsetLine 。
将 mapping 添加到 offsetMappings 。
将 sourceMap .[[Mappings]] 设为
列表拼接
sourceMap .[[Mappings]] 与
offsetMappings 的结果。
将 previousOffsetPosition 设为 offsetPosition 。
如果 offsetMappings 非空,则将 previousLastMapping 设为
offsetMappings 的最后一个元素。
返回 sourceMap 。
注意
实现可以选择不将所有 section 的映射拼接在一起,例如可以分别存储每个 section 并使用二分查找来定位。
11 获取源映射
11.1 关联生成代码与源映射
虽然 source map 格式旨在与语言和平台无关,但对于 Web 服务器托管的 JavaScript 的预期用例,定义如何引用它们是有用的。
将 source map 链接到输出有两种方法。第一种方法需要服务器支持以添加 HTTP 头,第二种方法则需要在源码中进行注释。
Source map 通过 URL 进行链接,具体格式参见 WHATWG URL ;特别地,URI 不允许出现的字符应进行百分号编码,同时也允许为
data URI。若配合 sourcesContent 字段使用 data URI,可实现完全自包含的 source map。
HTTP sourcemap 头的优先级高于源码注释,如果二者都存在,则应使用该头部的 URL 解析 source map 文件。
不管采用哪种方式获取 source map
URL ,解析过程是一致的,流程如下。
当 source map URL
不是绝对路径时,则它是相对于 生成代码 的 源码源(source origin) 。源码源 的确定方式如下:
11.1.2 通过源码内注释关联
生成代码 应包含一个名为sourceMappingURL的注释,或根据其语言或格式采用等效结构,并在其中包含
source map 的 URL 。本规范定义了 JavaScript、CSS 和 WebAssembly
语言下该注释的写法。其他语言应采用类似约定。
对于给定的语言,可以有多种检测sourceMappingURL注释的方法,以便不同的实现能够选择对其而言更简单的方式。若所有提取方法的结果一致,生成代码 即表明明确无歧义地链接到一个 source map 。
如果某工具消费了一个或多个明确无歧义地链接到 source map 的源文件,并生成一个输出文件且该文件链接到
source map,则输出文件也必须明确无歧义 地进行链接。
注
如下 JavaScript 代码虽然链接了 source map,但这种链接方式并不是明确无歧义 :
let a = `
//# sourceMappingURL=foo.js.map
// `
如果source map
URL 采用解析方式 提取,结果为foo.js.map,而采用非解析方式 则得到null 。
令 module 为 module_decode (bytes )。
如果 module 为 WebAssembly 错误 ,返回
null 。
对于 module 的每个 自定义段 custom
section customSection ,执行
令 name 为 customSection 的 name。
如果 CodePointsToString (name )
等于 "sourceMappingURL" ,则
令 value 为 customSection 的 bytes。
返回 CodePointsToString (value )。
返回 null 。
由于 WebAssembly 并非文本格式,且不支持注释,因此只支持唯一明确的提取方法。URL 以 WebAssembly
name 方式编码,并作为 自定义段 custom
section 的内容。对生成 WebAssembly 代码的工具来说,生成两个或更多名称为
sourceMappingURL 的 自定义段 是无效的行为。
11.2 获取源映射文件
11.2.1 FetchSourceMap ( url )
抽象操作 FetchSourceMap 接收参数 url (一个 URL ),返回一个 Promise。调用时执行以下步骤:
令 promiseCapability 为 NewPromiseCapability (%Promise% )。
令 request 为一个新的 request ,其
request URL 为
url 。
令 processResponseConsumeBody 为一个带参数 (response ,
bodyBytes ) 的 Abstract
Closure ,捕获 promiseCapability 和
url ,调用时按下列步骤执行:
如果 bodyBytes 为 null 或
failure ,则
执行 Call (promiseCapability .[[Reject]] , undefined , « 新建一个
TypeError »)。
返回。
如果 url 的 scheme 属于
HTTP(S) scheme
且 字节序列
`)]}'` 是
字节序列前缀 ,那么
循环,直到 bodyBytes 的 字节序列长度
≠ 0
且 bodyBytes [0] 不是 HTTP
换行字节 时,
将 bodyBytes 的第 0 个元素移除。
令 bodyString 为 Completion (对
bodyBytes 执行 UTF-8
解码 )。
IfAbruptRejectPromise (bodyString ,
promiseCapability )。
令 jsonValue 为 Completion (ParseJSON (bodyString ))。
IfAbruptRejectPromise (jsonValue ,
promiseCapability )。
执行 Call (promiseCapability .[[Resolve]] , undefined , «
jsonValue »)。
对 request 执行 fetch 操作,并将 processResponseConsumeBody
设为 processResponseConsumeBody 。
返回 promiseCapability .[[Promise]] 。
注
出于历史原因,经由 HTTP(S) 传递 source map 时,服务器可能会在头部加上一行以 )]}' 开头的内容。
)] } 'garbage here
{ "version" : 3 , ...}
其解释如下:
{ "version" : 3 , ...}
12 源映射记录的操作
解码 source map 后,source map 使用者可以利用所得的 已解码源码映射记录
查询用于调试或其他用途的位置数据。本文档本节描述 source map 使用者常见操作的行为。
GetOriginalPositions 操作可用于根据 生成代码 中的位置,查询其对应的 原始源码
位置。例如,调试器可以利用此操作,通过用户鼠标点击,从 生成代码 自动导航到 原始源码 。
12.1 GetOriginalPositions ( sourceMapRecord ,
generatedPosition )
抽象操作 GetOriginalPositions 接受参数 sourceMapRecord (一个 已解码源码映射记录 )和 generatedPosition (一个
位置记录 ),
返回 原始位置记录 的
列表 。调用时执行如下步骤:
令 mappings 为 sourceMapRecord .[[Mappings]] 。
令 last 为 null 。
令 originalPositions 为一个新的空
列表 。
对于 mappings 中的每个元素 mapping ,按逆序遍历,执行
如果 last 为 null ,则
如果执行 ComparePositions (mapping .[[GeneratedPosition]] , generatedPosition )
的结果为
lesser 或 equal ,则
将 last 设为 mapping 。
如果 last 不为 null ,则
对于 mappings 中的每个元素 mapping ,执行
如果执行 ComparePositions (last .[[GeneratedPosition]] , mapping .[[GeneratedPosition]] ) 的结果为
equal ,则
将 mapping .[[OriginalPosition]]
添加到 originalPositions 。
返回 originalPositions 。
附录A (资料性) 约定
在使用或生成源映射时,应遵循以下约定。
A.1 源映射命名
通常,源映射会和生成文件名称相同,只是文件扩展名为 .map。例如 page.js 的源映射会命名为
page.js.map。
A.2 关联eval代码与有名生成代码
在 eval 代码使用源映射时有一种现有约定,格式如下:
详细描述见 Give your eval a name with //@
sourceURL 。
附录B (资料性) 说明
B.1 语言无关的堆栈映射
无需源码语言知识的堆栈追踪映射,未在本文档中涉及 。
B.2 多级映射
目前常见工具会通过一些DSL(模板)或编译流程(TypeScript → JavaScript → 压缩
JavaScript)生成源文件,导致最终源映射在此过程中经过多次转换。此问题有两种解决方式。一种是简单但有信息损失的方法,即为调试目的忽略中间步骤,将中间产物视为“原始源码”,或者只传递源映射位置信息,隐藏上述过程。更完整的方法是支持多级映射:如果原始源码也有源映射引用,允许用户继续解析下一级源映射。
但尚不清楚除 JavaScript 外,其他语言的“源映射引用”应如何表达,特别是在不支持 JavaScript 风格单行注释的语言中。
附录C (资料性) 外部规范中定义的术语
本节列出了本文档中所用、由 ECMA-262 以外的外部规范定义的所有术语和算法。
WebAssembly 核心规范 <https://www.w3.org/TR/wasm-core-2/ >
custom section ,
module_decode ,
WebAssembly error ,
WebAssembly names
WHATWG Encoding <https://encoding.spec.whatwg.org/ >
UTF-8 decode
WHATWG Fetch <https://fetch.spec.whatwg.org/ >
fetch ,
HTTP newline byte ,
processResponseConsumeBody ,
request ,
request URL
WHATWG Infra <https://infra.spec.whatwg.org/ >
byte sequence ,
byte-sequence-prefix ,
byte-sequence-length ,
WHATWG URL <https://url.spec.whatwg.org/ >
HTTP(S) scheme ,
scheme ,
URL ,
URL parsing
附录D (资料性) 参考文献
IETF RFC 4648, Base16, Base32 和 Base64 数据编码 ,见 <https://datatracker.ietf.org/doc/html/rfc4648 >
ECMA-262, ECMAScript® 语言规范 ,见 <https://tc39.es/ecma262/ >
ECMA-404, JSON 数据交换格式 ,见 <https://www.ecma-international.org/publications-and-standards/standards/ecma-404/ >
WebAssembly 核心规范 ,见 <https://www.w3.org/TR/wasm-core-2/ >
WHATWG Encoding ,见 <https://encoding.spec.whatwg.org/ >
WHATWG Fetch ,见 <https://fetch.spec.whatwg.org/ >
WHATWG Infra ,见 <https://infra.spec.whatwg.org/ >
WHATWG URL ,见 <https://url.spec.whatwg.org/ >
给 eval 起名字 //@ sourceURL ,Firebug (2009),见
<http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/ >
Source Map Revision 2 Proposal ,John Lenz (2010),见
<https://docs.google.com/document/d/1xi12LrcqjqIHTtZzrzZKmQ3lbTv9mKrN076UB-j3UZQ/ >
Variable-length
quantity ,维基百科,见 <https://en.wikipedia.org/wiki/Variable-length_quantity >
附录E (资料性) 后记
本规范在 GitHub 上采用一种名为 Ecmarkup 的纯文本源格式编写。Ecmarkup 是一种基于 HTML 和 Markdown
的方言,提供了用于以纯文本编写 ECMAScript 规范并将其处理为符合本文件编辑规范的完整 HTML 渲染的框架和工具集。Ecmarkup 集成了诸多其他格式与技术,包括用于定义语法的 Grammarkdown 和用于编写算法步骤的 Ecmarkdown 。此规范的 PDF 版本通过打印 HTML 渲染结果到 PDF 完成。
本规范第一版是使用 Bikeshed 编写的,这是一种基于 HTML 和 Markdown 的不同纯文本源格式。
标准化前的版本采用 Google Docs 编写。
Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://ecma-international.org/
Copyright Notice
© 2026 Ecma International
This draft document may be copied and furnished to others, and derivative works that comment on or
otherwise explain it or assist in its implementation may be prepared, copied, published, and
distributed, in whole or in part, without restriction of any kind, provided that the above copyright
notice and this section are included on all such copies and derivative works. However, this document
itself may not be modified in any way, including by removing the copyright notice or references to
Ecma International, except as needed for the purpose of developing any document or deliverable
produced by Ecma International.
This disclaimer is valid only prior to final version of this document. After approval all rights on
the standard are reserved by Ecma International.
The limited permissions are granted through the standardization phase and will not be revoked by Ecma
International or its successors or assigns during this time.
This document and the information contained herein is provided on an "AS IS" basis and ECMA
INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY
IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Software License
All Software contained in this document ("Software") is protected by copyright and is being made
available under the "BSD License", included below. This Software may be subject to third party rights
(rights from parties other than Ecma International), including patent rights, and no licenses under such
third party rights are granted under this license even if the third party concerned is a member of Ecma
International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm
FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA
INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
Neither the name of the authors nor Ecma International may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.