# Attribute Stories to Source Requirements

You are the lineage attribution agent. You are given one imported source file and the complete
list of stories that already exist for this Target. Identify the distinct requirements the source
states, and for each one name the stories that implement it.

This is a matching task against a closed set. Every story you may name is listed in `<stories>`.
You are not decomposing work, proposing new stories, or judging whether the existing stories are
correct.

## Method

1. Read the source and identify each distinct requirement it states. A requirement is a thing the
   system must do, at whatever granularity the author wrote it. One sentence may state one
   requirement that several stories implement — for example "add a table and show it on screen"
   is one requirement implemented by a schema story, a route story, and a view story. Do not split
   a requirement to make the mapping tidier, and do not merge two requirements that a reader would
   act on separately.
2. Give each requirement a short kebab-case name that describes it. The name is an identifier, not
   a summary: `mark-book-read`, not `the-reader-can-mark-a-book-as-read`.
3. For each requirement, list every story that implements any part of it. A story may implement
   more than one requirement; a requirement may need more than one story.
4. List any story that implements no requirement in the source as `<unattached>`. This is expected
   and correct for foundational work — application scaffolding, configuration, shared UI framing,
   test harnesses — that the author never asked for by name. Do not force such a story onto an
   unrelated requirement.

## Rules

- Use only story ids that appear in `<stories>`. Never invent one.
- Every story must appear exactly once, either inside a `stories` attribute or as `<unattached>`.
- Quote the requirement text verbatim from the source in the tag body. Do not paraphrase it.
- Emit nothing but the tags below. No preamble, no commentary, no explanation.

## Output

```text
<requirement name="add-remove-books" stories="add-book,remove-book,database">
The reader can add a book with a title and author, view the books in the order added, and remove a book.
</requirement>
<requirement name="reject-empty-fields" stories="validate-book">
An empty title or author is rejected with a clear error message.
</requirement>
<unattached story="architecture"/>
<unattached story="ui-general"/>
```

# Attribution job

<source name="jq.test">
# Tests are groups of three lines: program, input, expected output
# Blank lines and lines starting with # are ignored

#
# Simple value tests to check parser. Input is irrelevant
#

true
null
true

false
null
false

null
42
null

1
null
1


-1
null
-1

# FIXME: much more number testing needed

{}
null
{}

[]
null
[]

{x:-1},{x:-.},{x:-.|abs}
1
{"x":-1}
{"x":-1}
{"x":1}

# The input line starts with a 0xFEFF (byte order mark) codepoint
# No, there is no reason to have a byte order mark in UTF8 text.
# But apparently people do, so jq shouldn't break on it.
.
﻿"byte order mark"
"byte order mark"

# We test escapes by matching them against Unicode codepoints
# FIXME: more tests needed for weird unicode stuff (e.g. utf16 pairs)
"Aa\r\n\t\b\f\u03bc"
null
"Aa\u000d\u000a\u0009\u0008\u000c\u03bc"

.
"Aa\r\n\t\b\f\u03bc"
"Aa\u000d\u000a\u0009\u0008\u000c\u03bc"

%%FAIL
"u\vw"
jq: error: Invalid escape at line 1, column 4 (while parsing '"\v"') at <top-level>, line 1, column 3:
    "u\vw"
      ^^

"inter\("pol" + "ation")"
null
"interpolation"

@text,@json,([1,.]|@csv,@tsv),@html,(@uri|.,@urid),@sh,(@base64|.,@base64d)
"!()<>&'\"\t"
"!()<>&'\"\t"
"\"!()<>&'\\\"\\t\""
"1,\"!()<>&'\"\"\t\""
"1\t!()<>&'\"\\t"
"!()&lt;&gt;&amp;&apos;&quot;\t"
"%21%28%29%3C%3E%26%27%22%09"
"!()<>&'\"\t"
"'!()<>&'\\''\"\t'"
"ISgpPD4mJyIJ"
"!()<>&'\"\t"

# regression test for #436
@base64
"foóbar\n"
"Zm/Ds2Jhcgo="

@base64d
"Zm/Ds2Jhcgo="
"foóbar\n"

@uri
"\u03bc"
"%CE%BC"

@urid
"%CE%BC"
"\u03bc"

@html "<b>\(.)</b>"
"<script>hax</script>"
"<b>&lt;script&gt;hax&lt;/script&gt;</b>"

[.[]|tojson|fromjson]
["foo", 1, ["a", 1, "b", 2, {"foo":"bar"}]]
["foo",1,["a",1,"b",2,{"foo":"bar"}]]

#
# Dictionary construction syntax
#

{a: 1}
null
{"a":1}

{a,b,(.d):.a,e:.b}
{"a":1, "b":2, "c":3, "d":"c"}
{"a":1, "b":2, "c":1, "e":2}

{"a",b,"a$\(1+1)"}
{"a":1, "b":2, "c":3, "a$2":4}
{"a":1, "b":2, "a$2":4}

%%FAIL
{(0):1}
jq: error: Cannot use number (0) as object key at <top-level>, line 1, column 3:
    {(0):1}
      ^

%%FAIL
{1+2:3}
jq: error: May need parentheses around object key expression at <top-level>, line 1, column 2:
    {1+2:3}
     ^^^

%%FAIL
{non_const:., (0):1}
jq: error: Cannot use number (0) as object key at <top-level>, line 1, column 16:
    {non_const:., (0):1}
                   ^

#
# Field access, piping
#

.foo
{"foo": 42, "bar": 43}
42

.foo | .bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

.foo.bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

.foo_bar
{"foo_bar": 2}
2

.["foo"].bar
{"foo": {"bar": 42}, "bar": "badvalue"}
42

."foo"."bar"
{"foo": {"bar": 20}}
20

.e0, .E1, .E-1, .E+1
{"e0": 1, "E1": 2, "E": 3}
1
2
2
4

[.[]|.foo?]
[1,[2],{"foo":3,"bar":4},{},{"foo":5}]
[3,null,5]

[.[]|.foo?.bar?]
[1,[2],[],{"foo":3},{"foo":{"bar":4}},{}]
[4,null]

[..]
[1,[[2]],{ "a":[1]}]
[[1,[[2]],{"a":[1]}],1,[[2]],[2],2,{"a":[1]},[1],1]

[.[]|.[]?]
[1,null,[],[1,[2,[[3]]]],[{}],[{"a":[1,[2]]}]]
[1,[2,[[3]]],{},{"a":[1,[2]]}]

[.[]|.[1:3]?]
[1,null,true,false,"abcdef",{},{"a":1,"b":2},[],[1,2,3,4,5],[1,2]]
[null,"bc",[],[2,3],[2]]

# chaining/suffix-list, with and without dot
map(try .a[] catch ., try .a.[] catch ., .a[]?, .a.[]?)
[{"a": [1,2]}, {"a": 123}]
[1,2,1,2,1,2,1,2,"Cannot iterate over number (123)","Cannot iterate over number (123)"]

# oss-fuzz #66070: objects[] leaks if a non-last element throws an error
try ["OK", (.[] | error)] catch ["KO", .]
{"a":["b"],"c":["d"]}
["KO",["b"]]

#
# Negative array indices
#

try (.foo[-1] = 0) catch .
null
"Out of bounds negative array index"

try (.foo[-2] = 0) catch .
null
"Out of bounds negative array index"

.[-1] = 5
[0,1,2]
[0,1,5]

.[-2] = 5
[0,1,2]
[0,5,2]

try (.[999999999] = 0) catch .
null
"Array index too large"

#
# Multiple outputs, iteration
#

.[]
[1,2,3]
1
2
3

1,1
[]
1
1

1,.
[]
1
[]

[.]
[2]
[[2]]

[[2]]
[3]
[[2]]

[{}]
[2]
[{}]

[.[]]
["a"]
["a"]

[(.,1),((.,.[]),(2,3))]
["a","b"]
[["a","b"],1,["a","b"],"a","b",2,3]

[([5,5][]),.,.[]]
[1,2,3]
[5,5,[1,2,3],1,2,3]

{x: (1,2)},{x:3} | .x
null
1
2
3

[.[-4,-3,-2,-1,0,1,2,3]]
[1,2,3]
[null,1,2,3,1,2,3,null]

[range(0;10)]
null
[0,1,2,3,4,5,6,7,8,9]

[range(0,1;3,4)]
null
[0,1,2, 0,1,2,3, 1,2, 1,2,3]

[range(0;10;3)]
null
[0,3,6,9]

[range(0;10;-1)]
null
[]

[range(0;-5;-1)]
null
[0,-1,-2,-3,-4]

[range(0,1;4,5;1,2)]
null
[0,1,2,3,0,2, 0,1,2,3,4,0,2,4, 1,2,3,1,3, 1,2,3,4,1,3]

[while(.<100; .*2)]
1
[1,2,4,8,16,32,64]

[(label $here | .[] | if .>1 then break $here else . end), "hi!"]
[0,1,2]
[0,1,"hi!"]

[(label $here | .[] | if .>1 then break $here else . end), "hi!"]
[0,2,1]
[0,"hi!"]

%%FAIL
. as $foo | break $foo
jq: error: $*label-foo is not defined at <top-level>, line 1, column 13:
    . as $foo | break $foo
                ^^^^^^^^^^

[.[]|[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]]
[1,2,3,4,5]
[1,2,6,24,120]

[label $out | foreach .[] as $item ([3, null]; if .[0] < 1 then break $out else [.[0] -1, $item] end; .[1])]
[11,22,33,44,55,66,77,88,99]
[11,22,33]

[foreach range(5) as $item (0; $item)]
null
[0,1,2,3,4]

[foreach .[] as [$i, $j] (0; . + $i - $j)]
[[2,1], [5,3], [6,4]]
[1,3,5]

[foreach .[] as {a:$a} (0; . + $a; -.)]
[{"a":1}, {"b":2}, {"a":3, "b":4}]
[-1, -1, -4]

[-foreach -.[] as $x (0; . + $x)]
[1,2,3]
[1,3,6]

[foreach .[] / .[] as $i (0; . + $i)]
[1,2]
[1,3,3.5,4.5]

[foreach .[] as $x (0; . + $x) as $x | $x]
[1,2,3]
[1,3,6]

[limit(3; .[])]
[11,22,33,44,55,66,77,88,99]
[11,22,33]

[limit(0; error)]
"badness"
[]

[limit(1; 1, error)]
"badness"
[1]

try limit(-1; error) catch .
null
"limit doesn't support negative count"

[skip(3; .[])]
[1,2,3,4,5,6,7,8,9]
[4,5,6,7,8,9]

[skip(0,2,3,4; .[])]
[1,2,3]
[1,2,3,3]

[skip(3; .[])]
[]
[]

try skip(-1; error) catch .
null
"skip doesn't support negative count"

nth(1; 0,1,error("foo"))
null
1

[first(range(.)), last(range(.))]
10
[0,9]

[first(range(.)), last(range(.))]
0
[]

[nth(0,5,9,10,15; range(.)), try nth(-1; range(.)) catch .]
10
[0,5,9,"nth doesn't support negative indices"]

# Check that first(g) does not extract more than one value from g
first(1,error("foo"))
null
1

#
# Check that various builtins evaluate all arguments where appropriate,
# doing cartesian products where appropriate.
#

# Check that limit does work for each value produced by n!
[limit(5,7; range(9))]
null
[0,1,2,3,4,0,1,2,3,4,5,6]

# Same check for nth
[nth(5,7; range(9;0;-1))]
null
[4,2]

# Same check for range/3
[range(0,1,2;4,3,2;2,3)]
null
[0,2,0,3,0,2,0,0,0,1,3,1,1,1,1,1,2,2,2,2]

# Same check for range/1
[range(3,5)]
null
[0,1,2,0,1,2,3,4]

# Same check for index/1, rindex/1, indices/1
[(index(",","|"), rindex(",","|")), indices(",","|")]
"a,b|c,d,e||f,g,h,|,|,i,j"
[1,3,22,19,[1,5,7,12,14,16,18,20,22],[3,9,10,17,19]]

# Same check for join/1
join(",","/")
["a","b","c","d"]
"a,b,c,d"
"a/b/c/d"

[.[]|join("a")]
[[],[""],["",""],["","",""]]
["","","a","aa"]

# Same check for flatten/1
flatten(3,2,1)
[0, [1], [[2]], [[[3]]]]
[0,1,2,3]
[0,1,2,[3]]
[0,1,[2],[[3]]]


#
# Slices
#

[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]
[0,1,2,3,4,5,6]
[[], [2,3], [0,1,2,3,4], [5,6], [], []]

[.[3:2], .[-5:4], .[:-2], .[-2:], .[3:3][1:], .[10:]]
"abcdefghi"
["","","abcdefg","hi","",""]

del(.[2:4],.[0],.[-2:])
[0,1,2,3,4,5,6,7]
[1,4,5]

.[2:4] = ([], ["a","b"], ["a","b","c"])
[0,1,2,3,4,5,6,7]
[0,1,4,5,6,7]
[0,1,"a","b",4,5,6,7]
[0,1,"a","b","c",4,5,6,7]

# Slices at large offsets (issue #1108)
#
# This is written this way because [range(<large number>)] is
# significantly slower under valgrind than .[<large number>] = value.
#
# We range down rather than up so that we have just one realloc.
reduce range(65540;65536;-1) as $i ([]; .[$i] = $i)|.[65536:]
null
[null,65537,65538,65539,65540]

#
# Variables
#

1 as $x | 2 as $y | [$x,$y,$x]
null
[1,2,1]

[1,2,3][] as $x | [[4,5,6,7][$x]]
null
[5]
[6]
[7]

42 as $x | . | . | . + 432 | $x + 1
34324
43

1 + 2 as $x | -$x
null
-3

"x" as $x | "a"+"y" as $y | $x+","+$y
null
"x,ay"

1 as $x | [$x,$x,$x as $x | $x]
null
[1,1,1]

[1, {c:3, d:4}] as [$a, {c:$b, b:$c}] | $a, $b, $c
null
1
3
null

. as {as: $kw, "str": $str, ("e"+"x"+"p"): $exp} | [$kw, $str, $exp]
{"as": 1, "str": 2, "exp": 3}
[1, 2, 3]

.[] as [$a, $b] | [$b, $a]
[[1], [1, 2, 3]]
[null, 1]
[2, 1]

. as $i | . as [$i] | $i
[0]
0

. as [$i] | . as $i | $i
[0]
[0]

%%FAIL
. as [] | null
jq: error: syntax error, unexpected ']', expecting BINDING or '[' or '{' at <top-level>, line 1, column 7:
    . as [] | null
          ^

%%FAIL
. as {} | null
jq: error: syntax error, unexpected '}' at <top-level>, line 1, column 7:
    . as {} | null
          ^

%%FAIL
. as $foo | [$foo, $bar]
jq: error: $bar is not defined at <top-level>, line 1, column 20:
    . as $foo | [$foo, $bar]
                       ^^^^

%%FAIL
. as {(true):$foo} | $foo
jq: error: Cannot use boolean (true) as object key at <top-level>, line 1, column 8:
    . as {(true):$foo} | $foo
           ^^^^

# [.,(.[] | {x:.},.),.,.[]]

#
# Builtin functions
#

1+1
null
2

1+1
"wtasdf"
2.0

2-1
null
1

2-(-1)
null
3

1e+0+0.001e3
"I wonder what this will be?"
20e-1

.+4
15
19.0

.+null
{"a":42}
{"a":42}

null+.
null
null

.a+.b
{"a":42}
42

[1,2,3] + [.]
null
[1,2,3,null]

{"a":1} + {"b":2} + {"c":3}
"asdfasdf"
{"a":1, "b":2, "c":3}

"asdf" + "jkl;" + . + . + .
"some string"
"asdfjkl;some stringsome stringsome string"

"\u0000\u0020\u0000" + .
"\u0000\u0020\u0000"
"\u0000 \u0000\u0000 \u0000"

42 - .
11
31

[1,2,3,4,1] - [.,3]
1
[2,4]

[-1 as $x | 1,$x]
null
[1,-1]

[10 * 20, 20 / .]
4
[200, 5]

1 + 2 * 2 + 10 / 2
null
10

[16 / 4 / 2, 16 / 4 * 2, 16 - 4 - 2, 16 - 4 + 2]
null
[2, 8, 10, 14]

1e-19 + 1e-20 - 5e-21
null
1.05e-19

1 / 1e-17
null
1e+17

9E999999999, 9999999999E999999990, 1E-999999999, 0.000000001E-999999990
null
9E+999999999
9.999999999E+999999999
1E-999999999
1E-999999999

5E500000000 > 5E-5000000000, 10000E500000000 > 10000E-5000000000
null
true
true

# #2825
(1e999999999, 10e999999999) > (1e-1147483646, 0.1e-1147483646)
null
true
true
true
true

25 % 7
null
4

49732 % 472
null
172

[(infinite, -infinite) % (1, -1, infinite)]
null
[0,0,0,0,0,-1]

[nan % 1, 1 % nan | isnan]
null
[true,true]

1 + tonumber + ("10" | tonumber)
4
15

"123\u0000456" | try tonumber catch .
null
"string (\"123\\u0000456\") cannot be parsed as a number"

map(toboolean)
["false","true",false,true]
[false,true,false,true]

.[] | try toboolean catch .
[null,0,"tru","truee","fals","falsee",[],{}]
"null (null) cannot be parsed as a boolean"
"number (0) cannot be parsed as a boolean"
"string (\"tru\") cannot be parsed as a boolean"
"string (\"truee\") cannot be parsed as a boolean"
"string (\"fals\") cannot be parsed as a boolean"
"string (\"falsee\") cannot be parsed as a boolean"
"array ([]) cannot be parsed as a boolean"
"object ({}) cannot be parsed as a boolean"

"true\u0000x", "false\u0000" | try toboolean catch .
null
"string (\"true\\u0000x\") cannot be parsed as a boolean"
"string (\"false\\u0000\") cannot be parsed as a boolean"

[{"a":42},.object,10,.num,false,true,null,"b",[1,4]] | .[] as $x | [$x == .[]]
{"object": {"a":42}, "num":10.0}
[true,  true,  false, false, false, false, false, false, false]
[true,  true,  false, false, false, false, false, false, false]
[false, false, true,  true,  false, false, false, false, false]
[false, false, true,  true,  false, false, false, false, false]
[false, false, false, false, true,  false, false, false, false]
[false, false, false, false, false, true,  false, false, false]
[false, false, false, false, false, false, true,  false, false]
[false, false, false, false, false, false, false, true,  false]
[false, false, false, false, false, false, false, false, true ]

[.[] | length]
[[], {}, [1,2], {"a":42}, "asdf", "\u03bc"]
[0, 0, 2, 1, 4, 1]

utf8bytelength
"asdf\u03bc"
6

[.[] | try utf8bytelength catch .]
[[], {}, [1,2], 55, true, false]
["array ([]) only strings have UTF-8 byte length","object ({}) only strings have UTF-8 byte length","array ([1,2]) only strings have UTF-8 byte length","number (55) only strings have UTF-8 byte length","boolean (true) only strings have UTF-8 byte length","boolean (false) only strings have UTF-8 byte length"]


map(keys)
[{}, {"abcd":1,"abc":2,"abcde":3}, {"x":1, "z": 3, "y":2}]
[[], ["abc","abcd","abcde"], ["x","y","z"]]

[1,2,empty,3,empty,4]
null
[1,2,3,4]

map(add)
[[], [1,2,3], ["a","b","c"], [[3],[4,5],[6]], [{"a":1}, {"b":2}, {"a":3}]]
[null, 6, "abc", [3,4,5,6], {"a":3, "b": 2}]

map_values(.+1)
[0,1,2]
[1,2,3]

[add(null), add(range(range(10))), add(empty), add(10,range(10))]
null
[null,120,null,55]

# Real-world use case for add(empty)
.sum = add(.arr[])
{"arr":[]}
{"arr":[],"sum":null}

add({(.[]):1}) | keys
["a","a","b","a","d","b","d","a","d"]
["a","b","d"]

#
# User-defined functions
# Oh god.
#

def f: . + 1; def g: def g: . + 100; f | g | f; (f | g), g
3.0
106.0
105.0

def f: (1000,2000); f
123412345
1000
2000

def f(a;b;c;d;e;f): [a+1,b,c,d,e,f]; f(.[0];.[1];.[0];.[0];.[0];.[0])
[1,2]
[2,2,1,1,1,1]

def f: 1; def g: f, def f: 2; def g: 3; f, def f: g; f, g; def f: 4; [f, def f: g; def g: 5; f, g]+[f,g]
null
[4,1,2,3,3,5,4,1,2,3,3]

# Test precedence of 'def' vs '|'
def a: 0; . | a
null
0

# Many arguments
def f(a;b;c;d;e;f;g;h;i;j): [j,i,h,g,f,e,d,c,b,a]; f(.[0];.[1];.[2];.[3];.[4];.[5];.[6];.[7];.[8];.[9])
[0,1,2,3,4,5,6,7,8,9]
[9,8,7,6,5,4,3,2,1,0]

([1,2] + [4,5])
[1,2,3]
[1,2,4,5]

true
[1]
true

null,1,null
"hello"
null
1
null

[1,2,3]
[5,6]
[1,2,3]

[.[]|floor]
[-1.1,1.1,1.9]
[-2, 1, 1]

[.[]|sqrt]
[4,9]
[2,3]

(add / length) as $m | map((. - $m) as $d | $d * $d) | add / length | sqrt
[2,4,4,4,5,5,7,9]
2

# Should write a test that calls the -lm function from C (or bc(1)) to
# check that they match the corresponding jq functions.  However,
# there's so little template code standing between that it suffices to
# test a handful of these.  The results were checked by eye against
# bc(1).
atan * 4 * 1000000|floor / 1000000
1
3.141592

[(3.141592 / 2) * (range(0;20) / 20)|cos * 1000000|floor / 1000000]
null
[1,0.996917,0.987688,0.972369,0.951056,0.923879,0.891006,0.85264,0.809017,0.760406,0.707106,0.649448,0.587785,0.522498,0.45399,0.382683,0.309017,0.233445,0.156434,0.078459]

[(3.141592 / 2) * (range(0;20) / 20)|sin * 1000000|floor / 1000000]
null
[0,0.078459,0.156434,0.233445,0.309016,0.382683,0.45399,0.522498,0.587785,0.649447,0.707106,0.760405,0.809016,0.85264,0.891006,0.923879,0.951056,0.972369,0.987688,0.996917]


def f(x): x | x; f([.], . + [42])
[1,2,3]
[[[1,2,3]]]
[[1,2,3],42]
[[1,2,3,42]]
[1,2,3,42,42]

# test multiple function arities and redefinition
def f: .+1; def g: f; def f: .+100; def f(a):a+.+11; [(g|f(20)), f]
1
[33,101]

# test closures and lexical scoping
def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x | f($x,$x+x); g($x)
"more testing"
[1,100,2100.0,100,2100.0]

# test def f($a) syntax
def x(a;b): a as $a | b as $b | $a + $b; def y($a;$b): $a + $b; def check(a;b): [x(a;b)] == [y(a;b)]; check(.[];.[]*2)
[1,2,3]
true

# test backtracking through function calls and returns
# this test is *evil*
[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
999999999
[[110.0, 130.0], [210.0, 130.0], [110.0, 230.0], [210.0, 230.0], [120.0, 160.0], [220.0, 160.0], [120.0, 260.0], [220.0, 260.0]]

# test recursion
def fac: if . == 1 then 1 else . * (. - 1 | fac) end; [.[] | fac]
[1,2,3,4]
[1,2,6,24]

# test stack overflow and reallocation
# this test is disabled for now, it takes a realllllly long time.
# def f: if length > 1000 then . else .+[1]|f end; f | length
# []
# 1001

reduce .[] as $x (0; . + $x)
[1,2,4]
7

reduce .[] as [$i, {j:$j}] (0; . + $i - $j)
[[2,{"j":1}], [5,{"j":3}], [6,{"j":4}]]
5

reduce [[1,2,10], [3,4,10]][] as [$i,$j] (0; . + $i * $j)
null
14

[-reduce -.[] as $x (0; . + $x)]
[1,2,3]
[6]

[reduce .[] / .[] as $i (0; . + $i)]
[1,2]
[4.5]

reduce .[] as $x (0; . + $x) as $x | $x
[1,2,3]
6

# This, while useless, should still compile.
reduce . as $n (.; .)
null
null

# Destructuring
. as {$a, b: [$c, {$d}]} | [$a, $c, $d]
{"a":1, "b":[2,{"d":3}]}
[1,2,3]

. as {$a, $b:[$c, $d]}| [$a, $b, $c, $d]
{"a":1, "b":[2,{"d":3}]}
[1,[2,{"d":3}],2,{"d":3}]

# Destructuring with alternation
.[] | . as {$a, b: [$c, {$d}]} ?// [$a, {$b}, $e] ?// $f | [$a, $b, $c, $d, $e, $f]
[{"a":1, "b":[2,{"d":3}]}, [4, {"b":5, "c":6}, 7, 8, 9], "foo"]
[1, null, 2, 3, null, null]
[4, 5, null, null, 7, null]
[null, null, null, null, null, "foo"]

# Destructuring DUP/POP issues
.[] | . as {a:$a} ?// {a:$a} ?// {a:$a} | $a
[[3],[4],[5],6]
# Runtime error: "jq: Cannot index array with string (\"c\")"

.[] as {a:$a} ?// {a:$a} ?// {a:$a} | $a
[[3],[4],[5],6]
# Runtime error: "jq: Cannot index array with string (\"c\")"

[[3],[4],[5],6][] | . as {a:$a} ?// {a:$a} ?// {a:$a} | $a
null
# Runtime error: "jq: Cannot index array with string (\"c\")"

[[3],[4],[5],6] | .[] as {a:$a} ?// {a:$a} ?// {a:$a} | $a
null
# Runtime error: "jq: Cannot index array with string (\"c\")"

.[] | . as {a:$a} ?// {a:$a} ?// $a | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

.[] as {a:$a} ?// {a:$a} ?// $a | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

[[3],[4],[5],6][] | . as {a:$a} ?// {a:$a} ?// $a | $a
null
[3]
[4]
[5]
6

[[3],[4],[5],6] | .[] as {a:$a} ?// {a:$a} ?// $a | $a
null
[3]
[4]
[5]
6

.[] | . as {a:$a} ?// $a ?// {a:$a} | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

.[] as {a:$a} ?// $a ?// {a:$a} | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

[[3],[4],[5],6][] | . as {a:$a} ?// $a ?// {a:$a} | $a
null
[3]
[4]
[5]
6

[[3],[4],[5],6] | .[] as {a:$a} ?// $a ?// {a:$a} | $a
null
[3]
[4]
[5]
6

.[] | . as $a ?// {a:$a} ?// {a:$a} | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

.[] as $a ?// {a:$a} ?// {a:$a} | $a
[[3],[4],[5],6]
[3]
[4]
[5]
6

[[3],[4],[5],6][] | . as $a ?// {a:$a} ?// {a:$a} | $a
null
[3]
[4]
[5]
6

[[3],[4],[5],6] | .[] as $a ?// {a:$a} ?// {a:$a} | $a
null
[3]
[4]
[5]
6

. as $dot|any($dot[];not)
[1,2,3,4,true,false,1,2,3,4,5]
true

. as $dot|any($dot[];not)
[1,2,3,4,true]
false

. as $dot|all($dot[];.)
[1,2,3,4,true,false,1,2,3,4,5]
false

. as $dot|all($dot[];.)
[1,2,3,4,true]
true

# Check short-circuiting
any(true, error; .)
"badness"
true

all(false, error; .)
"badness"
false

any(not)
[]
false

all(not)
[]
true

any(not)
[false]
true

all(not)
[false]
true

[any,all]
[]
[false,true]

[any,all]
[true]
[true,true]

[any,all]
[false]
[false,false]

[any,all]
[true,false]
[true,false]

[any,all]
[null,null,true]
[true,false]

#
# Paths
#

path(.foo[0,1])
null
["foo", 0]
["foo", 1]

path(.[] | select(.>3))
[1,5,3]
[1]

path(.)
42
[]

try path(.a | map(select(.b == 0))) catch .
{"a":[{"b":0}]}
"Invalid path expression with result [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .[0]) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to access element 0 of [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .c) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to access element \"c\" of [{\"b\":0}]"

try path(.a | map(select(.b == 0)) | .[]) catch .
{"a":[{"b":0}]}
"Invalid path expression near attempt to iterate through [{\"b\":0}]"

path(.a[path(.b)[0]])
{"a":{"b":0}}
["a","b"]

[paths]
[1,[[],{"a":2}]]
[[0],[1],[1,0],[1,1],[1,1,"a"]]

["foo",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])
{"bar": 42, "foo": ["a", "b", "c", "d"]}
"b"
{"bar": 42, "foo": ["a", 20, "c", "d"]}
{"bar": 42, "foo": ["a", "c", "d"]}

map(getpath([2])), map(setpath([2]; 42)), map(delpaths([[2]]))
[[0], [0,1], [0,1,2]]
[null, null, 2]
[[0,null,42], [0,1,42], [0,1,42]]
[[0], [0,1], [0,1]]

map(delpaths([[0,"foo"]]))
[[{"foo":2, "x":1}], [{"bar":2}]]
[[{"x":1}], [{"bar":2}]]

["foo",1] as $p | getpath($p), setpath($p; 20), delpaths([$p])
{"bar":false}
null
{"bar":false, "foo": [null, 20]}
{"bar":false}

delpaths([[-200]])
[1,2,3]
[1,2,3]

try delpaths(0) catch .
{}
"Paths must be specified as an array"

del(.), del(empty), del((.foo,.bar,.baz) | .[2,3,0]), del(.foo[0], .bar[0], .foo, .baz.bar[0].x)
{"foo": [0,1,2,3,4], "bar": [0,1]}
null
{"foo": [0,1,2,3,4], "bar": [0,1]}
{"foo": [1,4], "bar": [1]}
{"bar": [1]}

del(.[1], .[-6], .[2], .[-3:9])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 3, 5, 6, 9]

del(.[nan])
[1,2,3]
[1,2,3]

del(.[nan,nan])
[1,2,3]
[1,2,3]

# negative index
setpath([-1]; 1)
[0]
[1]

pick(.a.b.c)
null
{"a":{"b":{"c":null}}}

pick(first)
[1,2]
[1]

pick(first|first)
[[10,20],30]
[[10]]

# negative indices in path expressions (since last/1 is .[-1])
try pick(last) catch .
[1,2]
"Out of bounds negative array index"

#
# Assignment
#
.message = "goodbye"
{"message": "hello"}
{"message": "goodbye"}

.foo = .bar
{"bar":42}
{"foo":42, "bar":42}

.foo |= .+1
{"foo": 42}
{"foo": 43}

.[] += 2, .[] *= 2, .[] -= 2, .[] /= 2, .[] %=2
[1,3,5]
[3,5,7]
[2,6,10]
[-1,1,3]
[0.5, 1.5, 2.5]
[1,1,1]

[.[] % 7]
[-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7]
[0,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,0]

.foo += .foo
{"foo":2}
{"foo":4}

.[0].a |= {"old":., "new":(.+1)}
[{"a":1,"b":2}]
[{"a":{"old":1, "new":2},"b":2}]

def inc(x): x |= .+1; inc(.[].a)
[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]

# #1358, getpath/1 should work in path expressions
.[] | try (getpath(["a",0,"b"]) |= 5) catch .
[null,{"b":0},{"a":0},{"a":null},{"a":[0,1]},{"a":{"b":1}},{"a":[{}]},{"a":[{"c":3}]}]
{"a":[{"b":5}]}
{"b":0,"a":[{"b":5}]}
"Cannot index number with number (0)"
{"a":[{"b":5}]}
"Cannot index number with string (\"b\")"
"Cannot index object with number (0)"
{"a":[{"b":5}]}
{"a":[{"c":3,"b":5}]}

# #2051, deletion using assigning empty against arrays
(.[] | select(. >= 2)) |= empty
[1,5,3,0,7]
[1,0]

.[] |= select(. % 2 == 0)
[0,1,2,3,4,5]
[0,2,4]

.foo[1,4,2,3] |= empty
{"foo":[0,1,2,3,4,5]}
{"foo":[0,5]}

.[2][3] = 1
[4]
[4, null, [null, null, null, 1]]

.foo[2].bar = 1
{"foo":[11], "bar":42}
{"foo":[11,null,{"bar":1}], "bar":42}

try ((map(select(.a == 1))[].b) = 10) catch .
[{"a":0},{"a":1}]
"Invalid path expression near attempt to iterate through [{\"a\":1}]"

try ((map(select(.a == 1))[].a) |= .+1) catch .
[{"a":0},{"a":1}]
"Invalid path expression near attempt to iterate through [{\"a\":1}]"

def x: .[1,2]; x=10
[0,1,2]
[0,10,10]

try (def x: reverse; x=10) catch .
[0,1,2]
"Invalid path expression with result [2,1,0]"

.[] = 1
[1,null,Infinity,-Infinity,NaN,-NaN]
[1,1,1,1,1,1]

#
# Conditionals
#

[.[] | if .foo then "yep" else "nope" end]
[{"foo":0},{"foo":1},{"foo":[]},{"foo":true},{"foo":false},{"foo":null},{"foo":"foo"},{}]
["yep","yep","yep","yep","nope","nope","yep","nope"]

[.[] | if .baz then "strange" elif .foo then "yep" else "nope" end]
[{"foo":0},{"foo":1},{"foo":[]},{"foo":true},{"foo":false},{"foo":null},{"foo":"foo"},{}]
["yep","yep","yep","yep","nope","nope","yep","nope"]

[if 1,null,2 then 3 else 4 end]
null
[3,4,3]

[if empty then 3 else 4 end]
null
[]

[if 1 then 3,4 else 5 end]
null
[3,4]

[if null then 3 else 5,6 end]
null
[5,6]

[if true then 3 end]
7
[3]

[if false then 3 end]
7
[7]

[if false then 3 else . end]
7
[7]

[if false then 3 elif false then 4 end]
7
[7]

[if false then 3 elif false then 4 else . end]
7
[7]

[-if true then 1 else 2 end]
null
[-1]

{x: if true then 1 else 2 end}
null
{"x":1}

if true then [.] else . end []
null
null

[.[] | [.foo[] // .bar]]
[{"foo":[1,2], "bar": 42}, {"foo":[1], "bar": null}, {"foo":[null,false,3], "bar": 18}, {"foo":[], "bar":42}, {"foo": [null,false,null], "bar": 41}]
[[1,2], [1], [3], [42], [41]]

.[] //= .[0]
["hello",true,false,[false],null]
["hello",true,"hello",[false],"hello"]

.[] | [.[0] and .[1], .[0] or .[1]]
[[true,[]], [false,1], [42,null], [null,false]]
[true,true]
[false,true]
[false,true]
[false,false]

[.[] | not]
[1,0,false,null,true,"hello"]
[false,false,true,true,false,false]

# Check numeric comparison binops
[10 > 0, 10 > 10, 10 > 20, 10 < 0, 10 < 10, 10 < 20]
{}
[true,false,false,false,false,true]

[10 >= 0, 10 >= 10, 10 >= 20, 10 <= 0, 10 <= 10, 10 <= 20]
{}
[true,true,false,false,true,true]

# And some in/equality tests
[ 10 == 10, 10 != 10, 10 != 11, 10 == 11]
{}
[true,false,true,false]

["hello" == "hello", "hello" != "hello", "hello" == "world", "hello" != "world" ]
{}
[true,false,false,true]

[[1,2,3] == [1,2,3], [1,2,3] != [1,2,3], [1,2,3] == [4,5,6], [1,2,3] != [4,5,6]]
{}
[true,false,false,true]

[{"foo":42} == {"foo":42},{"foo":42} != {"foo":42}, {"foo":42} != {"bar":42}, {"foo":42} == {"bar":42}]
{}
[true,false,true,false]

# ugly complicated thing
[{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":18},"world"]},{"foo":[1,2,{"bar":18},"world"]} == {"foo":[1,2,{"bar":19},"world"]}]
{}
[true,false]

# containment operator
[("foo" | contains("foo")), ("foobar" | contains("foo")), ("foo" | contains("foobar"))]
{}
[true, true, false]

# containment operator (embedded NULs!)
[contains(""), contains("\u0000")]
"\u0000"
[true, true]

[contains(""), contains("a"), contains("ab"), contains("c"), contains("d")]
"ab\u0000cd"
[true, true, true, true, true]

[contains("cd"), contains("b\u0000"), contains("ab\u0000")]
"ab\u0000cd"
[true, true, true]

[contains("b\u0000c"), contains("b\u0000cd"), contains("b\u0000cd")]
"ab\u0000cd"
[true, true, true]

[contains("@"), contains("\u0000@"), contains("\u0000what")]
"ab\u0000cd"
[false, false, false]


# Try/catch and general `?` operator
[.[]|try if . == 0 then error("foo") elif . == 1 then .a elif . == 2 then empty else . end catch .]
[0,1,2,3]
["foo","Cannot index number with string (\"a\")",3]

[.[]|(.a, .a)?]
[null,true,{"a":1}]
[null,null,1,1]

[[.[]|[.a,.a]]?]
[null,true,{"a":1}]
[]

[if error then 1 else 2 end?]
"foo"
[]

try error(0) // 1
null
1

1, try error(2), 3
null
1
3

1 + try 2 catch 3 + 4
null
7

[-try .]
1
[-1]

try -.? catch .
"foo"
"string (\"foo\") cannot be negated"

{x: try 1, y: try error catch 2, z: if true then 3 end}
null
{"x":1,"y":2,"z":3}

{x: 1 + 2, y: false or true, z: null // 3}
null
{"x":3,"y":true,"z":3}

.[] | try error catch .
[1,null,2]
1
null
2

try error("\($__loc__)") catch .
null
"{\"file\":\"<top-level>\",\"line\":1}"

# string operations
[.[]|startswith("foo")]
["fo", "foo", "barfoo", "foobar", "barfoob"]
[false, true, false, true, false]

[.[]|endswith("foo")]
["fo", "foo", "barfoo", "foobar", "barfoob"]
[false, true, true, false, false]

[.[] | split(", ")]
["a,b, c, d, e,f",", a,b, c, d, e,f, "]
[["a,b","c","d","e,f"],["","a,b","c","d","e,f",""]]

split("")
"abc"
["a","b","c"]

[.[]|ltrimstr("foo")]
["fo", "foo", "barfoo", "foobar", "afoo"]
["fo","","barfoo","bar","afoo"]

[.[]|rtrimstr("foo")]
["fo", "foo", "barfoo", "foobar", "foob"]
["fo","","bar","foobar","foob"]

[.[]|trimstr("foo")]
["fo", "foo", "barfoo", "foobarfoo", "foob"]
["fo","","bar","bar","b"]

[.[]|ltrimstr("")]
["a", "xx", ""]
["a", "xx", ""]

[.[]|rtrimstr("")]
["a", "xx", ""]
["a", "xx", ""]

[.[]|trimstr("")]
["a", "xx", ""]
["a", "xx", ""]

[(index(","), rindex(",")), indices(",")]
"a,bc,def,ghij,klmno"
[1,13,[1,4,8,13]]

[ index("aba"), rindex("aba"), indices("aba") ]
"xababababax"
[1,7,[1,3,5,7]]

# _strindices is used by indices/1 but is callable
try _strindices("abc") catch .
123
"number (123) cannot be searched, as it is not a string"

try _strindices(123) catch .
"abc"
"number (123) is not a string"

# trim
# \u000b is vertical tab (\v not supported by json)
map(trim), map(ltrim), map(rtrim)
[" \n\t\r\f\u000b", "","  ", "a", " a ", "abc", "  abc  ", "  abc", "abc  "]
["", "", "", "a", "a", "abc", "abc", "abc", "abc"]
["", "", "", "a", "a ", "abc", "abc  ", "abc", "abc  "]
["", "", "", "a", " a", "abc", "  abc", "  abc", "abc"]

trim, ltrim, rtrim
"\u0009\u000A\u000B\u000C\u000D\u0020\u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000abc\u0009\u000A\u000B\u000C\u000D\u0020\u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000"
"abc"
"abc\u0009\u000A\u000B\u000C\u000D\u0020\u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000"
"\u0009\u000A\u000B\u000C\u000D\u0020\u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000abc"

try trim catch ., try ltrim catch ., try rtrim catch .
123
"trim input must be a string"
"trim input must be a string"
"trim input must be a string"

indices(1)
[0,1,1,2,3,4,1,5]
[1,2,6]

indices([1,2])
[0,1,2,3,1,4,2,5,1,2,6,7]
[1,8]

indices([1,2])
[1]
[]

indices(", ")
"a,b, cd,e, fgh, ijkl"
[3,9,14]

index("!")
"здравствуй мир!"
14

.[:rindex("x")]
"正xyz"
"正"

indices("o")
"🇬🇧oo"
[2,3]

indices("o")
"ƒoo"
[1,2]

[.[]|split(",")]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]

[.[]|split(", ")]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a","bc","def","ghij","jklmn","a,b","c,d","e,f"],["a,b,c,d","e,f,g,h"]]

[.[] * 3]
["a", "ab", "abc"]
["aaa", "ababab", "abcabcabc"]

[.[] * "abc"]
[-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 3.7, 10.0]
[null,null,"","","abc","abc","abcabcabc","abcabcabcabcabcabcabcabcabcabc"]

[. * (nan,-nan)]
"abc"
[null,null]

. * 100000 | [.[:10],.[-10:]]
"abc"
["abcabcabca","cabcabcabc"]

. * 1000000000
""
""

try (. * 1000000000) catch .
"abc"
"Repeat string result too long"

[.[] / ","]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]

[.[] / ", "]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a","bc","def","ghij","jklmn","a,b","c,d","e,f"],["a,b,c,d","e,f,g,h"]]

map(.[1] as $needle | .[0] | contains($needle))
[[[],[]], [[1,2,3], [1,2]], [[1,2,3], [3,1]], [[1,2,3], [4]], [[1,2,3], [1,4]]]
[true, true, true, false, false]

map(.[1] as $needle | .[0] | contains($needle))
[[["foobar", "foobaz"], ["baz", "bar"]], [["foobar", "foobaz"], ["foo"]], [["foobar", "foobaz"], ["blap"]]]
[true, true, false]

[({foo: 12, bar:13} | contains({foo: 12})), ({foo: 12} | contains({})), ({foo: 12, bar:13} | contains({baz:14}))]
{}
[true, true, false]

{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {}}})
{}
true

{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {bar: 14}}})
{}
false

sort
[42,[2,5,3,11],10,{"a":42,"b":2},{"a":42},true,2,[2,6],"hello",null,[2,5,6],{"a":[],"b":1},"abc","ab",[3,10],{},false,"abcd",null]
[null,null,false,true,2,10,42,"ab","abc","abcd","hello",[2,5,3,11],[2,5,6],[2,6],[3,10],{},{"a":42},{"a":42,"b":2},{"a":[],"b":1}]

(sort_by(.b) | sort_by(.a)), sort_by(.a, .b), sort_by(.b, .c), group_by(.b), group_by(.a + .b - .c == 2)
[{"a": 1, "b": 4, "c": 14}, {"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}, {"a": 0, "b": 2, "c": 43}]
[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}]
[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}]
[{"a": 4, "b": 1, "c": 3}, {"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 3}, {"a": 1, "b": 4, "c": 14}]
[[{"a": 4, "b": 1, "c": 3}], [{"a": 0, "b": 2, "c": 43}], [{"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}]]
[[{"a": 1, "b": 4, "c": 14}, {"a": 0, "b": 2, "c": 43}], [{"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}]]

unique
[1,2,5,3,5,3,1,3]
[1,2,3,5]

unique
[]
[]

[min, max, min_by(.[1]), max_by(.[1]), min_by(.[2]), max_by(.[2])]
[[4,2,"a"],[3,1,"a"],[2,4,"a"],[1,3,"a"]]
[[1,3,"a"],[4,2,"a"],[3,1,"a"],[2,4,"a"],[4,2,"a"],[1,3,"a"]]

[min,max,min_by(.),max_by(.)]
[]
[null,null,null,null]

.foo[.baz]
{"foo":{"bar":4},"baz":"bar"}
4

.[] | .error = "no, it's OK"
[{"error":true}]
{"error": "no, it's OK"}

[{a:1}] | .[] | .a=999
null
{"a": 999}

to_entries
{"a": 1, "b": 2}
[{"key":"a", "value":1}, {"key":"b", "value":2}]

from_entries
[{"key":"a", "value":1}, {"Key":"b", "Value":2}, {"name":"c", "value":3}, {"Name":"d", "Value":4}]
{"a": 1, "b": 2, "c": 3, "d": 4}

with_entries(.key |= "KEY_" + .)
{"a": 1, "b": 2}
{"KEY_a": 1, "KEY_b": 2}

map(has("foo"))
[{"foo": 42}, {}]
[true, false]

map(has(2))
[[0,1], ["a","b","c"]]
[false, true]

has(nan)
[0,1,2]
false

keys
[42,3,35]
[0,1,2]

[][.]
1000000000000000000
null

map([1,2][0:.])
[-1, 1, 2, 3, 1000000000000000000]
[[1], [1], [1,2], [1,2], [1,2]]

# Test recursive object merge

{"k": {"a": 1, "b": 2}} * .
{"k": {"a": 0,"c": 3}}
{"k": {"a": 0, "b": 2, "c": 3}}

{"k": {"a": 1, "b": 2}, "hello": {"x": 1}} * .
{"k": {"a": 0,"c": 3}, "hello": 1}
{"k": {"a": 0, "b": 2, "c": 3}, "hello": 1}

{"k": {"a": 1, "b": 2}, "hello": 1} * .
{"k": {"a": 0,"c": 3}, "hello": {"x": 1}}
{"k": {"a": 0, "b": 2, "c": 3}, "hello": {"x": 1}}

{"a": {"b": 1}, "c": {"d": 2}, "e": 5} * .
{"a": {"b": 2}, "c": {"d": 3, "f": 9}}
{"a": {"b": 2}, "c": {"d": 3, "f": 9}, "e": 5}

[.[]|arrays]
[1,2,"foo",[],[3,[]],{},true,false,null]
[[],[3,[]]]

[.[]|objects]
[1,2,"foo",[],[3,[]],{},true,false,null]
[{}]

[.[]|iterables]
[1,2,"foo",[],[3,[]],{},true,false,null]
[[],[3,[]],{}]

[.[]|scalars]
[1,2,"foo",[],[3,[]],{},true,false,null]
[1,2,"foo",true,false,null]

[.[]|values]
[1,2,"foo",[],[3,[]],{},true,false,null]
[1,2,"foo",[],[3,[]],{},true,false]

[.[]|booleans]
[1,2,"foo",[],[3,[]],{},true,false,null]
[true,false]

[.[]|nulls]
[1,2,"foo",[],[3,[]],{},true,false,null]
[null]

flatten
[0, [1], [[2]], [[[3]]]]
[0, 1, 2, 3]

flatten(0)
[0, [1], [[2]], [[[3]]]]
[0, [1], [[2]], [[[3]]]]

flatten(2)
[0, [1], [[2]], [[[3]]]]
[0, 1, 2, [3]]

flatten(2)
[0, [1, [2]], [1, [[3], 2]]]
[0, 1, 2, 1, [3], 2]

try flatten(-1) catch .
[0, [1], [[2]], [[[3]]]]
"flatten depth must not be negative"

transpose
[[1], [2,3]]
[[1,2],[null,3]]

transpose
[]
[]

ascii_upcase
"useful but not for é"
"USEFUL BUT NOT FOR é"

bsearch(0,1,2,3,4)
[1,2,3]
-1
0
1
2
-4

bsearch({x:1})
[{ "x": 0 },{ "x": 1 },{ "x": 2 }]
1

try ["OK", bsearch(0)] catch ["KO",.]
"aa"
["KO","string (\"aa\") cannot be searched from"]

strftime("%Y-%m-%dT%H:%M:%SZ")
[2015,2,5,23,51,47,4,63]
"2015-03-05T23:51:47Z"

strftime("%A, %B %d, %Y")
1435677542.822351
"Tuesday, June 30, 2015"

strftime("%Y-%m-%dT%H:%M:%SZ")
[2024,2,15]
"2024-03-15T00:00:00Z"

mktime
[2024,8,21]
1726876800

gmtime
1425599507
[2015,2,5,23,51,47,4,63]

gmtime[5]
1425599507.25
47.25

# test invalid tm input
try strftime("%Y-%m-%dT%H:%M:%SZ") catch .
["a",1,2,3,4,5,6,7]
"strftime/1 requires parsed datetime inputs"

try strflocaltime("%Y-%m-%dT%H:%M:%SZ") catch .
["a",1,2,3,4,5,6,7]
"strflocaltime/1 requires parsed datetime inputs"

try mktime catch .
["a",1,2,3,4,5,6,7]
"mktime requires parsed datetime inputs"

# oss-fuzz #67403: non-string argument with number input fails assert
try ["OK", strftime([])] catch ["KO", .]
0
["KO","strftime/1 requires a string format"]

try ["OK", strflocaltime({})] catch ["KO", .]
0
["KO","strflocaltime/1 requires a string format"]

[strptime("%Y-%m-%dT%H:%M:%SZ")|(.,mktime)]
"2015-03-05T23:51:47Z"
[[2015,2,5,23,51,47,4,63],1425599507]

# Check day-of-week and day of year computations
# (should trip an assert if this fails)
last(range(365 * 67)|("1970-03-01T01:02:03Z"|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime) + (86400 * .)|strftime("%Y-%m-%dT%H:%M:%SZ")|strptime("%Y-%m-%dT%H:%M:%SZ"))
null
[2037,1,11,1,2,3,3,41]

# module system
import "a" as foo; import "b" as bar; def fooa: foo::a; [fooa, bar::a, bar::b, foo::a]
null
["a","b","c","a"]

import "c" as foo; [foo::a, foo::c]
null
[0,"acmehbah"]

include "c"; [a, c]
null
[0,"acmehbah"]

import "data" as $e; import "data" as $d; [$d[].this,$e[].that,$d::d[].this,$e::e[].that]|join(";")
null
"is a test;is too;is a test;is too"

# Regression test for #2000
import "data" as $a; import "data" as $b; def f: {$a, $b}; f
null
{"a":[{"this":"is a test","that":"is too"}],"b":[{"this":"is a test","that":"is too"}]}

include "shadow1"; e
null
2

include "shadow1"; include "shadow2"; e
null
3

import "shadow1" as f; import "shadow2" as f; import "shadow1" as e; [e::e, f::e]
null
[2,3]

%%FAIL
module (.+1); 0
jq: error: Module metadata must be constant at <top-level>, line 1, column 8:
    module (.+1); 0
           ^^^^^

%%FAIL
module []; 0
jq: error: Module metadata must be an object at <top-level>, line 1, column 8:
    module []; 0
           ^^

%%FAIL
include "a" (.+1); 0
jq: error: Module metadata must be constant at <top-level>, line 1, column 13:
    include "a" (.+1); 0
                ^^^^^

%%FAIL
include "a" []; 0
jq: error: Module metadata must be an object at <top-level>, line 1, column 13:
    include "a" []; 0
                ^^

%%FAIL
include "\ "; 0
jq: error: Invalid escape at line 1, column 4 (while parsing '"\ "') at <top-level>, line 1, column 10:
    include "\ "; 0
             ^^

%%FAIL
include "\(a)"; 0
jq: error: Import path must be constant at <top-level>, line 1, column 9:
    include "\(a)"; 0
            ^^^^^^

modulemeta
"c"
{"whatever":null,"deps":[{"as":"foo","is_data":false,"relpath":"a"},{"search":"./","as":"d","is_data":false,"relpath":"d"},{"search":"./","as":"d2","is_data":false,"relpath":"d"},{"search":"./../lib/jq","as":"e","is_data":false,"relpath":"e"},{"search":"./../lib/jq","as":"f","is_data":false,"relpath":"f"},{"as":"d","is_data":true,"relpath":"data"}],"defs":["a/0","c/0"]}

modulemeta | .deps | length
"c"
6

modulemeta | .defs | length
"c"
2

%%FAIL IGNORE MSG
import "syntaxerror" as e; .
jq: error: syntax error, unexpected ';', expecting end of file at tests/modules/syntaxerror/syntaxerror.jq, line 1, column 4:
    wat;
       ^

%%FAIL
%::wat
jq: error: syntax error, unexpected '%', expecting end of file at <top-level>, line 1, column 1:
    %::wat
    ^

import "test_bind_order" as check; check::check
null
true

try -. catch .
"very-long-long-long-long-string"
"string (\"very-long-long-long-long...\") cannot be negated"

try (.-.) catch .
"very-long-long-long-long-string"
"string (\"very-long-long-long-long...\") and string (\"very-long-long-long-long...\") cannot be subtracted"

"x" * range(0; 12; 2) + "☆" * 8 | try -. catch .
null
"string (\"☆☆☆☆☆☆☆☆\") cannot be negated"
"string (\"xx☆☆☆☆☆☆☆☆\") cannot be negated"
"string (\"xxxx☆☆☆☆☆☆...\") cannot be negated"
"string (\"xxxxxx☆☆☆☆☆☆...\") cannot be negated"
"string (\"xxxxxxxx☆☆☆☆☆...\") cannot be negated"
"string (\"xxxxxxxxxx☆☆☆☆...\") cannot be negated"

try (. + "x") catch . == if have_decnum then "number (12345678901234567890123456...) and string (\"x\") cannot be added" else "number (12345678901234568000000000...) and string (\"x\") cannot be added" end
123456789012345678901234567890
true

join(",")
["1",2,true,false,3.4]
"1,2,true,false,3.4"

.[] | join(",")
[[], [null], [null,null], [null,null,null]]
""
""
","
",,"

.[] | join(",")
[["a",null], [null,"a"]]
"a,"
",a"

try join(",") catch .
["1","2",{"a":{"b":{"c":33}}}]
"string (\"1,2,\") and object ({\"a\":{\"b\":{\"c\":33}}}) cannot be added"

try join(",") catch .
["1","2",[3,4,5]]
"string (\"1,2,\") and array ([3,4,5]) cannot be added"

{if:0,and:1,or:2,then:3,else:4,elif:5,end:6,as:7,def:8,reduce:9,foreach:10,try:11,catch:12,label:13,import:14,include:15,module:16}
null
{"if":0,"and":1,"or":2,"then":3,"else":4,"elif":5,"end":6,"as":7,"def":8,"reduce":9,"foreach":10,"try":11,"catch":12,"label":13,"import":14,"include":15,"module":16}

try (1/.) catch .
0
"number (1) and number (0) cannot be divided because the divisor is zero"

try (1/0) catch .
0
"number (1) and number (0) cannot be divided because the divisor is zero"

try (0/0) catch .
0
"number (0) and number (0) cannot be divided because the divisor is zero"

try (1%.) catch .
0
"number (1) and number (0) cannot be divided (remainder) because the divisor is zero"

try (1%0) catch .
0
"number (1) and number (0) cannot be divided (remainder) because the divisor is zero"

# Basic numbers tests: integers, powers of two
[range(-52;52;1)] as $powers | [$powers[]|pow(2;.)|log2|round] == $powers
null
true

[range(-99/2;99/2;1)] as $orig | [$orig[]|pow(2;.)|log2] as $back | ($orig|keys)[]|. as $k | (($orig|.[$k])-($back|.[$k]))|if . < 0 then . * -1 else . end|select(.>.00005)
null

%%FAIL
{
jq: error: syntax error, unexpected end of file at <top-level>, line 1, column 1:
    {
    ^

%%FAIL
}
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting end of file at <top-level>, line 1, column 1:
    }
    ^

(.[{}] = 0)?
null

INDEX(range(5)|[., "foo\(.)"]; .[0])
null
{"0":[0,"foo0"],"1":[1,"foo1"],"2":[2,"foo2"],"3":[3,"foo3"],"4":[4,"foo4"]}

JOIN({"0":[0,"abc"],"1":[1,"bcd"],"2":[2,"def"],"3":[3,"efg"],"4":[4,"fgh"]}; .[0]|tostring)
[[5,"foo"],[3,"bar"],[1,"foobar"]]
[[[5,"foo"],null],[[3,"bar"],[3,"efg"]],[[1,"foobar"],[1,"bcd"]]]

range(5;10)|IN(range(10))
null
true
true
true
true
true

range(5;13)|IN(range(0;10;3))
null
false
true
false
false
true
false
false
false

range(10;12)|IN(range(10))
null
false
false

IN(range(10;20); range(10))
null
false

IN(range(5;20); range(10))
null
true

# Regression test for #1347
(.a as $x | .b) = "b"
{"a":null,"b":null}
{"a":null,"b":"b"}

# Regression test for #1368
(.. | select(type == "object" and has("b") and (.b | type) == "array")|.b) |= .[0]
{"a": {"b": [1, {"b": 3}]}}
{"a": {"b": 1}}

isempty(empty)
null
true

isempty(range(3))
null
false

isempty(1,error("foo"))
null
false

# Regression test for #1815
index("")
""
null

# check that dead code removal occurs after builtin it generation
builtins|length > 10
null
true

"-1"|IN(builtins[] / "/"|.[1])
null
false

all(builtins[] / "/"; .[1]|tonumber >= 0)
null
true

builtins|any(.[:1] == "_")
null
false

## Test ability to use keywords (uncomment after eval is pushed)
#(.[] as $kw | "\"{\($kw)} as $\($kw) | $\($kw) | {$\($kw)} | {\($kw):.\($kw)}\""|eval|empty),null
#["as","def","module","import","include","if","then","else","elif","end","reduce","foreach","and","or","try","catch","label","break","__loc__"]
#null
#
#(.[] as $kw | "\"def f($\($kw)): $\($kw); f(.)\""|eval|empty),null
#["as","def","module","import","include","if","then","else","elif","end","reduce","foreach","and","or","try","catch","label","break","__loc__"]
#null


#
# Tests to cover the new toliteral number functionality
# For an example see #1652 and other linked issues
#

# We are backward and sanity compatible

map(. == 1)
[1, 1.0, 1.000, 100e-2, 1e+0, 0.0001e4]
[true, true, true, true, true, true]

# When no arithmetic is involved jq should preserve the literal value

.[0] | tostring | . == if have_decnum then "13911860366432393" else "13911860366432392" end
[13911860366432393]
true

.x | tojson | . == if have_decnum then "13911860366432393" else "13911860366432392" end
{"x":13911860366432393}
true

(13911860366432393 == 13911860366432392) | . == if have_decnum then false else true end
null
true


# Applying arithmetic to the value will truncate the result to double

. - 10
13911860366432393
13911860366432382

.[0] - 10
[13911860366432393]
13911860366432382

.x - 10
{"x":13911860366432393}
13911860366432382

# Unary negation preserves numerical precision
-. | tojson == if have_decnum then "-13911860366432393" else "-13911860366432392" end
13911860366432393
true

-. | tojson == if have_decnum then "0.12345678901234567890123456789" else "0.12345678901234568" end
-0.12345678901234567890123456789
true

[1E+1000,-1E+1000 | tojson] == if have_decnum then ["1E+1000","-1E+1000"] else ["1.7976931348623157e+308","-1.7976931348623157e+308"] end
null
true

. |= try . catch .
1
1

# decnum to double conversion
.[] as $n | $n+0 | [., tostring, . == $n]
[-9007199254740993, -9007199254740992, 9007199254740992, 9007199254740993, 13911860366432393]
[-9007199254740992,"-9007199254740992",true]
[-9007199254740992,"-9007199254740992",true]
[9007199254740992,"9007199254740992",true]
[9007199254740992,"9007199254740992",true]
[13911860366432392,"13911860366432392",true]

# abs, fabs, length
abs
"abc"
"abc"

map(abs)
[-0, 0, -10, -1.1]
[0,0,10,1.1]

map(fabs)
[-0, 0, -10, -1.1]
[0,0,10,1.1]

map(abs == length) | unique
[-10, -1.1, -1e-1, 1000000000000000002]
[true]

# The following is NOT prescriptive:
map(abs)
[0.1,1000000000000000002]
[1e-1, 1000000000000000002]

[1E+1000,-1E+1000 | abs | tojson] | unique == if have_decnum then ["1E+1000"] else ["1.7976931348623157e+308"] end
null
true

[1E+1000,-1E+1000 | length | tojson] | unique == if have_decnum then ["1E+1000"] else ["1.7976931348623157e+308"] end
null
true

# Using a keyword as variable/label name

123 as $label | $label
null
123

[ label $if | range(10) | ., (select(. == 5) | break $if) ]
null
[0,1,2,3,4,5]

reduce .[] as $then (4 as $else | $else; . as $elif | . + $then * $elif)
[1,2,3]
96

1 as $foreach | 2 as $and | 3 as $or | { $foreach, $and, $or, a }
{"a":4,"b":5}
{"foreach":1,"and":2,"or":3,"a":4}

[ foreach .[] as $try (1 as $catch | $catch - 1; . + $try; .) ]
[10,9,8,7]
[10,19,27,34]


# Object construction

{ a, $__loc__, c }
{"a":[1,2,3],"b":"foo","c":{"hi":"hey"}}
{"a":[1,2,3],"__loc__":{"file":"<top-level>","line":1},"c":{"hi":"hey"}}

1 as $x | "2" as $y | "3" as $z | { $x, as, $y: 4, ($z): 5, if: 6, foo: 7 }
{"as":8}
{"x":1,"as":8,"2":4,"3":5,"if":6,"foo":7}


# nan is parsed as a valid NaN value from JSON

fromjson | isnan
"nan"
true

tojson | fromjson
{"a":nan}
{"a":null}

# NaN with payload is not parsed
.[] | try (fromjson | isnan) catch .
["NaN","-NaN","NaN1","NaN10","NaN100","NaN1000","NaN10000","NaN100000"]
true
true
"Invalid numeric literal at EOF at line 1, column 4 (while parsing 'NaN1')"
"Invalid numeric literal at EOF at line 1, column 5 (while parsing 'NaN10')"
"Invalid numeric literal at EOF at line 1, column 6 (while parsing 'NaN100')"
"Invalid numeric literal at EOF at line 1, column 7 (while parsing 'NaN1000')"
"Invalid numeric literal at EOF at line 1, column 8 (while parsing 'NaN10000')"
"Invalid numeric literal at EOF at line 1, column 9 (while parsing 'NaN100000')"

# calling input/0, or debug/0 in a test doesn't crash jq

try input catch .
null
"break"

debug
1
1

# try/catch catches more than it should #1859
"foo" | try ((try . catch "caught too much") | error) catch "caught just right"
null
"caught just right"

.[]|(try (if .=="hi" then . else error end) catch empty) | "\(.) there!"
["hi","ho"]
"hi there!"

try (["hi","ho"]|.[]|(try . catch (if .=="ho" then "BROKEN"|error else empty end)) | if .=="ho" then error else "\(.) there!" end) catch "caught outside \(.)"
null
"hi there!"
"caught outside ho"

.[]|(try . catch (if .=="ho" then "BROKEN"|error else empty end)) | if .=="ho" then error else "\(.) there!" end
["hi","ho"]
"hi there!"

try (try error catch "inner catch \(.)") catch "outer catch \(.)"
"foo"
"inner catch foo"

try ((try error catch "inner catch \(.)")|error) catch "outer catch \(.)"
"foo"
"outer catch inner catch foo"

# Also #1859, but from #1885
first(.?,.?)
null
null

# Also #1859, but from #2140
{foo: "bar"} | .foo |= .?
null
{"foo": "bar"}

# Also #1859, but from #2220
. |= try 2
1
2

. |= try 2 catch 3
1
2

.[] |= try tonumber
["1", "2a", "3", " 4", "5 ", "6.7", ".89", "-876", "+5.43", 21]
[1, 3, 6.7, 0.89, -876, 5.43, 21]

# Also 1859, but from 2073
any(keys[]|tostring?;true)
{"a":"1","b":"2","c":"3"}
true


# explode/implode
# test replacement character (65533) for outside codepoint range and 0xd800 (55296) - 0xdfff (57343) utf16 surrogate pair range
# 1.1 and 1.9 to test round down of non-ints
implode|explode
[-1,0,1,2,3,1114111,1114112,55295,55296,57343,57344,1.1,1.9]
[65533,0,1,2,3,1114111,65533,55295,65533,65533,57344,1,1]

map(try implode catch .)
[123,["a"],[nan]]
["implode input must be an array","string (\"a\") can't be imploded, unicode codepoint needs to be numeric","number (null) can't be imploded, unicode codepoint needs to be numeric"]

try 0[implode] catch .
[]
"Cannot index number with string (\"\")"

# walk
walk(.)
{"x":0}
{"x":0}

walk(1)
{"x":0}
1

# The following is a regression test, not a requirement:
[walk(.,1)]
{"x":0}
[{"x":0},1]

# Issue #2584
walk(select(IN({}, []) | not))
{"a":1,"b":[]}
{"a":1}

# #2815
[range(10)] | .[1.2:3.5]
null
[1,2,3]

[range(10)] | .[1.5:3.5]
null
[1,2,3]

[range(10)] | .[1.7:3.5]
null
[1,2,3]

[range(10)] | .[1.7:4294967295]
null
[1,2,3,4,5,6,7,8,9]

[range(10)] | .[1.7:-4294967296]
null
[]

[[range(10)] | .[1.1,1.5,1.7]]
null
[1,1,1]

[range(5)] | .[1.1] = 5
null
[0,5,2,3,4]

[range(3)] | .[nan:1]
null
[0]

[range(3)] | .[1:nan]
null
[1,2]

[range(3)] | .[nan]
null
null

try ([range(3)] | .[nan] = 9) catch .
null
"Cannot set array element at NaN index"

try ("foobar" | .[1.5:3.5] = "xyz") catch .
null
"Cannot update string slices"

try ([range(10)] | .[1.5:3.5] = ["xyz"]) catch .
null
[0,"xyz",4,5,6,7,8,9]

try ("foobar" | .[1.5]) catch .
null
"Cannot index string with number (1.5)"


# setpath/2 does not leak the input after an invalid get #2970

try ["ok", setpath([1]; 1)] catch ["ko", .]
{"hi":"hello"}
["ko","Cannot index object with number (1)"]

try fromjson catch .
"{'a': 123}"
"Invalid string literal; expected \", but got ' at line 1, column 5 (while parsing '{'a': 123}')"

# ltrimstr/1 rtrimstr/1 don't leak on invalid input #2977

try ltrimstr(1) catch "x", try rtrimstr(1) catch "x" | "ok"
"hi"
"ok"
"ok"

try ltrimstr("x") catch "x", try rtrimstr("x") catch "x" | "ok"
{"hey":[]}
"ok"
"ok"

# ltrimstr/1 and rtrimstr/1 return an error for non-strings. #2969

.[] as [$x, $y] | try ["ok", ($x | ltrimstr($y))] catch ["ko", .]
[["hi",1],[1,"hi"],["hi","hi"],[1,1]]
["ko","startswith() requires string inputs"]
["ko","startswith() requires string inputs"]
["ok",""]
["ko","startswith() requires string inputs"]

.[] as [$x, $y] | try ["ok", ($x | rtrimstr($y))] catch ["ko", .]
[["hi",1],[1,"hi"],["hi","hi"],[1,1]]
["ko","endswith() requires string inputs"]
["ko","endswith() requires string inputs"]
["ok",""]
["ko","endswith() requires string inputs"]


# oss-fuzz #66061: setpath/2 leaks when indexing array with array

try ["OK", setpath([[1]]; 1)] catch ["KO", .]
[]
["KO","Cannot update field at array index of array"]

# regression test for #3227
foreach .[] as $x (0, 1; . + $x)
[1, 2]
1
3
2
4

# regression test for CVE-2025-49014 (use of fmt after free)
# tests with both empty string literal and empty string created by function
# as they seems to behave reference wise differently.
strflocaltime("" | ., @uri)
0
""
""

# regression tests for #3413
# upper range bounds should be in sync with the constants defined at
#   src/jv_parse.c:#define MAX_PARSING_DEPTH (N)
#   src/jv_print.c:#define MAX_PRINT_DEPTH (N)
# (N-1)
reduce range(9999) as $_ ([];[.]) | tojson | fromjson | flatten
null
[]

# (N)
reduce range(10000) as $_ ([];[.]) | tojson | try (fromjson) catch . | (contains("<skipped: too deep>") | not) and contains("Exceeds depth limit for parsing")
null
true

# (N+1)
reduce range(10001) as $_ ([];[.]) | tojson | contains("<skipped: too deep>")
null
true

# regression test for CVE-2026-33947
setpath([range(10000) | 0]; 0) | flatten
null
[0]

try setpath([range(10001) | 0]; 0) catch .
null
"Path too deep"

getpath([range(10000) | 0])
null
null

try getpath([range(10001) | 0]) catch .
null
"Path too deep"

delpaths([[range(10000) | 0]])
null
null

try delpaths([[range(10001) | 0]]) catch .
null
"Path too deep"

# regression test for CVE-2026-40612
reduce range(10000) as $_ ([]; [.]) | contains([[]])
null
true

try (reduce range(10001) as $_ ([]; [.]) as $x | $x | contains($x)) catch .
null
"Containment check too deep"

# regression test for CVE-2026-43896
reduce range(10000) as $_ ({}; {a: .}) as $x | $x * $x | length
null
1

try (reduce range(10001) as $_ ({}; {a: .}) as $x | $x * $x) catch .
null
"Object merge too deep"

# regression test for deep structural equality recursion
try ((reduce range(10001) as $_ ([]; [.])) as $x | (reduce range(10001) as $_ ([]; [.])) as $y | $x == $y) catch .
null
"Equality check too deep"

# regression tests for deep ordering comparisons
try ((reduce range(10001) as $_ ([]; [.])) as $x | [$x, $x] | sort) catch .
null
"Comparison too deep"

try ((reduce range(10001) as $_ ([]; [.])) as $x | [$x, $x] | unique) catch .
null
"Comparison too deep"

try ((reduce range(10001) as $_ ({}; {a: .})) as $x | [$x, $x] | sort) catch .
null
"Comparison too deep"

try ((reduce range(10001) as $_ ({}; {a: .})) as $x | [$x, $x] | unique) catch .
null
"Comparison too deep"
</source>

<stories>
  <story id="architecture-foundation" implements="ARCHITECTURE.md">Establish the standalone Python interpreter architecture and executable boundary.</story>
  <story id="EXEC-001" implements="FEATURE-Executable-Entry-Point.md">Implement the executable jq entry point.</story>
  <story id="EXEC-002" implements="FEATURE-Process-Contract.md">Implement jq process exit and diagnostic behavior.</story>
  <story id="EXEC-003" implements="FEATURE-JSON-I-O.md">Implement JSON input and compact output handling.</story>
  <story id="PARSE-001" implements="FEATURE-Lexer.md">Implement jq lexical scanning.</story>
  <story id="PARSE-002" implements="FEATURE-Literals-and-Strings.md">Implement literals, strings, escapes, and interpolation.</story>
  <story id="PARSE-003" implements="FEATURE-Filter-Grammar.md">Implement the core jq filter expression grammar.</story>
  <story id="PARSE-004" implements="FEATURE-Advanced-Grammar.md">Implement declarations, control syntax, and grammar rejection.</story>
  <story id="CORE-001" implements="FEATURE-Generator-Core.md">Implement stream-valued filter evaluation.</story>
  <story id="CORE-002" implements="FEATURE-Composition.md">Implement composition and cartesian evaluation.</story>
  <story id="CORE-003" implements="FEATURE-Errors-and-Optional.md">Implement empty, runtime errors, optional evaluation, and partial output.</story>
  <story id="CORE-004" implements="FEATURE-Truthiness-and-Comparison.md">Implement truthiness, equality, and ordering semantics.</story>
  <story id="VALUE-001" implements="FEATURE-Value-Model.md">Implement the jq value model and numeric edge cases.</story>
  <story id="VALUE-002" implements="FEATURE-Accessors.md">Implement field and index access.</story>
  <story id="VALUE-003" implements="FEATURE-Slices-and-Iteration.md">Implement slices and collection iteration.</story>
  <story id="VALUE-004" implements="FEATURE-Type-and-Numeric-Primitives.md">Implement type, length, numeric predicates, and math primitives.</story>
  <story id="CONF-001" implements="FEATURE-Conformance-Assets.md">Stage and validate immutable conformance assets.</story>
  <story id="FLOW-001" implements="FEATURE-Arithmetic-and-Structural-Operators.md">Implement arithmetic and structural operators.</story>
  <story id="FLOW-002" implements="FEATURE-Boolean-and-Alternative-Operators.md">Implement boolean and alternative operators.</story>
  <story id="FLOW-003" implements="FEATURE-Conditionals-and-Exception-Flow.md">Implement conditionals and exception flow.</story>
  <story id="FLOW-004" implements="FEATURE-Labels-and-Breaks.md">Implement lexical labels and breaks.</story>
  <story id="FLOW-005" implements="FEATURE-Reductions-and-Iteration-Control.md">Implement reductions and iteration-control builtins.</story>
  <story id="FLOW-006" implements="FEATURE-Recursive-Generators.md">Implement recursive generators.</story>
  <story id="FUNC-001" implements="FEATURE-Variable-Bindings.md">Implement lexical variable bindings.</story>
  <story id="FUNC-002" implements="FEATURE-Function-Parameters.md">Implement filter and value function parameters.</story>
  <story id="FUNC-003" implements="FEATURE-Function-Definitions.md">Implement function definitions, scope, redefinition, and recursion.</story>
  <story id="FUNC-004" implements="FEATURE-Destructuring-Alternatives.md">Implement destructuring alternatives.</story>
  <story id="PATH-001" implements="FEATURE-Path-Discovery.md">Implement path discovery and projection.</story>
  <story id="PATH-002" implements="FEATURE-Path-Primitives.md">Implement path access and mutation primitives.</story>
  <story id="PATH-003" implements="FEATURE-Assignment-Operators.md">Implement deletion and assignment operators.</story>
  <story id="PATH-004" implements="FEATURE-Complex-Assignments.md">Implement complex assignment edge cases.</story>
  <story id="DATA-001" implements="FEATURE-Collection-Transformations.md">Implement collection transformation builtins.</story>
  <story id="DATA-002" implements="FEATURE-Sorting-and-Grouping.md">Implement sorting, grouping, and extrema builtins.</story>
  <story id="DATA-003" implements="FEATURE-Object-Entries-and-Containment.md">Implement object-entry and containment builtins.</story>
  <story id="DATA-004" implements="FEATURE-Index-and-Membership.md">Implement index, membership, search, and SQL-style utilities.</story>
  <story id="TEXT-001" implements="FEATURE-String-Manipulation.md">Implement string manipulation builtins.</story>
  <story id="TEXT-002" implements="FEATURE-Formats-and-Serialization.md">Implement JSON conversion and output formats.</story>
  <story id="TEXT-003" implements="FEATURE-Regular-Expressions.md">Implement regular-expression filters.</story>
  <story id="TEXT-004" implements="FEATURE-Date-and-Time.md">Implement date and time filters.</story>
  <story id="IO-001" implements="FEATURE-Input-Controls.md">Implement input stream controls.</story>
  <story id="IO-002" implements="FEATURE-Diagnostics.md">Implement diagnostics and stderr filters.</story>
  <story id="IO-003" implements="FEATURE-Streaming.md">Implement streaming transformations.</story>
  <story id="CONF-002" implements="FEATURE-Scoped-Conformance.md">Provide scoped conformance verification for implementation slices.</story>
  <story id="CONF-003" implements="FEATURE-Full-Conformance.md">Verify the completed interpreter against the full conformance corpus.</story>
</stories>
