├── .editorconfig ├── .github ├── pull_request_template.md └── workflows │ ├── floodgate.yml │ ├── publish.yml │ └── stale-lock.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── HISTORY.md ├── LICENSE.md ├── README.md ├── package-lock.json ├── package.json └── spec.html /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Thank you for taking the time to contribute to this proposal! 2 | We’re so happy you’re helping out. 3 | 4 | 1. Please take a look at the [contributing guidelines][] 5 | and the resources to which it links. 6 | 2. Please include the purpose of the pull request. For example: 7 | * “This adds…” 8 | * “This simplifies…” 9 | * “This fixes…” 10 | 3. Please be explicit about what feedback, if any, you want: 11 | a quick pair of eyes, discussion or critique of its approach, 12 | a review of its copywriting, and so on. 13 | 4. Please mark the pull request as a Draft if it is still unfinished. 14 | 15 | All text in this repository is under the 16 | [same BSD license as Ecma-262][LICENSE.md]. 17 | As is the norm in open source, by contributing to this GitHub repository, 18 | you are licensing your contribution under the same license, 19 | as per the 20 | [GitHub terms of service][ToS]. 21 | 22 | [contributing guidelines]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md 23 | [LICENSE.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/LICENSE.md 24 | [ToS]: https://help.github.com/en/github/site-policy/github-terms-of-service 25 | -------------------------------------------------------------------------------- /.github/workflows/floodgate.yml: -------------------------------------------------------------------------------- 1 | name: Comment Floodgate 2 | on: issue_comment 3 | jobs: 4 | floodgate: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: js-choi/github-comment-floodgate@v2 8 | with: 9 | minutes-in-period: 60 10 | # This number is how many comments are allowed per period per issue. 11 | max-comments-per-period: 12 12 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy to GitHub Pages 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | jobs: 8 | build-and-deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 🛎️ 12 | uses: actions/checkout@v2 13 | with: 14 | persist-credentials: false 15 | 16 | - name: Setup Node 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: '14.x' 20 | 21 | - name: Install and Build 🔧 22 | run: | 23 | npm install 24 | npm run build 25 | 26 | - name: Deploy 🚀 27 | uses: peaceiris/actions-gh-pages@v3 28 | with: 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | publish_dir: ./dist 31 | -------------------------------------------------------------------------------- /.github/workflows/stale-lock.yml: -------------------------------------------------------------------------------- 1 | name: Lock Stale Threads 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | workflow_dispatch: 8 | 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | 13 | concurrency: 14 | group: lock 15 | 16 | jobs: 17 | action: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: dessant/lock-threads@v3 21 | with: 22 | issue-inactive-days: 7 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | out 4 | dist 5 | npm-debug.log 6 | deploy_key 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: off 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - "8" 7 | 8 | script: 9 | - bash ./deploy.sh 10 | 11 | env: 12 | global: 13 | - ENCRYPTION_LABEL: "bc1f69dfbe70" 14 | - GH_USER_NAME: "littledan" 15 | - GH_USER_EMAIL: "littledan@igalia.com" 16 | - PRIVATE_KEY_FILE_NAME: "github_deploy_key.enc" 17 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of conduct 2 | This repository is a TC39 project, and it therefore subscribes to 3 | its [code of conduct][CoC]. It is available at . 4 | 5 | We all should strive here to be respectful, friendly and patient, 6 | inclusive, considerate, and careful in the words we choose. 7 | When we disagree, we should try to understand why. 8 | 9 | To ask a question or report an issue, please follow the [CoC]’s directions, e.g., emailing 10 | [tc39-conduct-reports@googlegroups.com][]. 11 | 12 | More information about contributing is also available in [CONTRIBUTING.md][]. 13 | 14 | [CoC]: https://tc39.es/code-of-conduct/ 15 | [tc39-conduct-reports@googlegroups.com]: mailto:tc39-conduct-reports@googlegroups.com 16 | [CONTRIBUTING.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md 17 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the ES pipe operator’s proposal 2 | First off, thank you for taking the time to contribute! 🎉 3 | 4 | Here are some suggestions to contributing to this proposal. 5 | The pipe operator in JavaScript has a [long and twisty history][HISTORY.md]. 6 | A lot of issues have already been argued round in round in circles. 7 | 8 | Bearing that in mind, please try to read the following 9 | before making new issues or comments: 10 | 11 | 1. [HISTORY.md][]: This will give a lot of context 12 | behind what’s been happening to the proposal since its creation in 2015. 13 | 2. The general [TC39 Process][], which summarizes 14 | how TC39’s “consensus” and “Stages” work. 15 | 3. The guide on [contributing to TC39 proposals][contributing guide]. 16 | 4. The [TC39 Code of Conduct][CoC]: 17 | It has important information about how we’re all expected to act 18 | and what to do when we feel like someone’s conduct does not meet the Code. 19 | We all want to maintain a friendly, productive working environment! 20 | 5. The [TC39 How to Give Feedback][feedback] article. 21 | 6. The [proposal explainer][] to make sure that it is 22 | not already addressed there. 23 | 7. The [TC39 Matrix guide][] (if you want to chat with TC39 members on Matrix, 24 | which is a real-time chat platform). 25 | 8. If the explainer does not already explain your topic adequately, 26 | then please [search the GitHub repository’s issues][issues] 27 | to see if any issues match the topic you had in mind. 28 | This proposal is more than four years old, 29 | and it is likely that the topic has already been raised and thoroughly discussed. 30 | 31 | You can leave a comment on an [existing GitHub issue][issues], 32 | create a new issue (but really do try to [find an existing GitHub issue][issues] first), 33 | or [participate on Matrix][TC39 Matrix guide]. 34 | 35 | Please try to keep any existing GitHub issues on their original topic. 36 | 37 | We’ve also installed a [“floodgate” moderation bot](https://github.com/marketplace/actions/comment-floodgate) 38 | (see [issue #231](https://github.com/tc39/proposal-pipeline-operator/issues/231)). 39 | When a issue gets a huge flood of new comments (i.e., new comments are being created at a very high rate), 40 | then the bot will temporarily lock that issue. 41 | (The threshold rate is currently set to twelve messages in the same thread in the same sixty minutes.) 42 | This doesn’t mean that the automatically locked high-traffic threads will get locked permanently. 43 | It just means that the issue’s thread will cool down until a volunteer moderator is able to look at what’s going on. 44 | 45 | If you feel that someone’s conduct is not meeting the [TC39 Code of Conduct][CoC], 46 | whether in this GitHub repository or in a [TC39 Matrix room][TC39 Matrix guide], 47 | then please follow the [Code of Conduct][CoC]’s directions for reporting the violation, 48 | including emailing [tc39-conduct-reports@googlegroups.com][]. 49 | 50 | Thank you again for taking the time to contribute! 51 | 52 | [HISTORY.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/HISTORY.md 53 | [CoC]: https://tc39.es/code-of-conduct/ 54 | [TC39 process]: https://tc39.es/process-document/ 55 | [contributing guide]: https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md#new-feature-proposals 56 | [feedback]: https://github.com/tc39/how-we-work/blob/master/feedback.md 57 | [proposal explainer]: https://github.com/tc39/proposal-pipeline-operator/blob/main/README.md 58 | [TC39 Matrix guide]: https://github.com/tc39/how-we-work/blob/master/matrix-guide.md 59 | [issues]: https://github.com/tc39/proposal-pipeline-operator/issues?q=is%3Aissue+ 60 | [tc39-conduct-reports@googlegroups.com]: mailto:tc39-conduct-reports@googlegroups.com 61 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # Brief history of the JavaScript pipe operator 2 | The pipe operator in JavaScript has a long and twisty history. 3 | Understanding that history can give context behind 4 | what’s been happening to the proposal since its creation in 2015. 5 | 6 | For information on what “Stage 1” and “Stage 2” mean, 7 | read about the [TC39 Process][]. 8 | 9 | More information about contributing is also available in [CONTRIBUTING.md][]. 10 | 11 | ## 2015–2017 12 | People are debating about a [proposed bind operator `::`][bind] 13 | by [@zenparsing][] (Brave). 14 | A binary `::` operator that binds its left-hand side to its right-hand side (a function) 15 | would serve as a “pipe” operator in JavaScript 16 | (e.g., `a::f(b, c)::g(d, e)` would be a “pipeline” equivalent to 17 | `g.call(f.call(a, b, c), d, e)`). 18 | However, parts of TC39 object to using `this`, 19 | saying that using `this` is strange outside of methods. 20 | Debate online in the `::` repository (and also offline) is bogged down in circles. 21 | 22 | [@littledan][] (Igalia) and [@gilbert][] create a proposal 23 | for an alternative pipe operator that does not use `this`. 24 | They start out [comparing F# pipes with Elixir pipes][first pipe preso]. 25 | They also [explore other syntaxes such as “placeholder” pipes (i.e., Hack pipes)][I4]. 26 | 27 | Meanwhile, [@rbuckton][] (Microsoft) discusses pipelining with the F# team 28 | and plans to simultaneously propose F# pipes and syntax 29 | for [partial function application][]. 30 | Upon discovering [@littledan][] (Igalia)’s proposal for F#-or-Elixir pipes, 31 | [@rbuckton][] (Microsoft) finds that it already 32 | aligns with the F# pipe that he had been planning to present, 33 | and he switches to focusing on syntax for [partial function application][]. 34 | 35 | ## 2017-07 36 | On [2017-09-26][S1], [@littledan][] makes a first 37 | [presentation for F#-or-Elixir pipes to TC39, successfully advancing to Stage 1][S1]. 38 | 39 | However, parts of TC39 object to redundancy with a bind operator. 40 | A condition of the advancement to Stage 1 is that it would not be redundant 41 | with a bind operator; this will become relevant later. 42 | 43 | In addition, parts of TC39 object to aspects of F# pipes, 44 | such as how they handle `await` and `yield`. 45 | 46 | [@rbuckton][] (Microsoft) presents syntax for [partial function application][] 47 | [at the same meeting and succeeds in advancing to Stage 1][PFA S1]. 48 | However, parts of TC39 push back against its syntax. 49 | 50 | ## 2017–2018 51 | [@littledan][] and collaborators [attempt to make a stopgap with `|> await`][I66] 52 | but encounter several conceptual and syntactic problems, 53 | including a problem related to unexpected automatic semicolon insertion. 54 | [@littledan][] decides to try to defer handling `await` at all to a later proposal; 55 | he also drops Elixir pipes in favor of F# pipes. 56 | 57 | On [2017-11-29][S2 2017], [@littledan][] makes 58 | [another presentation for F# pipes and does not succeed in advancing to Stage 2][S2 2017]. 59 | During the presentation, he proposes to TC39 that `|> await` be deferred, 60 | but there is pushback from several other representatives, and presentation time overflows. 61 | 62 | Advancement of F# pipes is therefore stymied. 63 | 64 | [@gilbert][] suggests resurrecting Hack pipes, 65 | which were [previously explored in 2015][I4], 66 | as a solution to TC39’s blocking concerns. 67 | He also suggests two possible compromises that mix F# pipes and Hack pipes: 68 | [“split-mix pipes” and “smart-mix pipes”][I89]. 69 | [@littledan][] (Igalia) agrees to investigate all three styles. 70 | [@mAAdhaTTah][] (pro-F#-pipes) and [@js-choi][] (slightly pro-Hack-pipes) 71 | volunteer to collaborate on competing specs: 72 | [@mAAdhaTTah][] writes a [spec for F# pipes][F# spec] 73 | and [@js-choi][] writes a [spec for smart-mix pipes][smart-mix-pipes spec]. 74 | 75 | ## 2018–2020 76 | On [2018-03-22][S2 2018], [@littledan][] presents F# pipes again—alongside 77 | smart-mix pipes—in an 78 | [update presentation, trying to gain more consensus within TC39 for Stage 2][S2 2018]. 79 | However, neither proposal is able to achieve much consensus among TC39 representatives 80 | due to syntactic concerns. 81 | Some TC39 representatives state that no pipe operator 82 | may be worth standardizing at all. 83 | 84 | Advancement of F# pipes therefore continues to be stymied; 85 | advancement of smart-mix pipes is also stymied. 86 | 87 | [@rbuckton][] (Microsoft) also presents [partial function application][] 88 | again [on 2018-07, attempting to advance it to Stage 2][PFA 2018-07]. 89 | However, several TC39 representatives continue to push back against its syntax. 90 | [@syg][] (Google V8) also expresses “strong reservations” about PFA syntax 91 | increasing the “ease with which [developers] can allocate many many closures”, 92 | with regards to memory use. 93 | Partial function application is also unable to advance to Stage 2, 94 | and its advancement is therefore also stymied. 95 | 96 | [@codehag][] (Mozilla SpiderMonkey) meanwhile leads a 97 | [Mozilla user study about pipes][Mozilla study]. 98 | Its results suggest that developers like and prefer smart-mix pipes slightly more, 99 | but they make slightly less errors with F# pipes. 100 | Her conclusions from the study were that no difference between smart-mix pipes or F# pipes 101 | was significant enough to justify any decision one way or the other. 102 | (There is also another Mozilla user study about partial function application, 103 | and its results suggests that the JavaScript community 104 | is much more interested in partial function application than any pipe operator.) 105 | The Mozilla SpiderMonkey team becomes weakly against any pipe operator. 106 | 107 | Work on F# pipes, smart-mix pipes, and PFA syntax stalls. 108 | 109 | For the three years, GitHub debate online and debate offline 110 | continues back and forth in circles: 111 | about the best way to increase the odds that smart-mix pipes vs. F# pipes 112 | will reach consensus in TC39. 113 | 114 | ## 2021-01 115 | The State of JS 2020 is published, 116 | and it reports that one of the [language’s top requested features][SoJS 20] 117 | is some kind of pipe operator. 118 | This galvanizes [@littledan][] (Igalia)’s further work on pipe, 119 | and he prepares a presentation for 2021-03’s TC39 meeting. 120 | 121 | ## 2021-03 122 | [@littledan][] (Igalia) is managing other projects 123 | and is now unable to devote time to the pipe operator. 124 | He presents about it again to TC39 and asks there for a new lead champion. 125 | [@tabatkins][] (Google), who also does much work in Web Platform standards 126 | such as HTML5 DOM and CSS, 127 | is personally enthusiastic about helping with any pipe operator 128 | and agrees to take on being co-champion. 129 | [@rbuckton][] (Microsoft) also agrees to co-champion the proposal. 130 | 131 | [@tabatkins][] (Google) publishes a [Gist comparing F#, Hack, and smart-mix pipes][Gist], concluding that they are all functionally the same, 132 | with only small differences in actual usage, 133 | and that all three would benefit everyone. 134 | Discussion is sparked in the Gist’s comments. 135 | 136 | Galvanized by the Gist, 137 | [@js-choi][] switches from writing the [smart-mix-pipes spec][] 138 | to writing a [Hack-pipes spec][]. 139 | 140 | ## 2021-07 141 | [@tabatkins][] (Google) schedules a 142 | [TC39 incubator meeting devoted to pipes][2021-07 incubator] 143 | (see [general information on incubator calls][]). 144 | Attendees of special note in this meeting are [@syg][] (Google V8), 145 | [@littledan][] (Igalia), [@rbuckton][] (Microsoft), and [@ljharb][]. [@codehag][] (Mozilla SpiderMonkey) is unable to attend. 146 | 147 | [@tabatkins][] (Google) presents three choices to the attendees again: 148 | F# pipes, Hack pipes, and Elixir pipes. 149 | 150 | [@rbuckton][] (Microsoft) is still in favor of F# pipes with his proposed syntax for 151 | [partial function application][] (see [§ 2016–2017](#20162017)). 152 | [@rbuckton][] (Microsoft) debates with [@tabatkins][] (Google) 153 | about whether F# pipes or Hack pipes are more intuitive. 154 | (He also mentions that [@codehag][] (Mozilla SpiderMonkey) 155 | might be interested in co-championing partial function application without pipes, 156 | based on her user studies’ findings; see [§ 2018–2020](#20182020).) 157 | 158 | [@syg][] (Google V8) voices concerns again about engine performance 159 | of partial function application and F# pipes (see [§ 2018–2020](#20182020)). 160 | 161 | [@tabatkins][] (Google) and [@ljharb][] are supportive 162 | of either Hack pipes or F# pipes: 163 | “90%” F# pipes and “100%” Hack pipes. 164 | However, their 90% support of F# pipes would drop a lot if [@syg][] 165 | (Google V8)’s performance concerns about F# pipes are borne out. 166 | 167 | Nobody in the meeting seems to think Elixir pipes are a good fit for JavaScript. 168 | 169 | Most everyone in the meeting seems to be in favor of picking some style for pipes 170 | after three years of indecision. 171 | 172 | ## 2021-08 173 | [@tabatkins][] (Google) plans to present *some* pipe-operator style for Stage 2. 174 | Based on the results of the the preceding meeting, they pick Hack pipes. 175 | This has support from [@ljharb][] and some other TC39 representatives. 176 | [@js-choi][] (Indiana University) joins as co-champion. 177 | 178 | Through this month, [@tabatkins][] (Google) continues to debate offline 179 | with [@mAAdhaTTah][] regarding Hack pipes vs. F# pipes. 180 | As a result, [@mAAdhaTTah][] changes his mind from being in favor of F# pipes 181 | to being in favor of Hack pipes, 182 | deciding that [Hack pipes would be better for bridging functional programming][JDG essay] 183 | with the rest of the JavaScript ecosystem. 184 | 185 | [@rbuckton][] (Microsoft) joins in debating with [@tabatkins][] (Google) in late August. 186 | [@rbuckton][] (Microsoft) notes the groundswell of support within TC39 about Hack pipes 187 | due to “some of the limitations of F# pipes”. 188 | Therefore feeling that F# pipes would continue to be indefinitely stuck at an impasse, 189 | [@rbuckton][] (Microsoft) thus decides to give “tentative agreement” to Hack pipes. 190 | (See [@rbuckton’s narrative][].) 191 | 192 | *** 193 | 194 | On [2021-08-31][S2 2021], a formal Committee plenary occurs, 195 | and [@tabatkins][] (Google) therefore 196 | [presents Hack pipes as the tentative consensus among the champions, 197 | proposing that TC39 advance them to Stage 2][S2 2021]. 198 | There are several responses from other representatives: 199 | 200 | [@ljharb][] voices concern that advancing pipe 201 | would kill any future bind operator (see [§ 2017-09](#2017-09)). 202 | Other representatives respond that Hack pipes are now orthogonal to any bind operator 203 | and would not kill it. [@ljharb][] decides not to block Stage 2. 204 | 205 | [@codehag][] (Mozilla SpiderMonkey) voices some concerns: 206 | the Mozilla SpiderMonkey team is still somewhat against any pipe operator, 207 | whatever the style. 208 | However, she decides that these concerns are not strong enough for her to block Stage 2. 209 | 210 | [@syg][] (Google V8), having previously expressed concerns about memory allocation 211 | encouraged by F# pipes and partial function application 212 | (see [§ 2021-07](#2021-07)), does not give any objection. 213 | 214 | [@rbuckton][] (Microsoft) continues to give tentative agreement to Hack pipes. 215 | 216 | No other representatives give objections to Stage 2. 217 | Hack pipes therefore succeed in advancing to Stage 2. 218 | [@tabatkins][] (Google) resolves to continue discussing concerns 219 | with [@rbuckton][] (Microsoft), [@codehag][] (Mozilla SpiderMonkey), [@mAAdhaTTah][], 220 | and others offline. 221 | They also discuss concerns with the community on GitHub, 222 | both in the [2021-03 comparison Gist][Gist]’s comments (see [§ 2021-03](#2021-03)) 223 | and in the [pipe proposal’s issues][issues]. 224 | 225 | ## 2021-09 226 | In order to explain this proposal’s history and process to other community members, 227 | [@js-choi][] (Indiana University) creates this document. 228 | 229 | Inspired by a [defense of unary functions][I233], [@js-choi][] (Indiana University) 230 | also creates a new proposal, [proposal-function-helpers][], that would add several Function 231 | helper methods. These include Function.pipe, pipeAsync, flow, and flowAsync. 232 | 233 | ## 2021-10 234 | Starting on 2021-10-25, another formal Commitee plenary occurs. 235 | The pipe operator is not presented at this meeting, although 236 | an [incubator meeting on 2021-11 is chartered][incubator charter 2021-11] 237 | for bikeshedding the pipe operator’s topic token. 238 | 239 | [On 2021-10-25, PFA syntax is presented again to the Committee 240 | plenary][2021-10 PFA] by [@rbuckton][] (Microsoft) for Stage 2. 241 | The Committee rejects this proposal; several representatives, 242 | including those from Mozilla SpiderMonkey and Google V8, state 243 | that there were insufficiently specific and compelling use cases presented, 244 | with high syntax cost and novelty in comparison to arrow functions. 245 | 246 | [On 2021-10-28, proposal-function-helpers is also presented to the 247 | Committee plenary][2021-10 Function] for Stage 1 by [@js-choi][]. 248 | The Committee also rejects this proposal due to its being overly broad, 249 | and it requests that it be split up into multiple proposals. 250 | These split proposals would include a proposal specifically 251 | about [Function.pipe and flow][]. 252 | 253 | ## 2021-12: Holistic-dataflow articles 254 | Since December, TC39 has continued to discuss the pipe operator in the greater 255 | context of “dataflow”. 256 | 257 | The “dataflow” proposals include the following: 258 | 259 | * The [pipe operator][Hack pipes] `… |> …` (aka “Hack pipes”) 260 | * [Function.pipe][] (a function version of the F# pipe operator) 261 | * The [bind-this][] operator `…::…` (and its variant [call-this][] `…@(…)`) 262 | * The [Extensions][] syntaxes `…::…`, `…::…:…`, and `const ::{ … } = …;` 263 | * [Partial function application][PFA syntax] `…~(…)` (aka “PFA syntax”) 264 | 265 | These dataflow proposals overlap in various complicated ways. Multiple TC39 266 | representatives expressed concerns about redundancies between these 267 | proposals—that the space as a whole needs to be holistically considered, that 268 | goals need to be more specifically articulated, and that there is not enough 269 | “syntax budget” in the language to approve all of these proposals. This applies 270 | to the pipe operator, as well as all the others in that list. 271 | 272 | ![][diagram] 273 | 274 | * In late December, [@js-choi][] wrote [an article detailing how these 275 | proposals overlap][2022-12 jschoi dataflow article]. 276 | * [@tabatkins then wrote a response article](https://www.xanthir.com/b5Gd0) on 277 | their own blog. 278 | * Later, [@hax would also write another response 279 | article](https://hackmd.io/yDDJCsS-Sv2AJwo8arAn3w?view). (@hax is a TC39 280 | champion of the [Extensions][] syntaxes.) 281 | 282 | ## 2022-01: Plenary meeting 283 | On [January 26, 2022, a plenary meeting was held][2022-01 plenary] to discuss these overlapping proposals holistically. This discussion overflowed into an [ad-hoc meeting on the next day][2022-01 overflow]. 284 | 285 | In these two meetings, TC39 representatives debated over such topics as: 286 | * Creating a unified language versus accommodating multiple programming paradigms (e.g., object oriented versus functional). 287 | * [TMTOWTDI][] versus [TOOWTDI][]. 288 | * Whether generalized language features (like the Hack-style pipe operator) or specialized features (like Function.pipe, the F#-style pipe operator, and the bind-this operator) were more desirable. 289 | * Whether it is better for language features to be universal or prescriptive in their usage. 290 | * The merits of specific dataflow proposals, including the pipe operator. 291 | 292 | Support among TC39 representatives for the pipe operator as it is now (with a Hack-style topic reference) appears to range from strongly in favor to weakly against. Several representatives reaffirmed that they are moderately or strongly against F#-style syntax. Support for Function.pipe appears to be tepid: neither strongly positive or negative. For more details, see the [conclusions of the ad-hoc overflow meeting][2022-01 overflow conclusions]. 293 | 294 | ## 2022-03 and 2022-04 295 | At the [2022-03 plenary, several candidate tokens for the topic reference were presented][2022-03 plenary pipe]. The Committee mildly preferred `@` as the topic reference. (However, a [delegate subsequently raised serious concerns about `@`][2022-04 serious @ concerns], and thus `@` was excluded again as a topic reference.) 296 | 297 | Additionally, an [update about call-this was also presented at the plenary][2022-03 plenary call-this]. The call-this proposal continues to polarize the Committee due to ecosystem-schism concerns. 298 | 299 | ## 2022-07 300 | [In the plenary on July 21, proposal-function-pipe-flow was formally presented to the Committee, and it was rejected for Stage 1][2022-07 plenary]. The Committee generally found its use cases not compelling enough compared to the pipe operator. Its champion subsequently withdrew it from consideration. (Eventually, after the pipe operator gains users, pain points with the pipe operator may be enough motivation to revive proposal-function-pipe-flow, but that would not occur for a long time.) 301 | 302 | There is another [incubator call chartered for more pipe-operator bikeshedding](https://github.com/tc39/incubator-agendas/issues/26), which might or might not occur before the [September plenary](https://github.com/tc39/agendas/blob/main/2022/09.md). 303 | 304 | [issues]: https://github.com/tc39/proposal-pipeline-operator/issues?q=is%3Aissue+ 305 | [CONTRIBUTING.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md 306 | [general information on incubator calls]: https://github.com/tc39/how-we-work/blob/master/incubator-calls.md 307 | 308 | [bind]: https://github.com/tc39/proposal-bind-operator 309 | [partial function application]: https://github.com/tc39/proposal-partial-application 310 | [proposal-function-helpers]: https://github.com/js-choi/proposal-function-helpers 311 | [Function.pipe and flow]: https://github.com/js-choi/proposal-function-pipe-flow 312 | 313 | [F# spec]: https://github.com/valtech-nyc/proposal-fsharp-pipelines/ 314 | [smart-mix-pipes spec]: https://github.com/js-choi/proposal-smart-pipelines 315 | [Hack-pipes spec]: https://github.com/tc39/proposal-hack-pipes 316 | [Function.pipe]: https://github.com/js-choi/proposal-function-pipe-flow 317 | [bind-this]: https://github.com/tc39/proposal-bind-this 318 | [call-this]: https://github.com/tabatkins/proposal-call-this-operator 319 | [Extensions]: https://github.com/tc39/proposal-extensions 320 | [PFA syntax]: https://github.com/tc39/proposal-partial-application 321 | [diagram]: https://jschoi.org/21/es-dataflow/map/ 322 | [Hack pipes]: https://github.com/tc39/proposal-pipeline-operator 323 | [TMTOWTDI]: https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it 324 | [TOOWTDI]: https://wiki.python.org/moin/TOOWTDI 325 | 326 | [first pipe preso]: https://docs.google.com/presentation/d/1qiWFzi5dkjuUVGcFXwypuQbEbZk-BV7unX0bYurcQsA/edit#slide=id.g1fa08b5c5c_0_93 327 | 328 | [I4]: https://github.com/tc39/proposal-pipeline-operator/issues/4 329 | [I75]: https://github.com/tc39/proposal-pipeline-operator/issues/75 330 | [I66]: https://github.com/tc39/proposal-pipeline-operator/pull/66 331 | [I89]: https://github.com/tc39/proposal-pipeline-operator/issues/89 332 | [I233]: https://github.com/tc39/proposal-pipeline-operator/issues/233 333 | 334 | [S1]: https://github.com/tc39/notes/blob/master/meetings/2017-09/sept-26.md#11iia-pipeline-operator 335 | [S2 2017]: https://github.com/tc39/notes/blob/master/meetings/2017-11/nov-29.md#9iii-pipeline-operator-for-stage-2 336 | [PFA S1]: https://github.com/tc39/notes/blob/master/meetings/2017-09/sept-28.md#13i-partial-application 337 | [S2 2018]: https://github.com/tc39/notes/blob/master/meetings/2018-03/mar-22.md#10ive-pipeline-operator 338 | [PFA 2018-07]: https://github.com/tc39/notes/blob/master/meetings/2018-07/july-25.md#partial-application 339 | [2021-07 incubator]: https://github.com/tc39/incubator-agendas/blob/master/notes/2021/06-17.md#pipeline 340 | [Mozilla study]: https://github.com/tc39/notes/blob/master/meetings/2019-06/june-6.md#javascript-and-syntax-research-methods 341 | [S2 2021]: https://github.com/tc39/notes/blob/master/meetings/2021-08/aug-31.md#pipeline-operator-for-stage-2 342 | [incubator charter 2021-11]: https://github.com/tc39/incubator-agendas/issues/21 343 | [2021-10 PFA]: https://github.com/tc39/notes/blob/master/meetings/2021-10/oct-25.md#partial-function-application-for-stage-2 344 | [2021-10 Function]: https://github.com/tc39/notes/blob/master/meetings/2021-10/oct-28.md#function-helpers 345 | [2022-01 plenary]: https://github.com/tc39/notes/blob/main/meetings/2022-01/jan-26.md#holistic-discussion-of-tc39-dataflow-proposals 346 | [2022-01 overflow]: https://github.com/tc39/incubator-agendas/blob/main/notes/2022/01-27.md 347 | [2022-01 overflow conclusions]: https://github.com/tc39/incubator-agendas/blob/main/notes/2022/01-27.md#conclusions 348 | [2022-12 jschoi dataflow article]: https://jschoi.org/21/es-dataflow/ 349 | [2022-03 plenary pipe]: https://github.com/tc39/notes/blob/main/meetings/2022-03/mar-29.md#bikeshedding-the-pipe-operator-topic-token 350 | [2022-03 plenary call-this]: https://github.com/tc39/notes/blob/main/meetings/2022-03/mar-29.md#bikeshedding-call-this-syntax 351 | [2022-04 serious @ concerns]: https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-1084946624 352 | [2022-07 plenary]: https://github.com/tc39/notes/blob/main/meetings/2022-07/jul-21.md#functionpipe--flow-for-stage-1 353 | 354 | [TC39 process]: https://tc39.es/process-document/ 355 | [Gist]: https://gist.github.com/tabatkins/1261b108b9e6cdab5ad5df4b8021bcb5 356 | [@rbuckton’s narrative]: https://github.com/tc39/proposal-pipeline-operator/issues/91#issuecomment-917645179 357 | [SoJS 20]: https://2020.stateofjs.com/en-US/opinions/?missing_from_js 358 | [JDG essay]: https://jamesdigioia.com/hack-pipe-for-functional-programmers-how-i-learned-to-stop-worrying-and-love-the-placeholder/ 359 | 360 | [@littledan]: https://github.com/littledan/ 361 | [@gilbert]: https://github.com/gilbert/ 362 | [@tabatkins]: https://github.com/tabatkins/ 363 | [@codehag]: https://github.com/codehag/ 364 | [@mAAdhaTTah]: https://github.com/mAAdhaTTah/ 365 | [@js-choi]: https://github.com/js-choi/ 366 | [@syg]: https://github.com/syg/ 367 | [@ljharb]: https://github.com/ljharb/ 368 | [@rbuckton]: https://github.com/rbuckton/ 369 | [@zenparsing]: https://github.com/zenparsing 370 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 J. S. Choi, James DiGioia, Ron Buckton, Tab Atkins-Bittner 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. 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. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | **This software is provided by the copyright holders and contributors “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 the copyright holder or contributors 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.** 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pipe Operator (`|>`) for JavaScript 2 | 3 | * **Stage**: 2 4 | * **Champions**: J. S. Choi, James DiGioia, Ron Buckton, Tab Atkins-Bittner, \[list incomplete] 5 | * **Former champions**: Daniel Ehrenberg 6 | * **[Specification][]** 7 | * **[Contributing guidelines][]** 8 | * **[Proposal history][]** 9 | * **Babel plugin**: [Implemented in v7.15][Babel 7.15]. See [Babel documentation][]. 10 | 11 | (This document uses `%` 12 | as the placeholder token for the topic reference. 13 | This will ***almost certainly not be the final choice***; 14 | see [the token bikeshedding discussion][token bikeshedding] for details.) 15 | 16 | [specification]: http://tc39.github.io/proposal-pipeline-operator/ 17 | [Babel 7.15]: https://babeljs.io/blog/2021/07/26/7.15.0#hack-style-pipeline-operator-support-13191httpsgithubcombabelbabelpull13191-13416httpsgithubcombabelbabelpull13416 18 | [Babel documentation]: https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator 19 | [token bikeshedding]: https://github.com/tc39/proposal-pipeline-operator/issues/91 20 | [contributing guidelines]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md 21 | [proposal history]: https://github.com/tc39/proposal-pipeline-operator/blob/main/HISTORY.md 22 | 23 | ## Why a pipe operator 24 | In the State of JS 2020 survey, the **fourth top answer** to 25 | [“What do you feel is currently missing from 26 | JavaScript?”](https://2020.stateofjs.com/en-US/opinions/#missing_from_js) 27 | was a **pipe operator**. Why? 28 | 29 | When we perform **consecutive operations** (e.g., function calls) 30 | on a **value** in JavaScript, 31 | there are currently two fundamental styles: 32 | * passing the value as an argument to the operation 33 | (**nesting** the operations if there are multiple operations), 34 | * or calling the function as a method on the value 35 | (**chaining** more method calls if there are multiple methods). 36 | 37 | That is, `three(two(one(value)))` versus `value.one().two().three()`. 38 | However, these styles differ much in readability, fluency, and applicability. 39 | 40 | ### Deep nesting is hard to read 41 | The first style, **nesting**, is generally applicable – 42 | it works for any sequence of operations: 43 | function calls, arithmetic, array/object literals, `await` and `yield`, etc. 44 | 45 | However, nesting is **difficult to read** when it becomes deep: 46 | the flow of execution moves **right to left**, 47 | rather than the left-to-right reading of normal code. 48 | If there are **multiple arguments** at some levels, 49 | reading even bounces **back and forth**: 50 | our eyes must **jump left** to find a function name, 51 | and then they must **jump right** to find additional arguments. 52 | Additionally, **editing** the code afterwards can be fraught: 53 | we must find the correct **place to insert** new arguments 54 | among **many nested parentheses**. 55 | 56 |
57 | Real-world example 58 | 59 | Consider this [real-world code from React](https://github.com/facebook/react/blob/17.0.2/scripts/jest/jest-cli.js#L295). 60 | 61 | ```js 62 | console.log( 63 | chalk.dim( 64 | `$ ${Object.keys(envars) 65 | .map(envar => 66 | `${envar}=${envars[envar]}`) 67 | .join(' ') 68 | }`, 69 | 'node', 70 | args.join(' '))); 71 | ``` 72 | 73 | This real-world code is made of **deeply nested expressions**. 74 | In order to read its flow of data, a human’s eyes must first: 75 | 76 | 1. Find the **initial data** (the innermost expression, `envars`). 77 | 2. And then scan **back and forth** repeatedly from **inside out** 78 | for each data transformation, 79 | each one either an easily missed prefix operator on the left 80 | or a suffix operators on the right: 81 | 82 | 1. `Object.keys()` (left side), 83 | 2. `.map()` (right side), 84 | 3. `.join()` (right side), 85 | 4. A template literal (both sides), 86 | 5. `chalk.dim()` (left side), then 87 | 6. `console.log()` (left side). 88 | 89 | As a result of deeply nesting many expressions 90 | (some of which use **prefix** operators, 91 | some of which use **postfix** operators, 92 | and some of which use **circumfix** operators), 93 | we must check **both left and right sides** 94 | to find the **head** of **each expression**. 95 | 96 |
97 | 98 | ### Method chaining is limited 99 | The second style, **method chaining**, is **only** usable 100 | if the value has the functions designated as **methods** for its class. 101 | This **limits** its applicability. 102 | But **when** it applies, thanks to its postfix structure, 103 | it is generally more usable and **easier** to read and write. 104 | Code execution flows **left to right**. 105 | Deeply nested expressions are **untangled**. 106 | All arguments for a function call are **grouped** with the function’s name. 107 | And editing the code later to **insert or delete** more method calls is trivial, 108 | since we would just have to put our cursor in one spot, 109 | then start typing or deleting one **contiguous** run of characters. 110 | 111 | Indeed, the benefits of method chaining are **so attractive** 112 | that some **popular libraries contort** their code structure 113 | specifically to allow **more method chaining**. 114 | The most prominent example is **[jQuery][]**, which 115 | still remains the **most popular JS library** in the world. 116 | jQuery’s core design is a single über-object with dozens of methods on it, 117 | all of which return the same object type so that we can **continue chaining**. 118 | There is even a name for this style of programming: 119 | **[fluent interfaces][]**. 120 | 121 | [jQuery]: https://jquery.com/ 122 | [fluent interfaces]: https://en.wikipedia.org/wiki/Fluent_interface 123 | 124 | Unfortunately, for all of its fluency, 125 | **method chaining** alone cannot accommodate JavaScript’s **other syntaxes**: 126 | function calls, arithmetic, array/object literals, `await` and `yield`, etc. 127 | In this way, method chaining remains **limited** in its **applicability**. 128 | 129 | ### Pipe operators combine both worlds 130 | The pipe operator attempts to marry the **convenience** and ease of **method chaining** 131 | with the wide **applicability** of **expression nesting**. 132 | 133 | The general structure of all the pipe operators is 134 | `value |>` e1 `|>` e2 `|>` e3, 135 | where e1, e2, e3 136 | are all expressions that take consecutive values as their parameters. 137 | The `|>` operator then does some degree of magic to “pipe” `value` 138 | from the lefthand side into the righthand side. 139 | 140 |
141 | Real-world example, continued 142 | 143 | Continuing this deeply nested [real-world code from React][react/scripts/jest/jest-cli.js]: 144 | 145 | ```js 146 | console.log( 147 | chalk.dim( 148 | `$ ${Object.keys(envars) 149 | .map(envar => 150 | `${envar}=${envars[envar]}`) 151 | .join(' ') 152 | }`, 153 | 'node', 154 | args.join(' '))); 155 | ``` 156 | 157 | …we can **untangle** it as such using a pipe operator 158 | and a placeholder token (`%`) standing in for the previous operation’s value: 159 | 160 | ```js 161 | Object.keys(envars) 162 | .map(envar => `${envar}=${envars[envar]}`) 163 | .join(' ') 164 | |> `$ ${%}` 165 | |> chalk.dim(%, 'node', args.join(' ')) 166 | |> console.log(%); 167 | ``` 168 | 169 | Now, the human reader can **rapidly find** the **initial data** 170 | (what had been the most innermost expression, `envars`), 171 | then **linearly** read, from **left to right**, 172 | each transformation on the data. 173 | 174 |
175 | 176 | ### Temporary variables are often tedious 177 | One could argue that using **temporary variables** 178 | should be the only way to untangle deeply nested code. 179 | Explicitly naming every step’s variable 180 | causes something similar to method chaining to happen, 181 | with similar benefits to reading and writing code. 182 | 183 |
184 | Real-world example, continued 185 | 186 | For example, using our previous modified 187 | [real-world example from React][react/scripts/jest/jest-cli.js]: 188 | 189 | ```js 190 | Object.keys(envars) 191 | .map(envar => `${envar}=${envars[envar]}`) 192 | .join(' ') 193 | |> `$ ${%}` 194 | |> chalk.dim(%, 'node', args.join(' ')) 195 | |> console.log(%); 196 | ``` 197 | 198 | …a version using temporary variables would look like this: 199 | 200 | ```js 201 | const envarString = Object.keys(envars) 202 | .map(envar => `${envar}=${envars[envar]}`) 203 | .join(' '); 204 | const consoleText = `$ ${envarString}`; 205 | const coloredConsoleText = chalk.dim(consoleText, 'node', args.join(' ')); 206 | console.log(coloredConsoleText); 207 | ``` 208 | 209 |
210 | 211 | But there are reasons why we encounter deeply nested expressions 212 | in each other’s code **all the time in the real world**, 213 | **rather than** lines of temporary variables. 214 | And there are reasons why the **method-chain-based [fluent interfaces][]** 215 | of jQuery, Mocha, and so on are still **popular**. 216 | 217 | It is often simply too **tedious and wordy** to **write** 218 | code with a long sequence of temporary, single-use variables. 219 | It is arguably even tedious and visually noisy for a human to **read**, too. 220 | 221 | If [**naming** is one of the **most difficult tasks** in programming][naming hard], 222 | then programmers will **inevitably avoid naming** variables 223 | when they perceive their benefit to be relatively small. 224 | 225 | [naming hard]: https://martinfowler.com/bliki/TwoHardThings.html 226 | 227 | ### Reusing temporary variables is prone to unexpected mutation 228 | One could argue that using a single **mutable variable** with a short name 229 | would reduce the wordiness of temporary variables, achieving 230 | similar results as with the pipe operator. 231 | 232 |
233 | Real-world example, continued 234 | 235 | For example, our previous modified 236 | [real-world example from React][react/scripts/jest/jest-cli.js] 237 | could be re-written like this: 238 | ```js 239 | let _; 240 | _ = Object.keys(envars) 241 | .map(envar => `${envar}=${envars[envar]}`) 242 | .join(' '); 243 | _ = `$ ${_}`; 244 | _ = chalk.dim(_, 'node', args.join(' ')); 245 | _ = console.log(_); 246 | ``` 247 | 248 |
249 | 250 | But code like this is **not common** in real-world code. 251 | One reason for this is that mutable variables can **change unexpectedly**, 252 | causing silent bugs that are hard to find. 253 | For example, the variable might be accidentally referenced in a closure. 254 | Or it might be mistakenly reassigned within an expression. 255 | 256 |
257 | Example code 258 | 259 | ```js 260 | // setup 261 | function one () { return 1; } 262 | function double (x) { return x * 2; } 263 | 264 | let _; 265 | _ = one(); // _ is now 1. 266 | _ = double(_); // _ is now 2. 267 | _ = Promise.resolve().then(() => 268 | // This does *not* print 2! 269 | // It prints 1, because `_` is reassigned downstream. 270 | console.log(_)); 271 | 272 | // _ becomes 1 before the promise callback. 273 | _ = one(_); 274 | ``` 275 | 276 | This issue would not happen with the pipe operator. 277 | The topic token cannot be reassigned, and 278 | code outside of each step cannot change its binding. 279 | 280 | ```js 281 | let _; 282 | _ = one() 283 | |> double(%) 284 | |> Promise.resolve().then(() => 285 | // This prints 2, as intended. 286 | console.log(%)); 287 | 288 | _ = one(); 289 | ``` 290 | 291 |
292 | 293 | For this reason, code with mutable variables is also harder to read. 294 | To determine what the variable represents at any given point, 295 | you must to **search the entire preceding scope** for places where it is **reassigned**. 296 | 297 | The topic reference of a pipeline, on the other hand, has a limited lexical scope, 298 | and its binding is immutable within its scope. 299 | It cannot be accidentally reassigned, and it can be safely used in closures. 300 | 301 | Although the topic value also changes with each pipeline step, 302 | we only scan the previous step of the pipeline to make sense of it, 303 | leading to code that is easier to read. 304 | 305 | ### Temporary variables must be declared in statements 306 | Another benefit of the pipe operator over sequences of assignment statements 307 | (whether with mutable or with immutable temporary variables) 308 | is that they are **expressions**. 309 | 310 | Pipe expressions are expressions that can be directly returned, 311 | assigned to a variable, or used in contexts such as JSX expressions. 312 | 313 | Using temporary variables, on the other hand, requires sequences of statements. 314 | 315 |
316 | Examples 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 337 | 349 | 350 | 351 | 372 | 390 | 391 | 392 |
PipelinesTemporary Variables
327 | 328 | ```js 329 | const envVarFormat = vars => 330 | Object.keys(vars) 331 | .map(var => `${var}=${vars[var]}`) 332 | .join(' ') 333 | |> chalk.dim(%, 'node', args.join(' ')); 334 | ``` 335 | 336 | 338 | 339 | ```js 340 | const envVarFormat = (vars) => { 341 | let _ = Object.keys(vars); 342 | _ = _.map(var => `${var}=${vars[var]}`); 343 | _ = _.join(' '); 344 | return chalk.dim(_, 'node', args.join(' ')); 345 | } 346 | ``` 347 | 348 |
352 | 353 | ```jsx 354 | // This example uses JSX. 355 | return ( 356 |
    357 | { 358 | values 359 | |> Object.keys(%) 360 | |> [...Array.from(new Set(%))] 361 | |> %.map(envar => ( 362 |
  • doStuff(values) 364 | }>{envar}
  • 365 | )) 366 | } 367 |
368 | ); 369 | ``` 370 | 371 |
373 | 374 | ```js 375 | // This example uses JSX. 376 | let _ = values; 377 | _= Object.keys(_); 378 | _= [...Array.from(new Set(_))]; 379 | _= _.map(envar => ( 380 |
  • doStuff(values) 382 | }>{envar}
  • 383 | )); 384 | return ( 385 |
      {_}
    386 | ); 387 | ``` 388 | 389 |
    393 | 394 |
    395 | 396 | ## Why the Hack pipe operator 397 | There were **two competing proposals** for the pipe operator: Hack pipes and F# pipes. 398 | (Before that, there **was** a [third proposal for a “smart mix” of the first two proposals][smart mix], 399 | but it has been withdrawn, 400 | since its syntax is strictly a superset of one of the proposals’.) 401 | 402 | [smart mix]: https://github.com/js-choi/proposal-smart-pipelines/ 403 | 404 | The two pipe proposals just differ **slightly** on what the “magic” is, 405 | when we spell our code when using `|>`. 406 | 407 | **Both** proposals **reuse** existing language concepts: 408 | Hack pipes are based on the concept of the **expression**, 409 | while F# pipes are based on the concept of the **unary function**. 410 | 411 | Piping **expressions** and piping **unary functions** 412 | correspondingly have **small** and nearly **symmetrical trade-offs**. 413 | 414 | ### This proposal: Hack pipes 415 | In the **Hack language**’s pipe syntax, 416 | the righthand side of the pipe is an **expression** containing a special **placeholder**, 417 | which is evaluated with the placeholder bound to the result of evaluating the lefthand side's expression. 418 | That is, we write `value |> one(%) |> two(%) |> three(%)` 419 | to pipe `value` through the three functions. 420 | 421 | **Pro:** The righthand side can be **any expression**, 422 | and the placeholder can go anywhere any normal variable identifier could go, 423 | so we can pipe to any code we want **without any special rules**: 424 | 425 | * `value |> foo(%)` for unary function calls, 426 | * `value |> foo(1, %)` for n-ary function calls, 427 | * `value |> %.foo()` for method calls, 428 | * `value |> % + 1` for arithmetic, 429 | * `value |> [%, 0]` for array literals, 430 | * `value |> {foo: %}` for object literals, 431 | * `` value |> `${%}` `` for template literals, 432 | * `value |> new Foo(%)` for constructing objects, 433 | * `value |> await %` for awaiting promises, 434 | * `value |> (yield %)` for yielding generator values, 435 | * `value |> import(%)` for calling function-like keywords, 436 | * etc. 437 | 438 | **Con:** Piping through **unary functions** 439 | is **slightly more verbose** with Hack pipes than with F# pipes. 440 | This includes unary functions 441 | that were created by **[function-currying][] libraries** like [Ramda][], 442 | as well as [unary arrow functions 443 | that perform **complex destructuring** on their arguments][destruct]: 444 | Hack pipes would be slightly more verbose 445 | with an **explicit** function call suffix `(%)`. 446 | 447 | (Complex destructuring of the topic value 448 | will be easier when [do expressions][] progress, 449 | as you will then be able to do variable assignment/destructuring 450 | inside of a pipe body.) 451 | 452 | [function-currying]: https://en.wikipedia.org/wiki/Currying 453 | [Ramda]: https://ramdajs.com/ 454 | [destruct]: https://github.com/js-choi/proposal-hack-pipes/issues/4#issuecomment-817208635 455 | 456 | ### Alternative proposal: F# pipes 457 | In the [**F# language**’s pipe syntax][F# pipes], 458 | the righthand side of the pipe is an expression 459 | that must **evaluate into a unary function**, 460 | which is then **tacitly called** 461 | with the lefthand side’s value as its **sole argument**. 462 | That is, we write `value |> one |> two |> three` to pipe `value` 463 | through the three functions. 464 | `left |> right` becomes `right(left)`. 465 | This is called [tacit programming or point-free style][tacit]. 466 | 467 | [F# pipes]: https://github.com/valtech-nyc/proposal-fsharp-pipelines 468 | [tacit]: https://en.wikipedia.org/wiki/Tacit_programming 469 | 470 |
    471 | Real-world example, continued 472 | 473 | For example, using our previous modified 474 | [real-world example from React][react/scripts/jest/jest-cli.js]: 475 | 476 | ```js 477 | Object.keys(envars) 478 | .map(envar => `${envar}=${envars[envar]}`) 479 | .join(' ') 480 | |> `$ ${%}` 481 | |> chalk.dim(%, 'node', args.join(' ')) 482 | |> console.log(%); 483 | ``` 484 | 485 | …a version using F# pipes instead of Hack pipes would look like this: 486 | 487 | ```js 488 | Object.keys(envars) 489 | .map(envar => `${envar}=${envars[envar]}`) 490 | .join(' ') 491 | |> x=> `$ ${x}` 492 | |> x=> chalk.dim(x, 'node', args.join(' ')) 493 | |> console.log; 494 | ``` 495 | 496 |
    497 | 498 | **Pro:** The restriction that the righthand side 499 | **must** resolve to a unary function 500 | lets us write very terse pipes 501 | **when** the operation we want to perform 502 | is a **unary function call**: 503 | 504 | * `value |> foo` for unary function calls. 505 | 506 | This includes unary functions 507 | that were created by **[function-currying][] libraries** like [Ramda][], 508 | as well as [unary arrow functions 509 | that perform **complex destructuring** on their arguments][destruct]: 510 | F# pipes would be **slightly less verbose** 511 | with an **implicit** function call (no `(%)`). 512 | 513 | **Con:** The restriction means that **any operations** 514 | that are performed by **other syntax** 515 | must be made **slightly more verbose** by **wrapping** the operation 516 | in a unary **arrow function**: 517 | 518 | * `value |> x=> x.foo()` for method calls, 519 | * `value |> x=> x + 1` for arithmetic, 520 | * `value |> x=> [x, 0]` for array literals, 521 | * `value |> x=> ({foo: x})` for object literals, 522 | * `` value |> x=> `${x}` `` for template literals, 523 | * `value |> x=> new Foo(x)` for constructing objects, 524 | * `value |> x=> import(x)` for calling function-like keywords, 525 | * etc. 526 | 527 | Even calling **named functions** requires **wrapping** 528 | when we need to pass **more than one argument**: 529 | 530 | * `value |> x=> foo(1, x)` for n-ary function calls. 531 | 532 | **Con:** The **`await` and `yield`** operations are **scoped** 533 | to their **containing function**, 534 | and thus **cannot be handled by unary functions** alone. 535 | If we want to integrate them into a pipe expression, 536 | [`await` and `yield` must be handled as **special syntax cases**][enhanced F# pipes]: 537 | 538 | * `value |> await` for awaiting promises, and 539 | * `value |> yield` for yielding generator values. 540 | 541 | [enhanced F# pipes]: https://github.com/valtech-nyc/proposal-fsharp-pipelines/ 542 | 543 | ### Hack pipes favor more common expressions 544 | **Both** Hack pipes and F# pipes respectively impose 545 | a small **syntax tax** on different expressions:\ 546 | **Hack pipes** slightly tax only **unary function calls**, and\ 547 | **F# pipes** slightly tax **all expressions except** unary function calls. 548 | 549 | In **both** proposals, the syntax tax per taxed expression is **small** 550 | (**both** `(%)` and `x=>` are **only three characters**). 551 | However, the tax is **multiplied** by the **prevalence** 552 | of its respectively taxed expressions. 553 | It therefore might make sense 554 | to impose a tax on whichever expressions are **less common** 555 | and to **optimize** in favor of whichever expressions are **more common**. 556 | 557 | Unary function calls are in general **less common** 558 | than **all** expressions **except** unary functions. 559 | In particular, **method** calling and **n-ary function** calling 560 | will **always** be **popular**; 561 | in general frequency, 562 | **unary** function calling is equal to or exceeded by 563 | those two cases **alone** – 564 | let alone by other ubiquitous syntaxes 565 | such as **array literals**, **object literals**, 566 | and **arithmetic operations**. 567 | This explainer contains several [real-world examples][] 568 | of this difference in prevalence. 569 | 570 | [real-world examples]: #real-world-examples 571 | 572 | Furthermore, several other proposed **new syntaxes**, 573 | such as **[extension calling][]**, 574 | **[do expressions][]**, 575 | and **[record/tuple literals][]**, 576 | will also likely become **pervasive** in the **future**. 577 | Likewise, **arithmetic** operations would also become **even more common** 578 | if TC39 standardizes **[operator overloading][]**. 579 | Untangling these future syntaxes’ expressions would be more fluent 580 | with Hack pipes compared to F# pipes. 581 | 582 | [extension calling]: https://github.com/tc39/proposal-extensions/ 583 | [do expressions]: https://github.com/tc39/proposal-do-expressions/ 584 | [record/tuple literals]: https://github.com/tc39/proposal-record-tuple/ 585 | [operator overloading]: https://github.com/tc39/proposal-operator-overloading/ 586 | 587 | ### Hack pipes might be simpler to use 588 | The syntax tax of Hack pipes on unary function calls 589 | (i.e., the `(%)` to invoke the righthand side’s unary function) 590 | is **not a special case**: 591 | it simply is **explicitly writing ordinary code**, 592 | in **the way we normally would** without a pipe. 593 | 594 | On the other hand, **F# pipes require** us to **distinguish** 595 | between “code that resolves to an unary function” 596 | versus **“any other expression”** – 597 | and to remember to add the arrow-function wrapper around the latter case. 598 | 599 | For example, with Hack pipes, `value |> someFunction + 1` 600 | is **invalid syntax** and will **fail early**. 601 | There is no need to recognize that `someFunction + 1` 602 | will not evaluate into a unary function. 603 | But with F# pipes, `value |> someFunction + 1` is **still valid syntax** – 604 | it’ll just **fail late** at **runtime**, 605 | because `someFunction + 1` isn’t callable. 606 | 607 | ### TC39 has rejected F# pipes multiple times 608 | The pipe champion group has presented F# pipes for Stage 2 to TC39 **twice**. 609 | It was **unsuccessful** in advancing to Stage 2 both times. 610 | Both F# pipes (and [partial function application (PFA)][PFA syntax]) 611 | have run into strong pushback from multiple other TC39 representatives 612 | due to various concerns. These have included: 613 | 614 | * Memory performance concerns (e.g., [especially from browser-engine implementors][V8 pushback]), 615 | * Syntax concerns about `await`. 616 | * Concerns about encouraging ecosystem bifurcation/forking, etc. 617 | 618 | [V8 pushback]: https://github.com/tc39/proposal-pipeline-operator/blob/main/HISTORY.md#2021-07 619 | 620 | This pushback has occurred from **outside** the pipe champion group. 621 | See [HISTORY.md][] for more information. 622 | 623 | It is the pipe champion group’s belief that any pipe operator is better than none, 624 | in order to [easily linearize deeply nested expressions](#why-a-pipe-operator) 625 | without resorting to named variables. 626 | Many members of the champion group believe that Hack pipes are slightly better than F# pipes, 627 | and some members of the champion group believe that F# pipes are slightly better than Hack pipes. 628 | But everyone in the champion group agrees that F# pipes have met with far too much resistance 629 | to be able to pass TC39 in the foreseeable future. 630 | 631 | To emphasize, it is likely that an attempt to switch from Hack pipes back to F# pipes 632 | will result in TC39 never agreeing to any pipes at all. 633 | [PFA syntax][] is similarly facing an uphill battle in TC39 (see [HISTORY.md][]). 634 | Many members of the pipe champion group think this is unfortunate, 635 | and they are willing to fight again **later** for an [F#-pipe split mix][split mix] and [PFA syntax][]. 636 | But there are quite a few representatives (including [browser-engine implementers][V8 pushback]) 637 | outside of the Pipe Champion Group 638 | who are generally against encouraging [tacit programming][] (and [PFA syntax][]), 639 | regardless of Hack pipes. 640 | 641 | [HISTORY.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/HISTORY.md 642 | [tacit programming]: https://en.wikipedia.org/wiki/Tacit_programming 643 | [PFA syntax]: https://github.com/tc39/proposal-partial-application 644 | [split mix]: #tacit-unary-function-application-syntax 645 | 646 | ## Description 647 | (A [formal draft specification][specification] is available.) 648 | 649 | The **topic reference** `%` is a **nullary operator**. 650 | It acts as a placeholder for a **topic value**, 651 | and it is **lexically scoped** and **immutable**. 652 | 653 |
    654 | % is not a final choice 655 | 656 | (The precise [**token** for the topic reference is **not final**][token bikeshedding]. 657 | `%` could instead be `^`, or many other tokens. 658 | We plan to [**bikeshed** what actual token to use][token bikeshedding] 659 | before advancing to Stage 3. 660 | However, `%` seems to be the [least syntactically problematic][], 661 | and it also resembles the placeholders of **[printf format strings][]** 662 | and [**Clojure**’s `#(%)` **function literals**][Clojure function literals].) 663 | 664 | [least syntactically problematic]: https://github.com/js-choi/proposal-hack-pipes/issues/2 665 | [Clojure function literals]: https://clojure.org/reference/reader#_dispatch 666 | [printf format strings]: https://en.wikipedia.org/wiki/Printf_format_string 667 | 668 |
    669 | 670 | The **pipe operator** `|>` is an **infix operator** 671 | that forms a **pipe expression** (also called a **pipeline**). 672 | It evaluates its lefthand side (the **pipe head** or **pipe input**), 673 | immutably **binds** the resulting value (the **topic value**) to the **topic reference**, 674 | then evaluates its righthand side (the **pipe body**) with that binding. 675 | The resulting value of the righthand side 676 | becomes the whole pipe expression’s final value (the **pipe output**). 677 | 678 | The pipe operator’s precedence is the **same** as: 679 | * the function arrow `=>`; 680 | * the assignment operators `=`, `+=`, etc.; 681 | * the generator operators `yield` and `yield *`; 682 | 683 | It is **tighter** than only the comma operator `,`.\ 684 | It is **looser** than **all other** operators. 685 | 686 | For example, `v => v |> % == null |> foo(%, 0)`\ 687 | would group into `v => (v |> (% == null) |> foo(%, 0))`,\ 688 | which in turn is equivalent to `v => foo(v == null, 0)`. 689 | 690 | A pipe body **must** use its topic value **at least once**. 691 | For example, `value |> foo + 1` is **invalid syntax**, 692 | because its body does not contain a topic reference. 693 | This design is because **omission** of the topic reference 694 | from a pipe expression’s body 695 | is almost certainly an **accidental** programmer error. 696 | 697 | Likewise, a topic reference **must** be contained in a pipe body. 698 | Using a topic reference outside of a pipe body 699 | is also **invalid syntax**. 700 | 701 | To prevent confusing grouping, 702 | it is **invalid** syntax to use **other** operators that have **similar precedence** 703 | (i.e., the arrow `=>`, the ternary conditional operator `?` `:`, 704 | the assignment operators, and the `yield` operator) 705 | as a **pipe head or body**. 706 | When using `|>` with these operators, we must use **parentheses** 707 | to explicitly indicate what grouping is correct. 708 | For example, `a |> b ? % : c |> %.d` is invalid syntax; 709 | it should be corrected to either `a |> (b ? % : c) |> %.d` 710 | or `a |> (b ? % : c |> %.d)`. 711 | 712 | Lastly, topic bindings **inside dynamically compiled** code 713 | (e.g., with `eval` or `new Function`) 714 | **cannot** be used **outside** of that code. 715 | For example, `v |> eval('% + 1')` will throw a syntax error 716 | when the `eval` expression is evaluated at runtime. 717 | 718 | There are **no other special rules**. 719 | 720 | A natural result of these rules is that, 721 | if we need to interpose a **side effect** 722 | in the middle of a chain of pipe expressions, 723 | without modifying the data being piped through, 724 | then we could use a **comma expression**, 725 | such as with `value |> (sideEffect(), %)`. 726 | As usual, the comma expression will evaluate to its righthand side `%`, 727 | essentially passing through the topic value without modifying it. 728 | This is especially useful for quick debugging: `value |> (console.log(%), %)`. 729 | 730 | ## Real-world examples 731 | The only changes to the original examples were dedentation and removal of comments. 732 | 733 | From [jquery/build/tasks/sourceMap.js][]: 734 | ```js 735 | // Status quo 736 | var minLoc = Object.keys( grunt.config( "uglify.all.files" ) )[ 0 ]; 737 | 738 | // With pipes 739 | var minLoc = grunt.config('uglify.all.files') |> Object.keys(%)[0]; 740 | ``` 741 | 742 | From [node/deps/npm/lib/unpublish.js][]: 743 | ```js 744 | // Status quo 745 | const json = await npmFetch.json(npa(pkgs[0]).escapedName, opts); 746 | 747 | // With pipes 748 | const json = pkgs[0] |> npa(%).escapedName |> await npmFetch.json(%, opts); 749 | ``` 750 | 751 | From [underscore.js][]: 752 | ```js 753 | // Status quo 754 | return filter(obj, negate(cb(predicate)), context); 755 | 756 | // With pipes 757 | return cb(predicate) |> _.negate(%) |> _.filter(obj, %, context); 758 | ``` 759 | 760 | From [ramda.js][]. 761 | ```js 762 | // Status quo 763 | return xf['@@transducer/result'](obj[methodName](bind(xf['@@transducer/step'], xf), acc)); 764 | 765 | // With pipes 766 | return xf 767 | |> bind(%['@@transducer/step'], %) 768 | |> obj[methodName](%, acc) 769 | |> xf['@@transducer/result'](%); 770 | ``` 771 | 772 | From [ramda.js][]. 773 | ```js 774 | // Status quo 775 | try { 776 | return tryer.apply(this, arguments); 777 | } catch (e) { 778 | return catcher.apply(this, _concat([e], arguments)); 779 | } 780 | 781 | // With pipes: Note the visual parallelism between the two clauses. 782 | try { 783 | return arguments 784 | |> tryer.apply(this, %); 785 | } catch (e) { 786 | return arguments 787 | |> _concat([e], %) 788 | |> catcher.apply(this, %); 789 | } 790 | ``` 791 | 792 | From [express/lib/response.js][]. 793 | ```js 794 | // Status quo 795 | return this.set('Link', link + Object.keys(links).map(function(rel){ 796 | return '<' + links[rel] + '>; rel="' + rel + '"'; 797 | }).join(', ')); 798 | 799 | // With pipes 800 | return links 801 | |> Object.keys(%).map(function (rel) { 802 | return '<' + links[rel] + '>; rel="' + rel + '"'; 803 | }) 804 | |> link + %.join(', ') 805 | |> this.set('Link', %); 806 | ``` 807 | 808 | From [react/scripts/jest/jest-cli.js][]. 809 | ```js 810 | // Status quo 811 | console.log( 812 | chalk.dim( 813 | `$ ${Object.keys(envars) 814 | .map(envar => `${envar}=${envars[envar]}`) 815 | .join(' ')}`, 816 | 'node', 817 | args.join(' ') 818 | ) 819 | ); 820 | 821 | // With pipes 822 | Object.keys(envars) 823 | .map(envar => `${envar}=${envars[envar]}`) 824 | .join(' ') 825 | |> `$ ${%}` 826 | |> chalk.dim(%, 'node', args.join(' ')) 827 | |> console.log(%); 828 | ``` 829 | 830 | From [ramda.js][]. 831 | ```js 832 | // Status quo 833 | return _reduce(xf(typeof fn === 'function' ? _xwrap(fn) : fn), acc, list); 834 | 835 | // With pipes 836 | return fn 837 | |> (typeof % === 'function' ? _xwrap(%) : %) 838 | |> xf(%) 839 | |> _reduce(%, acc, list); 840 | ``` 841 | 842 | From [jquery/src/core/init.js][]. 843 | ```js 844 | // Status quo 845 | jQuery.merge( this, jQuery.parseHTML( 846 | match[ 1 ], 847 | context && context.nodeType ? context.ownerDocument || context : document, 848 | true 849 | ) ); 850 | 851 | // With pipes 852 | context 853 | |> (% && %.nodeType ? %.ownerDocument || % : document) 854 | |> jQuery.parseHTML(match[1], %, true) 855 | |> jQuery.merge(%); 856 | ``` 857 | 858 | [ramda.js]: https://github.com/ramda/ramda/blob/v0.27.1/dist/ramda.js 859 | [node/deps/npm/lib/unpublish.js]: https://github.com/nodejs/node/blob/v16.x/deps/npm/lib/unpublish.js 860 | [node/deps/v8/test/mjsunit/regress/regress-crbug-158185.js]: https://github.com/nodejs/node/blob/v16.x/deps/v8/test/mjsunit/regress/regress-crbug-158185.js 861 | [express/lib/response.js]: https://github.com/expressjs/express/blob/5.0/lib/response.js 862 | [react/scripts/jest/jest-cli.js]: https://github.com/facebook/react/blob/17.0.2/scripts/jest/jest-cli.js 863 | [jquery/build/tasks/sourceMap.js]: https://github.com/jquery/jquery/blob/2.2-stable/build/tasks/sourcemap.js 864 | [jquery/src/core/init.js]: https://github.com/jquery/jquery/blob/2.2-stable/src/core/init.js 865 | [underscore.js]: https://underscorejs.org/docs/underscore-esm.html 866 | 867 | ## Relationships with other proposals 868 | 869 | ### `Function` helpers 870 | Hack pipes can and would coexist with the [`Function` helpers proposal][helpers], 871 | including its `pipe` and `flow` functions. 872 | These simple (and commonly downloaded) convenience functions 873 | manipulate unary functions without extra syntax. 874 | 875 | [helpers]: https://github.com/js-choi/proposal-function-helpers 876 | 877 | [TC39 has rejected the F# pipe operator twice][rejected]. 878 | Given this reality, TC39 is considerably more likely to pass 879 | `pipe` and `flow` helper functions than a similar syntactic operator. 880 | 881 | [rejected]: #tc39-has-rejected-f-pipes-multiple-times 882 | 883 | Standardized `pipe` and `flow` convenience functions 884 | may also obviate some of the need for a F#-pipe infix operator. 885 | (They would not preclude standardizing an equivalent operator later. 886 | For example, TC39 standardized binary `**` even when `Math.pow` existed.) 887 | 888 | ### Partial-function-application syntax 889 | Hack pipes can coexist with a syntax for **partial function application** (PFA). 890 | There are two approaches with which they may coexist. 891 | 892 | The **first approach** is with an **eagerly** evaluated PFA syntax, 893 | which has [already been proposed in proposal-partial-application][PFA syntax]. 894 | This eager PFA syntax would add an `…~(…)` operator. 895 | The operator’s right-hand side would be a list of arguments, 896 | each of which is an ordinary expression or a `?` placeholder. 897 | Each consecutive `?` placeholder would represent another parameter. 898 | 899 | Ordinary expressions would be evaluated **before** the function is created. 900 | For example, `f~(g(), ?, h(), ?)` would evaluate `f`, then `g()`, then `h()`, 901 | and *then* it would create a partially applied version of `f` with two arguments. 902 | 903 | An optional number after `?` placeholder 904 | would override the parameter’s position. 905 | For example, `f~(?1, ?0)` would have two parameters but would switch them when calling `f`. 906 | 907 | The **second approach** is with a **lazily** evaluated syntax. 908 | This could be handled with an **extension to Hack pipes**, 909 | with a syntax further inspired by 910 | [Clojure’s `#(%1 %2)` function literals][Clojure function literals]. 911 | It would do so by **combining** the Hack pipe `|>` 912 | with the **arrow function** `=>` 913 | into a **pipe-function** operator `+>`, 914 | which would use the same general rules as `|>`. 915 | 916 | `+>` would be a **prefix operator** that **creates a new function**, 917 | which in turn **binds its argument(s)** to topic references. 918 | **Non-unary functions** would be created 919 | by including topic references with **numbers** (`%0`, `%1`, `%2`, etc.) or `...`. 920 | `%0` (equivalent to plain `%`) would be bound to the **zeroth argument**, 921 | `%1` would be bound to the next argument, and so on. 922 | `%...` would be bound to an array of **rest arguments**. 923 | And just as with `|>`, `+>` would require its body 924 | to contain at least one topic reference 925 | in order to be syntactically valid. 926 | 927 | | Eager PFA | Pipe functions | 928 | | ---------------------------| -------------------------- | 929 | |`a.map(f~(?, 0))` |`a.map(+> f(%, 0))` | 930 | |`a.map(f~(?, ?, 0))` |`a.map(+> f(%0, %1, 0))` | 931 | |`a.map(x=> x + 1)` |`a.map(+> % + 1)` | 932 | |`a.map(x=> x + x)` |`a.map(+> % + %)` | 933 | |`a.map(x=> f(x, x))` |`a.map(+> f(%, %))` | 934 | 935 | In contrast to the [eagerly evaluated PFA syntax][PFA syntax], 936 | topic functions would **lazily** evaluate its arguments, 937 | just like how an arrow function would. 938 | 939 | For example, `+> f(g(), %0, h(), %1)` would evaluate `f`, 940 | and then it would create an arrow function that closes over `g` and `h`. 941 | The created function would **not** evaluate `g()` or `h()` 942 | until the every time the created function is called. 943 | 944 | No matter the approach taken, Hack pipes could coexist with PFA. 945 | 946 | ### Eventual sending / pipelining 947 | Despite sharing the word “pipe” in their name, 948 | the pipe operator and the [eventual-send proposal][]’s remote-object pipelines 949 | are orthogonal and independent. 950 | They can coexist and even work together. 951 | 952 | ```js 953 | const fileP = E( 954 | E(target).openDirectory(dirName) 955 | ).openFile(fileName); 956 | 957 | const fileP = target 958 | |> E(%).openDirectory(dirName) 959 | |> E(%).openFile(fileName); 960 | ``` 961 | 962 | [eventual-send proposal]: https://github.com/tc39/proposal-eventual-send/ 963 | 964 | ## Possible future extensions 965 | 966 | ### Hack-pipe syntax for `if`, `catch`, and `for`–`of` 967 | Many **`if`, `catch`, and `for` statements** could become pithier 968 | if they gained **“pipe syntax”** that bound the topic reference. 969 | 970 | `if () |>` would bind its condition value to `%`,\ 971 | `catch |>` would bind its caught error to `%`,\ 972 | and `for (of) |>` would consecutively bind each of its iterator’s values to `%`. 973 | 974 | | Status quo | Hack-pipe statement syntax | 975 | | --------------------------- | -------------------------- | 976 | |`const c = f(); if (c) g(c);`|`if (f()) \|> g(%);` | 977 | |`catch (e) f(e);` |`catch \|> f(%);` | 978 | |`for (const v of f()) g(v);` |`for (f()) \|> g(%);` | 979 | 980 | ### Optional Hack pipes 981 | A **short-circuiting** optional-pipe operator `|?>` could also be useful, 982 | much in the way `?.` is useful for optional method calls. 983 | 984 | For example, `value |> (% == null ? % : await foo(%) |> (% == null ? % : % + 1))`\ 985 | would be equivalent to `value |?> await foo(%) |?> % + 1`. 986 | 987 | ### Tacit unary function application syntax 988 | **Syntax** for **tacit unary function application** – that is, the F# pipe operator – 989 | has been [rejected twice by TC39][rejected]. 990 | However, they could still eventually be added to the language in two ways. 991 | 992 | First, it can be added as a convenience function `Function.pipe`. 993 | This is what the [function-helpers proposal][helpers] proposes. 994 | `Function.pipe` may obviate much of the need for an F#-pipe operator, 995 | while still not closing off the possibility of an F#-pipe operator. 996 | 997 | Secondly, it can be added as **another pipe operator** `|>>` – 998 | similarly to how [Clojure has multiple pipe macros][Clojure pipes] 999 | `->`, `->>`, and `as->`.\ 1000 | For example, `value |> % + 1 |>> f |> g(%, 0)`\ 1001 | would mean `value |> % + 1 |> f(%) |> g(%, 0)`. 1002 | 1003 | [Clojure pipes]: https://clojure.org/guides/threading_macros 1004 | 1005 | There was an [informal proposal for such a **split mix** of two pipe operators][split mix], 1006 | which was set aside in favor of single-operator proposals. 1007 | This split mix might return as a proposal after Hack pipes. 1008 | 1009 | [split mix]: https://github.com/tc39/proposal-pipeline-operator/wiki#proposal-3-split-mix 1010 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proposal-pipeline-operator", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "proposal-pipeline-operator", 9 | "version": "1.0.0", 10 | "license": "BSD-3-Clause", 11 | "dependencies": { 12 | "ecmarkup": "^12.0.0" 13 | } 14 | }, 15 | "node_modules/@babel/code-frame": { 16 | "version": "7.12.11", 17 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", 18 | "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", 19 | "dependencies": { 20 | "@babel/highlight": "^7.10.4" 21 | } 22 | }, 23 | "node_modules/@babel/helper-validator-identifier": { 24 | "version": "7.16.7", 25 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", 26 | "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", 27 | "engines": { 28 | "node": ">=6.9.0" 29 | } 30 | }, 31 | "node_modules/@babel/highlight": { 32 | "version": "7.16.10", 33 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", 34 | "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", 35 | "dependencies": { 36 | "@babel/helper-validator-identifier": "^7.16.7", 37 | "chalk": "^2.0.0", 38 | "js-tokens": "^4.0.0" 39 | }, 40 | "engines": { 41 | "node": ">=6.9.0" 42 | } 43 | }, 44 | "node_modules/@babel/highlight/node_modules/ansi-styles": { 45 | "version": "3.2.1", 46 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 47 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 48 | "dependencies": { 49 | "color-convert": "^1.9.0" 50 | }, 51 | "engines": { 52 | "node": ">=4" 53 | } 54 | }, 55 | "node_modules/@babel/highlight/node_modules/chalk": { 56 | "version": "2.4.2", 57 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 58 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 59 | "dependencies": { 60 | "ansi-styles": "^3.2.1", 61 | "escape-string-regexp": "^1.0.5", 62 | "supports-color": "^5.3.0" 63 | }, 64 | "engines": { 65 | "node": ">=4" 66 | } 67 | }, 68 | "node_modules/@babel/highlight/node_modules/color-convert": { 69 | "version": "1.9.3", 70 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 71 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 72 | "dependencies": { 73 | "color-name": "1.1.3" 74 | } 75 | }, 76 | "node_modules/@babel/highlight/node_modules/color-name": { 77 | "version": "1.1.3", 78 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 79 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 80 | }, 81 | "node_modules/@babel/highlight/node_modules/has-flag": { 82 | "version": "3.0.0", 83 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 84 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 85 | "engines": { 86 | "node": ">=4" 87 | } 88 | }, 89 | "node_modules/@babel/highlight/node_modules/supports-color": { 90 | "version": "5.5.0", 91 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 92 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 93 | "dependencies": { 94 | "has-flag": "^3.0.0" 95 | }, 96 | "engines": { 97 | "node": ">=4" 98 | } 99 | }, 100 | "node_modules/@esfx/async-canceltoken": { 101 | "version": "1.0.0-pre.30", 102 | "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0-pre.30.tgz", 103 | "integrity": "sha512-4he0W+ZKH4OO4RvGfmATIibO5JzGLQqwm4Dp3X15bWnguDTmmOFt3Qt169Doij/gXxn2aPpZvxUaYIEebi8Xig==", 104 | "dependencies": { 105 | "@esfx/cancelable": "^1.0.0-pre.30", 106 | "@esfx/collections-linkedlist": "^1.0.0-pre.24", 107 | "@esfx/disposable": "^1.0.0-pre.30", 108 | "@esfx/internal-guards": "^1.0.0-pre.23", 109 | "@esfx/internal-tag": "^1.0.0-pre.19", 110 | "tslib": "^2.1.0" 111 | } 112 | }, 113 | "node_modules/@esfx/cancelable": { 114 | "version": "1.0.0-pre.30", 115 | "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", 116 | "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", 117 | "dependencies": { 118 | "@esfx/disposable": "^1.0.0-pre.30", 119 | "@esfx/internal-deprecate": "^1.0.0-pre.24", 120 | "@esfx/internal-guards": "^1.0.0-pre.23", 121 | "@esfx/internal-tag": "^1.0.0-pre.19" 122 | } 123 | }, 124 | "node_modules/@esfx/collection-core": { 125 | "version": "1.0.0-pre.24", 126 | "resolved": "https://registry.npmjs.org/@esfx/collection-core/-/collection-core-1.0.0-pre.24.tgz", 127 | "integrity": "sha512-OIgMS91JmjSoRWD7u/DfnDzo8vDggeTeUPRi1p5WhyboY0+IwmetEqgeHZb8bpka/SsmtYX5qxqEjeqNXqh+pA==", 128 | "dependencies": { 129 | "@esfx/internal-deprecate": "^1.0.0-pre.24", 130 | "@esfx/internal-guards": "^1.0.0-pre.23" 131 | } 132 | }, 133 | "node_modules/@esfx/collections-linkedlist": { 134 | "version": "1.0.0-pre.24", 135 | "resolved": "https://registry.npmjs.org/@esfx/collections-linkedlist/-/collections-linkedlist-1.0.0-pre.24.tgz", 136 | "integrity": "sha512-Maya8jXH0xvzyfeSH88/j2b5gavO/mluslgIC2Ttdz8rh6+3o8/pVYriceH/Jinn4pgTEzDhO6Rn/aruZG0+Ug==", 137 | "dependencies": { 138 | "@esfx/collection-core": "^1.0.0-pre.24", 139 | "@esfx/equatable": "^1.0.0-pre.19", 140 | "@esfx/internal-guards": "^1.0.0-pre.23" 141 | } 142 | }, 143 | "node_modules/@esfx/disposable": { 144 | "version": "1.0.0-pre.30", 145 | "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", 146 | "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==" 147 | }, 148 | "node_modules/@esfx/equatable": { 149 | "version": "1.0.0-pre.19", 150 | "resolved": "https://registry.npmjs.org/@esfx/equatable/-/equatable-1.0.0-pre.19.tgz", 151 | "integrity": "sha512-+f6Xm6GOigyGx7t0D0IyG9Z0AuYDhNWjwV49vs5uNG/+0VQAOSYjmnpSzTZRYcYwxW52DmWJWFYNY8bvCDD2ag==" 152 | }, 153 | "node_modules/@esfx/internal-deprecate": { 154 | "version": "1.0.0-pre.24", 155 | "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", 156 | "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==" 157 | }, 158 | "node_modules/@esfx/internal-guards": { 159 | "version": "1.0.0-pre.23", 160 | "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", 161 | "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", 162 | "dependencies": { 163 | "@esfx/type-model": "^1.0.0-pre.23" 164 | } 165 | }, 166 | "node_modules/@esfx/internal-tag": { 167 | "version": "1.0.0-pre.19", 168 | "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", 169 | "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==" 170 | }, 171 | "node_modules/@esfx/type-model": { 172 | "version": "1.0.0-pre.23", 173 | "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", 174 | "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==" 175 | }, 176 | "node_modules/@nodelib/fs.scandir": { 177 | "version": "2.1.5", 178 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 179 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 180 | "dependencies": { 181 | "@nodelib/fs.stat": "2.0.5", 182 | "run-parallel": "^1.1.9" 183 | }, 184 | "engines": { 185 | "node": ">= 8" 186 | } 187 | }, 188 | "node_modules/@nodelib/fs.stat": { 189 | "version": "2.0.5", 190 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 191 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 192 | "engines": { 193 | "node": ">= 8" 194 | } 195 | }, 196 | "node_modules/@nodelib/fs.walk": { 197 | "version": "1.2.8", 198 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 199 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 200 | "dependencies": { 201 | "@nodelib/fs.scandir": "2.1.5", 202 | "fastq": "^1.6.0" 203 | }, 204 | "engines": { 205 | "node": ">= 8" 206 | } 207 | }, 208 | "node_modules/@tootallnate/once": { 209 | "version": "2.0.0", 210 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", 211 | "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", 212 | "engines": { 213 | "node": ">= 10" 214 | } 215 | }, 216 | "node_modules/abab": { 217 | "version": "2.0.5", 218 | "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", 219 | "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" 220 | }, 221 | "node_modules/acorn": { 222 | "version": "8.7.0", 223 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", 224 | "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", 225 | "bin": { 226 | "acorn": "bin/acorn" 227 | }, 228 | "engines": { 229 | "node": ">=0.4.0" 230 | } 231 | }, 232 | "node_modules/acorn-globals": { 233 | "version": "6.0.0", 234 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", 235 | "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", 236 | "dependencies": { 237 | "acorn": "^7.1.1", 238 | "acorn-walk": "^7.1.1" 239 | } 240 | }, 241 | "node_modules/acorn-globals/node_modules/acorn": { 242 | "version": "7.4.1", 243 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 244 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", 245 | "bin": { 246 | "acorn": "bin/acorn" 247 | }, 248 | "engines": { 249 | "node": ">=0.4.0" 250 | } 251 | }, 252 | "node_modules/acorn-walk": { 253 | "version": "7.2.0", 254 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", 255 | "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", 256 | "engines": { 257 | "node": ">=0.4.0" 258 | } 259 | }, 260 | "node_modules/agent-base": { 261 | "version": "6.0.2", 262 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 263 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 264 | "dependencies": { 265 | "debug": "4" 266 | }, 267 | "engines": { 268 | "node": ">= 6.0.0" 269 | } 270 | }, 271 | "node_modules/ansi-styles": { 272 | "version": "4.3.0", 273 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 274 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 275 | "dependencies": { 276 | "color-convert": "^2.0.1" 277 | }, 278 | "engines": { 279 | "node": ">=8" 280 | }, 281 | "funding": { 282 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 283 | } 284 | }, 285 | "node_modules/argparse": { 286 | "version": "1.0.10", 287 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 288 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 289 | "dependencies": { 290 | "sprintf-js": "~1.0.2" 291 | } 292 | }, 293 | "node_modules/array-back": { 294 | "version": "3.1.0", 295 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", 296 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", 297 | "engines": { 298 | "node": ">=6" 299 | } 300 | }, 301 | "node_modules/asynckit": { 302 | "version": "0.4.0", 303 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 304 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 305 | }, 306 | "node_modules/braces": { 307 | "version": "3.0.2", 308 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 309 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 310 | "dependencies": { 311 | "fill-range": "^7.0.1" 312 | }, 313 | "engines": { 314 | "node": ">=8" 315 | } 316 | }, 317 | "node_modules/browser-process-hrtime": { 318 | "version": "1.0.0", 319 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", 320 | "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" 321 | }, 322 | "node_modules/chalk": { 323 | "version": "4.1.2", 324 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 325 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 326 | "dependencies": { 327 | "ansi-styles": "^4.1.0", 328 | "supports-color": "^7.1.0" 329 | }, 330 | "engines": { 331 | "node": ">=10" 332 | }, 333 | "funding": { 334 | "url": "https://github.com/chalk/chalk?sponsor=1" 335 | } 336 | }, 337 | "node_modules/color-convert": { 338 | "version": "2.0.1", 339 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 340 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 341 | "dependencies": { 342 | "color-name": "~1.1.4" 343 | }, 344 | "engines": { 345 | "node": ">=7.0.0" 346 | } 347 | }, 348 | "node_modules/color-name": { 349 | "version": "1.1.4", 350 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 351 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 352 | }, 353 | "node_modules/combined-stream": { 354 | "version": "1.0.8", 355 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 356 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 357 | "dependencies": { 358 | "delayed-stream": "~1.0.0" 359 | }, 360 | "engines": { 361 | "node": ">= 0.8" 362 | } 363 | }, 364 | "node_modules/command-line-args": { 365 | "version": "5.2.1", 366 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", 367 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", 368 | "dependencies": { 369 | "array-back": "^3.1.0", 370 | "find-replace": "^3.0.0", 371 | "lodash.camelcase": "^4.3.0", 372 | "typical": "^4.0.0" 373 | }, 374 | "engines": { 375 | "node": ">=4.0.0" 376 | } 377 | }, 378 | "node_modules/command-line-usage": { 379 | "version": "6.1.1", 380 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz", 381 | "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==", 382 | "dependencies": { 383 | "array-back": "^4.0.1", 384 | "chalk": "^2.4.2", 385 | "table-layout": "^1.0.1", 386 | "typical": "^5.2.0" 387 | }, 388 | "engines": { 389 | "node": ">=8.0.0" 390 | } 391 | }, 392 | "node_modules/command-line-usage/node_modules/ansi-styles": { 393 | "version": "3.2.1", 394 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 395 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 396 | "dependencies": { 397 | "color-convert": "^1.9.0" 398 | }, 399 | "engines": { 400 | "node": ">=4" 401 | } 402 | }, 403 | "node_modules/command-line-usage/node_modules/array-back": { 404 | "version": "4.0.2", 405 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", 406 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", 407 | "engines": { 408 | "node": ">=8" 409 | } 410 | }, 411 | "node_modules/command-line-usage/node_modules/chalk": { 412 | "version": "2.4.2", 413 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 414 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 415 | "dependencies": { 416 | "ansi-styles": "^3.2.1", 417 | "escape-string-regexp": "^1.0.5", 418 | "supports-color": "^5.3.0" 419 | }, 420 | "engines": { 421 | "node": ">=4" 422 | } 423 | }, 424 | "node_modules/command-line-usage/node_modules/color-convert": { 425 | "version": "1.9.3", 426 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 427 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 428 | "dependencies": { 429 | "color-name": "1.1.3" 430 | } 431 | }, 432 | "node_modules/command-line-usage/node_modules/color-name": { 433 | "version": "1.1.3", 434 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 435 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 436 | }, 437 | "node_modules/command-line-usage/node_modules/has-flag": { 438 | "version": "3.0.0", 439 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 440 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 441 | "engines": { 442 | "node": ">=4" 443 | } 444 | }, 445 | "node_modules/command-line-usage/node_modules/supports-color": { 446 | "version": "5.5.0", 447 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 448 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 449 | "dependencies": { 450 | "has-flag": "^3.0.0" 451 | }, 452 | "engines": { 453 | "node": ">=4" 454 | } 455 | }, 456 | "node_modules/command-line-usage/node_modules/typical": { 457 | "version": "5.2.0", 458 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 459 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", 460 | "engines": { 461 | "node": ">=8" 462 | } 463 | }, 464 | "node_modules/cssom": { 465 | "version": "0.5.0", 466 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", 467 | "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" 468 | }, 469 | "node_modules/cssstyle": { 470 | "version": "2.3.0", 471 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", 472 | "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", 473 | "dependencies": { 474 | "cssom": "~0.3.6" 475 | }, 476 | "engines": { 477 | "node": ">=8" 478 | } 479 | }, 480 | "node_modules/cssstyle/node_modules/cssom": { 481 | "version": "0.3.8", 482 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", 483 | "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" 484 | }, 485 | "node_modules/data-urls": { 486 | "version": "3.0.1", 487 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", 488 | "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==", 489 | "dependencies": { 490 | "abab": "^2.0.3", 491 | "whatwg-mimetype": "^3.0.0", 492 | "whatwg-url": "^10.0.0" 493 | }, 494 | "engines": { 495 | "node": ">=12" 496 | } 497 | }, 498 | "node_modules/debug": { 499 | "version": "4.3.4", 500 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 501 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 502 | "dependencies": { 503 | "ms": "2.1.2" 504 | }, 505 | "engines": { 506 | "node": ">=6.0" 507 | }, 508 | "peerDependenciesMeta": { 509 | "supports-color": { 510 | "optional": true 511 | } 512 | } 513 | }, 514 | "node_modules/decimal.js": { 515 | "version": "10.3.1", 516 | "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", 517 | "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" 518 | }, 519 | "node_modules/dedent-js": { 520 | "version": "1.0.1", 521 | "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", 522 | "integrity": "sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU=" 523 | }, 524 | "node_modules/deep-extend": { 525 | "version": "0.6.0", 526 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 527 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 528 | "engines": { 529 | "node": ">=4.0.0" 530 | } 531 | }, 532 | "node_modules/deep-is": { 533 | "version": "0.1.4", 534 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 535 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" 536 | }, 537 | "node_modules/delayed-stream": { 538 | "version": "1.0.0", 539 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 540 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 541 | "engines": { 542 | "node": ">=0.4.0" 543 | } 544 | }, 545 | "node_modules/domexception": { 546 | "version": "4.0.0", 547 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", 548 | "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", 549 | "dependencies": { 550 | "webidl-conversions": "^7.0.0" 551 | }, 552 | "engines": { 553 | "node": ">=12" 554 | } 555 | }, 556 | "node_modules/ecmarkdown": { 557 | "version": "7.0.0", 558 | "resolved": "https://registry.npmjs.org/ecmarkdown/-/ecmarkdown-7.0.0.tgz", 559 | "integrity": "sha512-hJxPALjSOpSMMcFjSzwzJBk8EWOu20mYlTfV7BnVTh9er0FEaT2eSx16y36YxqQfdFxPUsa0CSH4fLf0qUclKw==", 560 | "dependencies": { 561 | "escape-html": "^1.0.1" 562 | } 563 | }, 564 | "node_modules/ecmarkup": { 565 | "version": "12.0.0", 566 | "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-12.0.0.tgz", 567 | "integrity": "sha512-Nd1dr3EMP9bAQICNiBjtz4W2VjRJBnwJPQCL5dhmss1StucOY3/b+pHSCP5JN9DUe9cu02fItZOcrQrLtamxxg==", 568 | "dependencies": { 569 | "chalk": "^4.1.2", 570 | "command-line-args": "^5.2.0", 571 | "command-line-usage": "^6.1.1", 572 | "dedent-js": "^1.0.1", 573 | "ecmarkdown": "^7.0.0", 574 | "eslint-formatter-codeframe": "^7.32.1", 575 | "fast-glob": "^3.2.7", 576 | "grammarkdown": "^3.2.0", 577 | "highlight.js": "11.0.1", 578 | "html-escape": "^1.0.2", 579 | "js-yaml": "^3.13.1", 580 | "jsdom": "^19.0.0", 581 | "parse5": "^6.0.1", 582 | "prex": "^0.4.7", 583 | "promise-debounce": "^1.0.1" 584 | }, 585 | "bin": { 586 | "ecmarkup": "bin/ecmarkup.js", 587 | "emu-format": "bin/emu-format.js" 588 | }, 589 | "engines": { 590 | "node": ">= 12 || ^11.10.1 || ^10.13 || ^8.10" 591 | } 592 | }, 593 | "node_modules/escape-html": { 594 | "version": "1.0.3", 595 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 596 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 597 | }, 598 | "node_modules/escape-string-regexp": { 599 | "version": "1.0.5", 600 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 601 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 602 | "engines": { 603 | "node": ">=0.8.0" 604 | } 605 | }, 606 | "node_modules/escodegen": { 607 | "version": "2.0.0", 608 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", 609 | "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", 610 | "dependencies": { 611 | "esprima": "^4.0.1", 612 | "estraverse": "^5.2.0", 613 | "esutils": "^2.0.2", 614 | "optionator": "^0.8.1" 615 | }, 616 | "bin": { 617 | "escodegen": "bin/escodegen.js", 618 | "esgenerate": "bin/esgenerate.js" 619 | }, 620 | "engines": { 621 | "node": ">=6.0" 622 | }, 623 | "optionalDependencies": { 624 | "source-map": "~0.6.1" 625 | } 626 | }, 627 | "node_modules/eslint-formatter-codeframe": { 628 | "version": "7.32.1", 629 | "resolved": "https://registry.npmjs.org/eslint-formatter-codeframe/-/eslint-formatter-codeframe-7.32.1.tgz", 630 | "integrity": "sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==", 631 | "dependencies": { 632 | "@babel/code-frame": "7.12.11", 633 | "chalk": "^4.0.0" 634 | }, 635 | "engines": { 636 | "node": "^10.12.0 || >=12.0.0" 637 | } 638 | }, 639 | "node_modules/esprima": { 640 | "version": "4.0.1", 641 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 642 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 643 | "bin": { 644 | "esparse": "bin/esparse.js", 645 | "esvalidate": "bin/esvalidate.js" 646 | }, 647 | "engines": { 648 | "node": ">=4" 649 | } 650 | }, 651 | "node_modules/estraverse": { 652 | "version": "5.3.0", 653 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 654 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 655 | "engines": { 656 | "node": ">=4.0" 657 | } 658 | }, 659 | "node_modules/esutils": { 660 | "version": "2.0.3", 661 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 662 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 663 | "engines": { 664 | "node": ">=0.10.0" 665 | } 666 | }, 667 | "node_modules/fast-glob": { 668 | "version": "3.2.11", 669 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", 670 | "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", 671 | "dependencies": { 672 | "@nodelib/fs.stat": "^2.0.2", 673 | "@nodelib/fs.walk": "^1.2.3", 674 | "glob-parent": "^5.1.2", 675 | "merge2": "^1.3.0", 676 | "micromatch": "^4.0.4" 677 | }, 678 | "engines": { 679 | "node": ">=8.6.0" 680 | } 681 | }, 682 | "node_modules/fast-levenshtein": { 683 | "version": "2.0.6", 684 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 685 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 686 | }, 687 | "node_modules/fastq": { 688 | "version": "1.13.0", 689 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", 690 | "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", 691 | "dependencies": { 692 | "reusify": "^1.0.4" 693 | } 694 | }, 695 | "node_modules/fill-range": { 696 | "version": "7.0.1", 697 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 698 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 699 | "dependencies": { 700 | "to-regex-range": "^5.0.1" 701 | }, 702 | "engines": { 703 | "node": ">=8" 704 | } 705 | }, 706 | "node_modules/find-replace": { 707 | "version": "3.0.0", 708 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", 709 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", 710 | "dependencies": { 711 | "array-back": "^3.0.1" 712 | }, 713 | "engines": { 714 | "node": ">=4.0.0" 715 | } 716 | }, 717 | "node_modules/form-data": { 718 | "version": "4.0.0", 719 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 720 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 721 | "dependencies": { 722 | "asynckit": "^0.4.0", 723 | "combined-stream": "^1.0.8", 724 | "mime-types": "^2.1.12" 725 | }, 726 | "engines": { 727 | "node": ">= 6" 728 | } 729 | }, 730 | "node_modules/glob-parent": { 731 | "version": "5.1.2", 732 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 733 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 734 | "dependencies": { 735 | "is-glob": "^4.0.1" 736 | }, 737 | "engines": { 738 | "node": ">= 6" 739 | } 740 | }, 741 | "node_modules/grammarkdown": { 742 | "version": "3.2.0", 743 | "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.2.0.tgz", 744 | "integrity": "sha512-pEVUvG2Kxv/PwM3Dm3kFEU1/GHRkNcFWmk/zkqN/y0uoQtPaZ+5VaBacMQAaFOIL9WGYjHXtqpkT5YRvySsISQ==", 745 | "dependencies": { 746 | "@esfx/async-canceltoken": "^1.0.0-pre.13", 747 | "@esfx/cancelable": "^1.0.0-pre.13" 748 | }, 749 | "bin": { 750 | "grammarkdown": "bin/grammarkdown" 751 | } 752 | }, 753 | "node_modules/has-flag": { 754 | "version": "4.0.0", 755 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 756 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 757 | "engines": { 758 | "node": ">=8" 759 | } 760 | }, 761 | "node_modules/highlight.js": { 762 | "version": "11.0.1", 763 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.0.1.tgz", 764 | "integrity": "sha512-EqYpWyTF2s8nMfttfBA2yLKPNoZCO33pLS4MnbXQ4hECf1TKujCt1Kq7QAdrio7roL4+CqsfjqwYj4tYgq0pJQ==", 765 | "engines": { 766 | "node": ">=12.0.0" 767 | } 768 | }, 769 | "node_modules/html-encoding-sniffer": { 770 | "version": "3.0.0", 771 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", 772 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", 773 | "dependencies": { 774 | "whatwg-encoding": "^2.0.0" 775 | }, 776 | "engines": { 777 | "node": ">=12" 778 | } 779 | }, 780 | "node_modules/html-escape": { 781 | "version": "1.0.2", 782 | "resolved": "https://registry.npmjs.org/html-escape/-/html-escape-1.0.2.tgz", 783 | "integrity": "sha1-X6eHwFaAkP4zLtWzz0qk9kZCGnQ=" 784 | }, 785 | "node_modules/http-proxy-agent": { 786 | "version": "5.0.0", 787 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", 788 | "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", 789 | "dependencies": { 790 | "@tootallnate/once": "2", 791 | "agent-base": "6", 792 | "debug": "4" 793 | }, 794 | "engines": { 795 | "node": ">= 6" 796 | } 797 | }, 798 | "node_modules/https-proxy-agent": { 799 | "version": "5.0.0", 800 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 801 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 802 | "dependencies": { 803 | "agent-base": "6", 804 | "debug": "4" 805 | }, 806 | "engines": { 807 | "node": ">= 6" 808 | } 809 | }, 810 | "node_modules/iconv-lite": { 811 | "version": "0.6.3", 812 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 813 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 814 | "dependencies": { 815 | "safer-buffer": ">= 2.1.2 < 3.0.0" 816 | }, 817 | "engines": { 818 | "node": ">=0.10.0" 819 | } 820 | }, 821 | "node_modules/is-extglob": { 822 | "version": "2.1.1", 823 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 824 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 825 | "engines": { 826 | "node": ">=0.10.0" 827 | } 828 | }, 829 | "node_modules/is-glob": { 830 | "version": "4.0.3", 831 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 832 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 833 | "dependencies": { 834 | "is-extglob": "^2.1.1" 835 | }, 836 | "engines": { 837 | "node": ">=0.10.0" 838 | } 839 | }, 840 | "node_modules/is-number": { 841 | "version": "7.0.0", 842 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 843 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 844 | "engines": { 845 | "node": ">=0.12.0" 846 | } 847 | }, 848 | "node_modules/is-potential-custom-element-name": { 849 | "version": "1.0.1", 850 | "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", 851 | "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" 852 | }, 853 | "node_modules/js-tokens": { 854 | "version": "4.0.0", 855 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 856 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 857 | }, 858 | "node_modules/js-yaml": { 859 | "version": "3.14.1", 860 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 861 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 862 | "dependencies": { 863 | "argparse": "^1.0.7", 864 | "esprima": "^4.0.0" 865 | }, 866 | "bin": { 867 | "js-yaml": "bin/js-yaml.js" 868 | } 869 | }, 870 | "node_modules/jsdom": { 871 | "version": "19.0.0", 872 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", 873 | "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", 874 | "dependencies": { 875 | "abab": "^2.0.5", 876 | "acorn": "^8.5.0", 877 | "acorn-globals": "^6.0.0", 878 | "cssom": "^0.5.0", 879 | "cssstyle": "^2.3.0", 880 | "data-urls": "^3.0.1", 881 | "decimal.js": "^10.3.1", 882 | "domexception": "^4.0.0", 883 | "escodegen": "^2.0.0", 884 | "form-data": "^4.0.0", 885 | "html-encoding-sniffer": "^3.0.0", 886 | "http-proxy-agent": "^5.0.0", 887 | "https-proxy-agent": "^5.0.0", 888 | "is-potential-custom-element-name": "^1.0.1", 889 | "nwsapi": "^2.2.0", 890 | "parse5": "6.0.1", 891 | "saxes": "^5.0.1", 892 | "symbol-tree": "^3.2.4", 893 | "tough-cookie": "^4.0.0", 894 | "w3c-hr-time": "^1.0.2", 895 | "w3c-xmlserializer": "^3.0.0", 896 | "webidl-conversions": "^7.0.0", 897 | "whatwg-encoding": "^2.0.0", 898 | "whatwg-mimetype": "^3.0.0", 899 | "whatwg-url": "^10.0.0", 900 | "ws": "^8.2.3", 901 | "xml-name-validator": "^4.0.0" 902 | }, 903 | "engines": { 904 | "node": ">=12" 905 | }, 906 | "peerDependencies": { 907 | "canvas": "^2.5.0" 908 | }, 909 | "peerDependenciesMeta": { 910 | "canvas": { 911 | "optional": true 912 | } 913 | } 914 | }, 915 | "node_modules/levn": { 916 | "version": "0.3.0", 917 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 918 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 919 | "dependencies": { 920 | "prelude-ls": "~1.1.2", 921 | "type-check": "~0.3.2" 922 | }, 923 | "engines": { 924 | "node": ">= 0.8.0" 925 | } 926 | }, 927 | "node_modules/lodash.camelcase": { 928 | "version": "4.3.0", 929 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 930 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" 931 | }, 932 | "node_modules/merge2": { 933 | "version": "1.4.1", 934 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 935 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 936 | "engines": { 937 | "node": ">= 8" 938 | } 939 | }, 940 | "node_modules/micromatch": { 941 | "version": "4.0.5", 942 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 943 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 944 | "dependencies": { 945 | "braces": "^3.0.2", 946 | "picomatch": "^2.3.1" 947 | }, 948 | "engines": { 949 | "node": ">=8.6" 950 | } 951 | }, 952 | "node_modules/mime-db": { 953 | "version": "1.52.0", 954 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 955 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 956 | "engines": { 957 | "node": ">= 0.6" 958 | } 959 | }, 960 | "node_modules/mime-types": { 961 | "version": "2.1.35", 962 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 963 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 964 | "dependencies": { 965 | "mime-db": "1.52.0" 966 | }, 967 | "engines": { 968 | "node": ">= 0.6" 969 | } 970 | }, 971 | "node_modules/ms": { 972 | "version": "2.1.2", 973 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 974 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 975 | }, 976 | "node_modules/nwsapi": { 977 | "version": "2.2.0", 978 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", 979 | "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" 980 | }, 981 | "node_modules/optionator": { 982 | "version": "0.8.3", 983 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 984 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 985 | "dependencies": { 986 | "deep-is": "~0.1.3", 987 | "fast-levenshtein": "~2.0.6", 988 | "levn": "~0.3.0", 989 | "prelude-ls": "~1.1.2", 990 | "type-check": "~0.3.2", 991 | "word-wrap": "~1.2.3" 992 | }, 993 | "engines": { 994 | "node": ">= 0.8.0" 995 | } 996 | }, 997 | "node_modules/parse5": { 998 | "version": "6.0.1", 999 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", 1000 | "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" 1001 | }, 1002 | "node_modules/picomatch": { 1003 | "version": "2.3.1", 1004 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1005 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1006 | "engines": { 1007 | "node": ">=8.6" 1008 | }, 1009 | "funding": { 1010 | "url": "https://github.com/sponsors/jonschlinkert" 1011 | } 1012 | }, 1013 | "node_modules/prelude-ls": { 1014 | "version": "1.1.2", 1015 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1016 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1017 | "engines": { 1018 | "node": ">= 0.8.0" 1019 | } 1020 | }, 1021 | "node_modules/prex": { 1022 | "version": "0.4.7", 1023 | "resolved": "https://registry.npmjs.org/prex/-/prex-0.4.7.tgz", 1024 | "integrity": "sha512-ulhl3iyjmAW/GroRQJN4CG+pC6KJ+W+deNRBkEShQwe16wLP9k92+x6RmLJuLiVSGkbxhnAqHpGdJJCh3bRpUQ==", 1025 | "dependencies": { 1026 | "@esfx/cancelable": "^1.0.0-pre.13", 1027 | "@esfx/disposable": "^1.0.0-pre.13" 1028 | } 1029 | }, 1030 | "node_modules/promise-debounce": { 1031 | "version": "1.0.1", 1032 | "resolved": "https://registry.npmjs.org/promise-debounce/-/promise-debounce-1.0.1.tgz", 1033 | "integrity": "sha1-btdvj3nQFE/b0BzBVYnOV/nXHng=" 1034 | }, 1035 | "node_modules/psl": { 1036 | "version": "1.8.0", 1037 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 1038 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 1039 | }, 1040 | "node_modules/punycode": { 1041 | "version": "2.1.1", 1042 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1043 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1044 | "engines": { 1045 | "node": ">=6" 1046 | } 1047 | }, 1048 | "node_modules/queue-microtask": { 1049 | "version": "1.2.3", 1050 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1051 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1052 | "funding": [ 1053 | { 1054 | "type": "github", 1055 | "url": "https://github.com/sponsors/feross" 1056 | }, 1057 | { 1058 | "type": "patreon", 1059 | "url": "https://www.patreon.com/feross" 1060 | }, 1061 | { 1062 | "type": "consulting", 1063 | "url": "https://feross.org/support" 1064 | } 1065 | ] 1066 | }, 1067 | "node_modules/reduce-flatten": { 1068 | "version": "2.0.0", 1069 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", 1070 | "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", 1071 | "engines": { 1072 | "node": ">=6" 1073 | } 1074 | }, 1075 | "node_modules/reusify": { 1076 | "version": "1.0.4", 1077 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1078 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1079 | "engines": { 1080 | "iojs": ">=1.0.0", 1081 | "node": ">=0.10.0" 1082 | } 1083 | }, 1084 | "node_modules/run-parallel": { 1085 | "version": "1.2.0", 1086 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1087 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1088 | "funding": [ 1089 | { 1090 | "type": "github", 1091 | "url": "https://github.com/sponsors/feross" 1092 | }, 1093 | { 1094 | "type": "patreon", 1095 | "url": "https://www.patreon.com/feross" 1096 | }, 1097 | { 1098 | "type": "consulting", 1099 | "url": "https://feross.org/support" 1100 | } 1101 | ], 1102 | "dependencies": { 1103 | "queue-microtask": "^1.2.2" 1104 | } 1105 | }, 1106 | "node_modules/safer-buffer": { 1107 | "version": "2.1.2", 1108 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1109 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1110 | }, 1111 | "node_modules/saxes": { 1112 | "version": "5.0.1", 1113 | "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", 1114 | "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", 1115 | "dependencies": { 1116 | "xmlchars": "^2.2.0" 1117 | }, 1118 | "engines": { 1119 | "node": ">=10" 1120 | } 1121 | }, 1122 | "node_modules/source-map": { 1123 | "version": "0.6.1", 1124 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1125 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1126 | "optional": true, 1127 | "engines": { 1128 | "node": ">=0.10.0" 1129 | } 1130 | }, 1131 | "node_modules/sprintf-js": { 1132 | "version": "1.0.3", 1133 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1134 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 1135 | }, 1136 | "node_modules/supports-color": { 1137 | "version": "7.2.0", 1138 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1139 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1140 | "dependencies": { 1141 | "has-flag": "^4.0.0" 1142 | }, 1143 | "engines": { 1144 | "node": ">=8" 1145 | } 1146 | }, 1147 | "node_modules/symbol-tree": { 1148 | "version": "3.2.4", 1149 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", 1150 | "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" 1151 | }, 1152 | "node_modules/table-layout": { 1153 | "version": "1.0.2", 1154 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", 1155 | "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", 1156 | "dependencies": { 1157 | "array-back": "^4.0.1", 1158 | "deep-extend": "~0.6.0", 1159 | "typical": "^5.2.0", 1160 | "wordwrapjs": "^4.0.0" 1161 | }, 1162 | "engines": { 1163 | "node": ">=8.0.0" 1164 | } 1165 | }, 1166 | "node_modules/table-layout/node_modules/array-back": { 1167 | "version": "4.0.2", 1168 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", 1169 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", 1170 | "engines": { 1171 | "node": ">=8" 1172 | } 1173 | }, 1174 | "node_modules/table-layout/node_modules/typical": { 1175 | "version": "5.2.0", 1176 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 1177 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", 1178 | "engines": { 1179 | "node": ">=8" 1180 | } 1181 | }, 1182 | "node_modules/to-regex-range": { 1183 | "version": "5.0.1", 1184 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1185 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1186 | "dependencies": { 1187 | "is-number": "^7.0.0" 1188 | }, 1189 | "engines": { 1190 | "node": ">=8.0" 1191 | } 1192 | }, 1193 | "node_modules/tough-cookie": { 1194 | "version": "4.0.0", 1195 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", 1196 | "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", 1197 | "dependencies": { 1198 | "psl": "^1.1.33", 1199 | "punycode": "^2.1.1", 1200 | "universalify": "^0.1.2" 1201 | }, 1202 | "engines": { 1203 | "node": ">=6" 1204 | } 1205 | }, 1206 | "node_modules/tr46": { 1207 | "version": "3.0.0", 1208 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", 1209 | "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", 1210 | "dependencies": { 1211 | "punycode": "^2.1.1" 1212 | }, 1213 | "engines": { 1214 | "node": ">=12" 1215 | } 1216 | }, 1217 | "node_modules/tslib": { 1218 | "version": "2.3.1", 1219 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 1220 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 1221 | }, 1222 | "node_modules/type-check": { 1223 | "version": "0.3.2", 1224 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1225 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1226 | "dependencies": { 1227 | "prelude-ls": "~1.1.2" 1228 | }, 1229 | "engines": { 1230 | "node": ">= 0.8.0" 1231 | } 1232 | }, 1233 | "node_modules/typical": { 1234 | "version": "4.0.0", 1235 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", 1236 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", 1237 | "engines": { 1238 | "node": ">=8" 1239 | } 1240 | }, 1241 | "node_modules/universalify": { 1242 | "version": "0.1.2", 1243 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1244 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1245 | "engines": { 1246 | "node": ">= 4.0.0" 1247 | } 1248 | }, 1249 | "node_modules/w3c-hr-time": { 1250 | "version": "1.0.2", 1251 | "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", 1252 | "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", 1253 | "dependencies": { 1254 | "browser-process-hrtime": "^1.0.0" 1255 | } 1256 | }, 1257 | "node_modules/w3c-xmlserializer": { 1258 | "version": "3.0.0", 1259 | "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", 1260 | "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", 1261 | "dependencies": { 1262 | "xml-name-validator": "^4.0.0" 1263 | }, 1264 | "engines": { 1265 | "node": ">=12" 1266 | } 1267 | }, 1268 | "node_modules/webidl-conversions": { 1269 | "version": "7.0.0", 1270 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 1271 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 1272 | "engines": { 1273 | "node": ">=12" 1274 | } 1275 | }, 1276 | "node_modules/whatwg-encoding": { 1277 | "version": "2.0.0", 1278 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", 1279 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", 1280 | "dependencies": { 1281 | "iconv-lite": "0.6.3" 1282 | }, 1283 | "engines": { 1284 | "node": ">=12" 1285 | } 1286 | }, 1287 | "node_modules/whatwg-mimetype": { 1288 | "version": "3.0.0", 1289 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", 1290 | "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", 1291 | "engines": { 1292 | "node": ">=12" 1293 | } 1294 | }, 1295 | "node_modules/whatwg-url": { 1296 | "version": "10.0.0", 1297 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", 1298 | "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", 1299 | "dependencies": { 1300 | "tr46": "^3.0.0", 1301 | "webidl-conversions": "^7.0.0" 1302 | }, 1303 | "engines": { 1304 | "node": ">=12" 1305 | } 1306 | }, 1307 | "node_modules/word-wrap": { 1308 | "version": "1.2.3", 1309 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1310 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1311 | "engines": { 1312 | "node": ">=0.10.0" 1313 | } 1314 | }, 1315 | "node_modules/wordwrapjs": { 1316 | "version": "4.0.1", 1317 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", 1318 | "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", 1319 | "dependencies": { 1320 | "reduce-flatten": "^2.0.0", 1321 | "typical": "^5.2.0" 1322 | }, 1323 | "engines": { 1324 | "node": ">=8.0.0" 1325 | } 1326 | }, 1327 | "node_modules/wordwrapjs/node_modules/typical": { 1328 | "version": "5.2.0", 1329 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 1330 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", 1331 | "engines": { 1332 | "node": ">=8" 1333 | } 1334 | }, 1335 | "node_modules/ws": { 1336 | "version": "8.5.0", 1337 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", 1338 | "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", 1339 | "engines": { 1340 | "node": ">=10.0.0" 1341 | }, 1342 | "peerDependencies": { 1343 | "bufferutil": "^4.0.1", 1344 | "utf-8-validate": "^5.0.2" 1345 | }, 1346 | "peerDependenciesMeta": { 1347 | "bufferutil": { 1348 | "optional": true 1349 | }, 1350 | "utf-8-validate": { 1351 | "optional": true 1352 | } 1353 | } 1354 | }, 1355 | "node_modules/xml-name-validator": { 1356 | "version": "4.0.0", 1357 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", 1358 | "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", 1359 | "engines": { 1360 | "node": ">=12" 1361 | } 1362 | }, 1363 | "node_modules/xmlchars": { 1364 | "version": "2.2.0", 1365 | "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", 1366 | "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" 1367 | } 1368 | }, 1369 | "dependencies": { 1370 | "@babel/code-frame": { 1371 | "version": "7.12.11", 1372 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", 1373 | "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", 1374 | "requires": { 1375 | "@babel/highlight": "^7.10.4" 1376 | } 1377 | }, 1378 | "@babel/helper-validator-identifier": { 1379 | "version": "7.16.7", 1380 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", 1381 | "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" 1382 | }, 1383 | "@babel/highlight": { 1384 | "version": "7.16.10", 1385 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", 1386 | "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", 1387 | "requires": { 1388 | "@babel/helper-validator-identifier": "^7.16.7", 1389 | "chalk": "^2.0.0", 1390 | "js-tokens": "^4.0.0" 1391 | }, 1392 | "dependencies": { 1393 | "ansi-styles": { 1394 | "version": "3.2.1", 1395 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1396 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1397 | "requires": { 1398 | "color-convert": "^1.9.0" 1399 | } 1400 | }, 1401 | "chalk": { 1402 | "version": "2.4.2", 1403 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1404 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1405 | "requires": { 1406 | "ansi-styles": "^3.2.1", 1407 | "escape-string-regexp": "^1.0.5", 1408 | "supports-color": "^5.3.0" 1409 | } 1410 | }, 1411 | "color-convert": { 1412 | "version": "1.9.3", 1413 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1414 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1415 | "requires": { 1416 | "color-name": "1.1.3" 1417 | } 1418 | }, 1419 | "color-name": { 1420 | "version": "1.1.3", 1421 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1422 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 1423 | }, 1424 | "has-flag": { 1425 | "version": "3.0.0", 1426 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1427 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 1428 | }, 1429 | "supports-color": { 1430 | "version": "5.5.0", 1431 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1432 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1433 | "requires": { 1434 | "has-flag": "^3.0.0" 1435 | } 1436 | } 1437 | } 1438 | }, 1439 | "@esfx/async-canceltoken": { 1440 | "version": "1.0.0-pre.30", 1441 | "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0-pre.30.tgz", 1442 | "integrity": "sha512-4he0W+ZKH4OO4RvGfmATIibO5JzGLQqwm4Dp3X15bWnguDTmmOFt3Qt169Doij/gXxn2aPpZvxUaYIEebi8Xig==", 1443 | "requires": { 1444 | "@esfx/cancelable": "^1.0.0-pre.30", 1445 | "@esfx/collections-linkedlist": "^1.0.0-pre.24", 1446 | "@esfx/disposable": "^1.0.0-pre.30", 1447 | "@esfx/internal-guards": "^1.0.0-pre.23", 1448 | "@esfx/internal-tag": "^1.0.0-pre.19", 1449 | "tslib": "^2.1.0" 1450 | } 1451 | }, 1452 | "@esfx/cancelable": { 1453 | "version": "1.0.0-pre.30", 1454 | "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", 1455 | "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", 1456 | "requires": { 1457 | "@esfx/disposable": "^1.0.0-pre.30", 1458 | "@esfx/internal-deprecate": "^1.0.0-pre.24", 1459 | "@esfx/internal-guards": "^1.0.0-pre.23", 1460 | "@esfx/internal-tag": "^1.0.0-pre.19" 1461 | } 1462 | }, 1463 | "@esfx/collection-core": { 1464 | "version": "1.0.0-pre.24", 1465 | "resolved": "https://registry.npmjs.org/@esfx/collection-core/-/collection-core-1.0.0-pre.24.tgz", 1466 | "integrity": "sha512-OIgMS91JmjSoRWD7u/DfnDzo8vDggeTeUPRi1p5WhyboY0+IwmetEqgeHZb8bpka/SsmtYX5qxqEjeqNXqh+pA==", 1467 | "requires": { 1468 | "@esfx/internal-deprecate": "^1.0.0-pre.24", 1469 | "@esfx/internal-guards": "^1.0.0-pre.23" 1470 | } 1471 | }, 1472 | "@esfx/collections-linkedlist": { 1473 | "version": "1.0.0-pre.24", 1474 | "resolved": "https://registry.npmjs.org/@esfx/collections-linkedlist/-/collections-linkedlist-1.0.0-pre.24.tgz", 1475 | "integrity": "sha512-Maya8jXH0xvzyfeSH88/j2b5gavO/mluslgIC2Ttdz8rh6+3o8/pVYriceH/Jinn4pgTEzDhO6Rn/aruZG0+Ug==", 1476 | "requires": { 1477 | "@esfx/collection-core": "^1.0.0-pre.24", 1478 | "@esfx/equatable": "^1.0.0-pre.19", 1479 | "@esfx/internal-guards": "^1.0.0-pre.23" 1480 | } 1481 | }, 1482 | "@esfx/disposable": { 1483 | "version": "1.0.0-pre.30", 1484 | "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", 1485 | "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==" 1486 | }, 1487 | "@esfx/equatable": { 1488 | "version": "1.0.0-pre.19", 1489 | "resolved": "https://registry.npmjs.org/@esfx/equatable/-/equatable-1.0.0-pre.19.tgz", 1490 | "integrity": "sha512-+f6Xm6GOigyGx7t0D0IyG9Z0AuYDhNWjwV49vs5uNG/+0VQAOSYjmnpSzTZRYcYwxW52DmWJWFYNY8bvCDD2ag==" 1491 | }, 1492 | "@esfx/internal-deprecate": { 1493 | "version": "1.0.0-pre.24", 1494 | "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", 1495 | "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==" 1496 | }, 1497 | "@esfx/internal-guards": { 1498 | "version": "1.0.0-pre.23", 1499 | "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", 1500 | "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", 1501 | "requires": { 1502 | "@esfx/type-model": "^1.0.0-pre.23" 1503 | } 1504 | }, 1505 | "@esfx/internal-tag": { 1506 | "version": "1.0.0-pre.19", 1507 | "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", 1508 | "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==" 1509 | }, 1510 | "@esfx/type-model": { 1511 | "version": "1.0.0-pre.23", 1512 | "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", 1513 | "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==" 1514 | }, 1515 | "@nodelib/fs.scandir": { 1516 | "version": "2.1.5", 1517 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 1518 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 1519 | "requires": { 1520 | "@nodelib/fs.stat": "2.0.5", 1521 | "run-parallel": "^1.1.9" 1522 | } 1523 | }, 1524 | "@nodelib/fs.stat": { 1525 | "version": "2.0.5", 1526 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1527 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" 1528 | }, 1529 | "@nodelib/fs.walk": { 1530 | "version": "1.2.8", 1531 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1532 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1533 | "requires": { 1534 | "@nodelib/fs.scandir": "2.1.5", 1535 | "fastq": "^1.6.0" 1536 | } 1537 | }, 1538 | "@tootallnate/once": { 1539 | "version": "2.0.0", 1540 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", 1541 | "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" 1542 | }, 1543 | "abab": { 1544 | "version": "2.0.5", 1545 | "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", 1546 | "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" 1547 | }, 1548 | "acorn": { 1549 | "version": "8.7.0", 1550 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", 1551 | "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" 1552 | }, 1553 | "acorn-globals": { 1554 | "version": "6.0.0", 1555 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", 1556 | "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", 1557 | "requires": { 1558 | "acorn": "^7.1.1", 1559 | "acorn-walk": "^7.1.1" 1560 | }, 1561 | "dependencies": { 1562 | "acorn": { 1563 | "version": "7.4.1", 1564 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 1565 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" 1566 | } 1567 | } 1568 | }, 1569 | "acorn-walk": { 1570 | "version": "7.2.0", 1571 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", 1572 | "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" 1573 | }, 1574 | "agent-base": { 1575 | "version": "6.0.2", 1576 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 1577 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 1578 | "requires": { 1579 | "debug": "4" 1580 | } 1581 | }, 1582 | "ansi-styles": { 1583 | "version": "4.3.0", 1584 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1585 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1586 | "requires": { 1587 | "color-convert": "^2.0.1" 1588 | } 1589 | }, 1590 | "argparse": { 1591 | "version": "1.0.10", 1592 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 1593 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 1594 | "requires": { 1595 | "sprintf-js": "~1.0.2" 1596 | } 1597 | }, 1598 | "array-back": { 1599 | "version": "3.1.0", 1600 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", 1601 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" 1602 | }, 1603 | "asynckit": { 1604 | "version": "0.4.0", 1605 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 1606 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 1607 | }, 1608 | "braces": { 1609 | "version": "3.0.2", 1610 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1611 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1612 | "requires": { 1613 | "fill-range": "^7.0.1" 1614 | } 1615 | }, 1616 | "browser-process-hrtime": { 1617 | "version": "1.0.0", 1618 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", 1619 | "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" 1620 | }, 1621 | "chalk": { 1622 | "version": "4.1.2", 1623 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1624 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1625 | "requires": { 1626 | "ansi-styles": "^4.1.0", 1627 | "supports-color": "^7.1.0" 1628 | } 1629 | }, 1630 | "color-convert": { 1631 | "version": "2.0.1", 1632 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1633 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1634 | "requires": { 1635 | "color-name": "~1.1.4" 1636 | } 1637 | }, 1638 | "color-name": { 1639 | "version": "1.1.4", 1640 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1641 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 1642 | }, 1643 | "combined-stream": { 1644 | "version": "1.0.8", 1645 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 1646 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 1647 | "requires": { 1648 | "delayed-stream": "~1.0.0" 1649 | } 1650 | }, 1651 | "command-line-args": { 1652 | "version": "5.2.1", 1653 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", 1654 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", 1655 | "requires": { 1656 | "array-back": "^3.1.0", 1657 | "find-replace": "^3.0.0", 1658 | "lodash.camelcase": "^4.3.0", 1659 | "typical": "^4.0.0" 1660 | } 1661 | }, 1662 | "command-line-usage": { 1663 | "version": "6.1.1", 1664 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz", 1665 | "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==", 1666 | "requires": { 1667 | "array-back": "^4.0.1", 1668 | "chalk": "^2.4.2", 1669 | "table-layout": "^1.0.1", 1670 | "typical": "^5.2.0" 1671 | }, 1672 | "dependencies": { 1673 | "ansi-styles": { 1674 | "version": "3.2.1", 1675 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1676 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1677 | "requires": { 1678 | "color-convert": "^1.9.0" 1679 | } 1680 | }, 1681 | "array-back": { 1682 | "version": "4.0.2", 1683 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", 1684 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==" 1685 | }, 1686 | "chalk": { 1687 | "version": "2.4.2", 1688 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1689 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1690 | "requires": { 1691 | "ansi-styles": "^3.2.1", 1692 | "escape-string-regexp": "^1.0.5", 1693 | "supports-color": "^5.3.0" 1694 | } 1695 | }, 1696 | "color-convert": { 1697 | "version": "1.9.3", 1698 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1699 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1700 | "requires": { 1701 | "color-name": "1.1.3" 1702 | } 1703 | }, 1704 | "color-name": { 1705 | "version": "1.1.3", 1706 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1707 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 1708 | }, 1709 | "has-flag": { 1710 | "version": "3.0.0", 1711 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1712 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 1713 | }, 1714 | "supports-color": { 1715 | "version": "5.5.0", 1716 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1717 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1718 | "requires": { 1719 | "has-flag": "^3.0.0" 1720 | } 1721 | }, 1722 | "typical": { 1723 | "version": "5.2.0", 1724 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 1725 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" 1726 | } 1727 | } 1728 | }, 1729 | "cssom": { 1730 | "version": "0.5.0", 1731 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", 1732 | "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" 1733 | }, 1734 | "cssstyle": { 1735 | "version": "2.3.0", 1736 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", 1737 | "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", 1738 | "requires": { 1739 | "cssom": "~0.3.6" 1740 | }, 1741 | "dependencies": { 1742 | "cssom": { 1743 | "version": "0.3.8", 1744 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", 1745 | "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" 1746 | } 1747 | } 1748 | }, 1749 | "data-urls": { 1750 | "version": "3.0.1", 1751 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", 1752 | "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==", 1753 | "requires": { 1754 | "abab": "^2.0.3", 1755 | "whatwg-mimetype": "^3.0.0", 1756 | "whatwg-url": "^10.0.0" 1757 | } 1758 | }, 1759 | "debug": { 1760 | "version": "4.3.4", 1761 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1762 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1763 | "requires": { 1764 | "ms": "2.1.2" 1765 | } 1766 | }, 1767 | "decimal.js": { 1768 | "version": "10.3.1", 1769 | "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", 1770 | "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" 1771 | }, 1772 | "dedent-js": { 1773 | "version": "1.0.1", 1774 | "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", 1775 | "integrity": "sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU=" 1776 | }, 1777 | "deep-extend": { 1778 | "version": "0.6.0", 1779 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 1780 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 1781 | }, 1782 | "deep-is": { 1783 | "version": "0.1.4", 1784 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1785 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" 1786 | }, 1787 | "delayed-stream": { 1788 | "version": "1.0.0", 1789 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 1790 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 1791 | }, 1792 | "domexception": { 1793 | "version": "4.0.0", 1794 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", 1795 | "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", 1796 | "requires": { 1797 | "webidl-conversions": "^7.0.0" 1798 | } 1799 | }, 1800 | "ecmarkdown": { 1801 | "version": "7.0.0", 1802 | "resolved": "https://registry.npmjs.org/ecmarkdown/-/ecmarkdown-7.0.0.tgz", 1803 | "integrity": "sha512-hJxPALjSOpSMMcFjSzwzJBk8EWOu20mYlTfV7BnVTh9er0FEaT2eSx16y36YxqQfdFxPUsa0CSH4fLf0qUclKw==", 1804 | "requires": { 1805 | "escape-html": "^1.0.1" 1806 | } 1807 | }, 1808 | "ecmarkup": { 1809 | "version": "12.0.0", 1810 | "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-12.0.0.tgz", 1811 | "integrity": "sha512-Nd1dr3EMP9bAQICNiBjtz4W2VjRJBnwJPQCL5dhmss1StucOY3/b+pHSCP5JN9DUe9cu02fItZOcrQrLtamxxg==", 1812 | "requires": { 1813 | "chalk": "^4.1.2", 1814 | "command-line-args": "^5.2.0", 1815 | "command-line-usage": "^6.1.1", 1816 | "dedent-js": "^1.0.1", 1817 | "ecmarkdown": "^7.0.0", 1818 | "eslint-formatter-codeframe": "^7.32.1", 1819 | "fast-glob": "^3.2.7", 1820 | "grammarkdown": "^3.2.0", 1821 | "highlight.js": "11.0.1", 1822 | "html-escape": "^1.0.2", 1823 | "js-yaml": "^3.13.1", 1824 | "jsdom": "^19.0.0", 1825 | "parse5": "^6.0.1", 1826 | "prex": "^0.4.7", 1827 | "promise-debounce": "^1.0.1" 1828 | } 1829 | }, 1830 | "escape-html": { 1831 | "version": "1.0.3", 1832 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1833 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 1834 | }, 1835 | "escape-string-regexp": { 1836 | "version": "1.0.5", 1837 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1838 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 1839 | }, 1840 | "escodegen": { 1841 | "version": "2.0.0", 1842 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", 1843 | "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", 1844 | "requires": { 1845 | "esprima": "^4.0.1", 1846 | "estraverse": "^5.2.0", 1847 | "esutils": "^2.0.2", 1848 | "optionator": "^0.8.1", 1849 | "source-map": "~0.6.1" 1850 | } 1851 | }, 1852 | "eslint-formatter-codeframe": { 1853 | "version": "7.32.1", 1854 | "resolved": "https://registry.npmjs.org/eslint-formatter-codeframe/-/eslint-formatter-codeframe-7.32.1.tgz", 1855 | "integrity": "sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==", 1856 | "requires": { 1857 | "@babel/code-frame": "7.12.11", 1858 | "chalk": "^4.0.0" 1859 | } 1860 | }, 1861 | "esprima": { 1862 | "version": "4.0.1", 1863 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1864 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 1865 | }, 1866 | "estraverse": { 1867 | "version": "5.3.0", 1868 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1869 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" 1870 | }, 1871 | "esutils": { 1872 | "version": "2.0.3", 1873 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1874 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" 1875 | }, 1876 | "fast-glob": { 1877 | "version": "3.2.11", 1878 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", 1879 | "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", 1880 | "requires": { 1881 | "@nodelib/fs.stat": "^2.0.2", 1882 | "@nodelib/fs.walk": "^1.2.3", 1883 | "glob-parent": "^5.1.2", 1884 | "merge2": "^1.3.0", 1885 | "micromatch": "^4.0.4" 1886 | } 1887 | }, 1888 | "fast-levenshtein": { 1889 | "version": "2.0.6", 1890 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1891 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 1892 | }, 1893 | "fastq": { 1894 | "version": "1.13.0", 1895 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", 1896 | "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", 1897 | "requires": { 1898 | "reusify": "^1.0.4" 1899 | } 1900 | }, 1901 | "fill-range": { 1902 | "version": "7.0.1", 1903 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1904 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1905 | "requires": { 1906 | "to-regex-range": "^5.0.1" 1907 | } 1908 | }, 1909 | "find-replace": { 1910 | "version": "3.0.0", 1911 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", 1912 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", 1913 | "requires": { 1914 | "array-back": "^3.0.1" 1915 | } 1916 | }, 1917 | "form-data": { 1918 | "version": "4.0.0", 1919 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 1920 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 1921 | "requires": { 1922 | "asynckit": "^0.4.0", 1923 | "combined-stream": "^1.0.8", 1924 | "mime-types": "^2.1.12" 1925 | } 1926 | }, 1927 | "glob-parent": { 1928 | "version": "5.1.2", 1929 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1930 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1931 | "requires": { 1932 | "is-glob": "^4.0.1" 1933 | } 1934 | }, 1935 | "grammarkdown": { 1936 | "version": "3.2.0", 1937 | "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.2.0.tgz", 1938 | "integrity": "sha512-pEVUvG2Kxv/PwM3Dm3kFEU1/GHRkNcFWmk/zkqN/y0uoQtPaZ+5VaBacMQAaFOIL9WGYjHXtqpkT5YRvySsISQ==", 1939 | "requires": { 1940 | "@esfx/async-canceltoken": "^1.0.0-pre.13", 1941 | "@esfx/cancelable": "^1.0.0-pre.13" 1942 | } 1943 | }, 1944 | "has-flag": { 1945 | "version": "4.0.0", 1946 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1947 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 1948 | }, 1949 | "highlight.js": { 1950 | "version": "11.0.1", 1951 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.0.1.tgz", 1952 | "integrity": "sha512-EqYpWyTF2s8nMfttfBA2yLKPNoZCO33pLS4MnbXQ4hECf1TKujCt1Kq7QAdrio7roL4+CqsfjqwYj4tYgq0pJQ==" 1953 | }, 1954 | "html-encoding-sniffer": { 1955 | "version": "3.0.0", 1956 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", 1957 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", 1958 | "requires": { 1959 | "whatwg-encoding": "^2.0.0" 1960 | } 1961 | }, 1962 | "html-escape": { 1963 | "version": "1.0.2", 1964 | "resolved": "https://registry.npmjs.org/html-escape/-/html-escape-1.0.2.tgz", 1965 | "integrity": "sha1-X6eHwFaAkP4zLtWzz0qk9kZCGnQ=" 1966 | }, 1967 | "http-proxy-agent": { 1968 | "version": "5.0.0", 1969 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", 1970 | "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", 1971 | "requires": { 1972 | "@tootallnate/once": "2", 1973 | "agent-base": "6", 1974 | "debug": "4" 1975 | } 1976 | }, 1977 | "https-proxy-agent": { 1978 | "version": "5.0.0", 1979 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 1980 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 1981 | "requires": { 1982 | "agent-base": "6", 1983 | "debug": "4" 1984 | } 1985 | }, 1986 | "iconv-lite": { 1987 | "version": "0.6.3", 1988 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1989 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1990 | "requires": { 1991 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1992 | } 1993 | }, 1994 | "is-extglob": { 1995 | "version": "2.1.1", 1996 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1997 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" 1998 | }, 1999 | "is-glob": { 2000 | "version": "4.0.3", 2001 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2002 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2003 | "requires": { 2004 | "is-extglob": "^2.1.1" 2005 | } 2006 | }, 2007 | "is-number": { 2008 | "version": "7.0.0", 2009 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2010 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" 2011 | }, 2012 | "is-potential-custom-element-name": { 2013 | "version": "1.0.1", 2014 | "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", 2015 | "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" 2016 | }, 2017 | "js-tokens": { 2018 | "version": "4.0.0", 2019 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 2020 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 2021 | }, 2022 | "js-yaml": { 2023 | "version": "3.14.1", 2024 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 2025 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 2026 | "requires": { 2027 | "argparse": "^1.0.7", 2028 | "esprima": "^4.0.0" 2029 | } 2030 | }, 2031 | "jsdom": { 2032 | "version": "19.0.0", 2033 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", 2034 | "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", 2035 | "requires": { 2036 | "abab": "^2.0.5", 2037 | "acorn": "^8.5.0", 2038 | "acorn-globals": "^6.0.0", 2039 | "cssom": "^0.5.0", 2040 | "cssstyle": "^2.3.0", 2041 | "data-urls": "^3.0.1", 2042 | "decimal.js": "^10.3.1", 2043 | "domexception": "^4.0.0", 2044 | "escodegen": "^2.0.0", 2045 | "form-data": "^4.0.0", 2046 | "html-encoding-sniffer": "^3.0.0", 2047 | "http-proxy-agent": "^5.0.0", 2048 | "https-proxy-agent": "^5.0.0", 2049 | "is-potential-custom-element-name": "^1.0.1", 2050 | "nwsapi": "^2.2.0", 2051 | "parse5": "6.0.1", 2052 | "saxes": "^5.0.1", 2053 | "symbol-tree": "^3.2.4", 2054 | "tough-cookie": "^4.0.0", 2055 | "w3c-hr-time": "^1.0.2", 2056 | "w3c-xmlserializer": "^3.0.0", 2057 | "webidl-conversions": "^7.0.0", 2058 | "whatwg-encoding": "^2.0.0", 2059 | "whatwg-mimetype": "^3.0.0", 2060 | "whatwg-url": "^10.0.0", 2061 | "ws": "^8.2.3", 2062 | "xml-name-validator": "^4.0.0" 2063 | } 2064 | }, 2065 | "levn": { 2066 | "version": "0.3.0", 2067 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 2068 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 2069 | "requires": { 2070 | "prelude-ls": "~1.1.2", 2071 | "type-check": "~0.3.2" 2072 | } 2073 | }, 2074 | "lodash.camelcase": { 2075 | "version": "4.3.0", 2076 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 2077 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" 2078 | }, 2079 | "merge2": { 2080 | "version": "1.4.1", 2081 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 2082 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" 2083 | }, 2084 | "micromatch": { 2085 | "version": "4.0.5", 2086 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 2087 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 2088 | "requires": { 2089 | "braces": "^3.0.2", 2090 | "picomatch": "^2.3.1" 2091 | } 2092 | }, 2093 | "mime-db": { 2094 | "version": "1.52.0", 2095 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 2096 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 2097 | }, 2098 | "mime-types": { 2099 | "version": "2.1.35", 2100 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 2101 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 2102 | "requires": { 2103 | "mime-db": "1.52.0" 2104 | } 2105 | }, 2106 | "ms": { 2107 | "version": "2.1.2", 2108 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2109 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2110 | }, 2111 | "nwsapi": { 2112 | "version": "2.2.0", 2113 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", 2114 | "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" 2115 | }, 2116 | "optionator": { 2117 | "version": "0.8.3", 2118 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 2119 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 2120 | "requires": { 2121 | "deep-is": "~0.1.3", 2122 | "fast-levenshtein": "~2.0.6", 2123 | "levn": "~0.3.0", 2124 | "prelude-ls": "~1.1.2", 2125 | "type-check": "~0.3.2", 2126 | "word-wrap": "~1.2.3" 2127 | } 2128 | }, 2129 | "parse5": { 2130 | "version": "6.0.1", 2131 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", 2132 | "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" 2133 | }, 2134 | "picomatch": { 2135 | "version": "2.3.1", 2136 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2137 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" 2138 | }, 2139 | "prelude-ls": { 2140 | "version": "1.1.2", 2141 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 2142 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 2143 | }, 2144 | "prex": { 2145 | "version": "0.4.7", 2146 | "resolved": "https://registry.npmjs.org/prex/-/prex-0.4.7.tgz", 2147 | "integrity": "sha512-ulhl3iyjmAW/GroRQJN4CG+pC6KJ+W+deNRBkEShQwe16wLP9k92+x6RmLJuLiVSGkbxhnAqHpGdJJCh3bRpUQ==", 2148 | "requires": { 2149 | "@esfx/cancelable": "^1.0.0-pre.13", 2150 | "@esfx/disposable": "^1.0.0-pre.13" 2151 | } 2152 | }, 2153 | "promise-debounce": { 2154 | "version": "1.0.1", 2155 | "resolved": "https://registry.npmjs.org/promise-debounce/-/promise-debounce-1.0.1.tgz", 2156 | "integrity": "sha1-btdvj3nQFE/b0BzBVYnOV/nXHng=" 2157 | }, 2158 | "psl": { 2159 | "version": "1.8.0", 2160 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 2161 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 2162 | }, 2163 | "punycode": { 2164 | "version": "2.1.1", 2165 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2166 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 2167 | }, 2168 | "queue-microtask": { 2169 | "version": "1.2.3", 2170 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 2171 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" 2172 | }, 2173 | "reduce-flatten": { 2174 | "version": "2.0.0", 2175 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", 2176 | "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==" 2177 | }, 2178 | "reusify": { 2179 | "version": "1.0.4", 2180 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 2181 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" 2182 | }, 2183 | "run-parallel": { 2184 | "version": "1.2.0", 2185 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 2186 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 2187 | "requires": { 2188 | "queue-microtask": "^1.2.2" 2189 | } 2190 | }, 2191 | "safer-buffer": { 2192 | "version": "2.1.2", 2193 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2194 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2195 | }, 2196 | "saxes": { 2197 | "version": "5.0.1", 2198 | "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", 2199 | "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", 2200 | "requires": { 2201 | "xmlchars": "^2.2.0" 2202 | } 2203 | }, 2204 | "source-map": { 2205 | "version": "0.6.1", 2206 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2207 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2208 | "optional": true 2209 | }, 2210 | "sprintf-js": { 2211 | "version": "1.0.3", 2212 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2213 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 2214 | }, 2215 | "supports-color": { 2216 | "version": "7.2.0", 2217 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2218 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2219 | "requires": { 2220 | "has-flag": "^4.0.0" 2221 | } 2222 | }, 2223 | "symbol-tree": { 2224 | "version": "3.2.4", 2225 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", 2226 | "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" 2227 | }, 2228 | "table-layout": { 2229 | "version": "1.0.2", 2230 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", 2231 | "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", 2232 | "requires": { 2233 | "array-back": "^4.0.1", 2234 | "deep-extend": "~0.6.0", 2235 | "typical": "^5.2.0", 2236 | "wordwrapjs": "^4.0.0" 2237 | }, 2238 | "dependencies": { 2239 | "array-back": { 2240 | "version": "4.0.2", 2241 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", 2242 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==" 2243 | }, 2244 | "typical": { 2245 | "version": "5.2.0", 2246 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 2247 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" 2248 | } 2249 | } 2250 | }, 2251 | "to-regex-range": { 2252 | "version": "5.0.1", 2253 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2254 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2255 | "requires": { 2256 | "is-number": "^7.0.0" 2257 | } 2258 | }, 2259 | "tough-cookie": { 2260 | "version": "4.0.0", 2261 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", 2262 | "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", 2263 | "requires": { 2264 | "psl": "^1.1.33", 2265 | "punycode": "^2.1.1", 2266 | "universalify": "^0.1.2" 2267 | } 2268 | }, 2269 | "tr46": { 2270 | "version": "3.0.0", 2271 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", 2272 | "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", 2273 | "requires": { 2274 | "punycode": "^2.1.1" 2275 | } 2276 | }, 2277 | "tslib": { 2278 | "version": "2.3.1", 2279 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 2280 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 2281 | }, 2282 | "type-check": { 2283 | "version": "0.3.2", 2284 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2285 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2286 | "requires": { 2287 | "prelude-ls": "~1.1.2" 2288 | } 2289 | }, 2290 | "typical": { 2291 | "version": "4.0.0", 2292 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", 2293 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" 2294 | }, 2295 | "universalify": { 2296 | "version": "0.1.2", 2297 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2298 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 2299 | }, 2300 | "w3c-hr-time": { 2301 | "version": "1.0.2", 2302 | "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", 2303 | "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", 2304 | "requires": { 2305 | "browser-process-hrtime": "^1.0.0" 2306 | } 2307 | }, 2308 | "w3c-xmlserializer": { 2309 | "version": "3.0.0", 2310 | "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", 2311 | "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", 2312 | "requires": { 2313 | "xml-name-validator": "^4.0.0" 2314 | } 2315 | }, 2316 | "webidl-conversions": { 2317 | "version": "7.0.0", 2318 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 2319 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" 2320 | }, 2321 | "whatwg-encoding": { 2322 | "version": "2.0.0", 2323 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", 2324 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", 2325 | "requires": { 2326 | "iconv-lite": "0.6.3" 2327 | } 2328 | }, 2329 | "whatwg-mimetype": { 2330 | "version": "3.0.0", 2331 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", 2332 | "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" 2333 | }, 2334 | "whatwg-url": { 2335 | "version": "10.0.0", 2336 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", 2337 | "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", 2338 | "requires": { 2339 | "tr46": "^3.0.0", 2340 | "webidl-conversions": "^7.0.0" 2341 | } 2342 | }, 2343 | "word-wrap": { 2344 | "version": "1.2.3", 2345 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2346 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" 2347 | }, 2348 | "wordwrapjs": { 2349 | "version": "4.0.1", 2350 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", 2351 | "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", 2352 | "requires": { 2353 | "reduce-flatten": "^2.0.0", 2354 | "typical": "^5.2.0" 2355 | }, 2356 | "dependencies": { 2357 | "typical": { 2358 | "version": "5.2.0", 2359 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", 2360 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" 2361 | } 2362 | } 2363 | }, 2364 | "ws": { 2365 | "version": "8.5.0", 2366 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", 2367 | "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", 2368 | "requires": {} 2369 | }, 2370 | "xml-name-validator": { 2371 | "version": "4.0.0", 2372 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", 2373 | "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" 2374 | }, 2375 | "xmlchars": { 2376 | "version": "2.2.0", 2377 | "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", 2378 | "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" 2379 | } 2380 | } 2381 | } 2382 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "proposal-pipeline-operator", 4 | "version": "1.0.0", 5 | "description": "ECMAScript pipe-operator proposal", 6 | "repository": "tc39/proposal-pipeline-operator", 7 | "author": "Ecma TC39", 8 | "license": "BSD-3-Clause", 9 | "homepage": "https://tc39.github.io/proposal-pipeline-operator/", 10 | "dependencies": { 11 | "ecmarkup": "^12.0.0" 12 | }, 13 | "scripts": { 14 | "prebuild": "mkdir -p dist", 15 | "build": "ecmarkup --verbose spec.html dist/index.html", 16 | "watch": "npm run build -- --watch" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spec.html: -------------------------------------------------------------------------------- 1 |
      2 | title: ES pipe operator (2021)
      3 | status: proposal
      4 | stage: 2
      5 | location: https://github.com/tc39/proposal-pipeline-operator
      6 | copyright: false
      7 | contributors: J. S. Choi, James DiGioia, Ron Buckton, Tab Atkins-Bittner
      8 | 
    9 | 10 | 11 | 12 | 13 |

    Introduction

    14 |

    This is the formal specification for a proposed Hack-style pipe 15 | operator `|>` in JavaScript. It modifies the original ECMAScript specification with 17 | several new or revised clauses. See the proposal's 19 | explainer for the proposal's background, motivation, and usage examples.

    20 | 21 |

    This document presumptively uses `%` as the token 22 | for the topic reference. This choice of token is not a final decision; 23 | `%` could instead be `^` or some other token.

    24 |
    25 | 26 | 27 |

    Syntax-Directed Operations

    28 | 29 | 30 |

    Function Name Inference

    31 | 32 | 34 |

    Static Semantics: IsFunctionDefinition

    35 | 36 | 37 |

    This section augments the original 39 | IsFunctionDefinition clause.

    40 | 41 |

    It presumptively uses `%` as the placeholder token for the 42 | topic reference. This choice of token is not a final decision; `%` 43 | could instead be `^` or some other token.

    44 |
    45 | 46 | 47 | PrimaryExpression : 48 | `this` 49 | `%` 50 | IdentifierReference 51 | Literal 52 | ArrayLiteral 53 | ObjectLiteral 54 | RegularExpressionLiteral 55 | TemplateLiteral 56 | 57 | PipeExpression : 58 | ShortCircuitExpression `|>` PipeBody 59 | 60 | 61 | 1. Return *false*. 62 | 63 |
    64 | 65 | 67 |

    Static Semantics: IsIdentifierRef

    68 | 69 | 70 |

    This section augments the original IsIdentifierRef 72 | clause.

    73 | 74 |

    It presumptively uses `%` as the placeholder token for the 75 | topic reference. This choice of token is not a final decision; `%` 76 | could instead be `^` or some other token.

    77 |
    78 | 79 | PrimaryExpression : IdentifierReference 80 | 81 | 1. Return *true*. 82 | 83 | 84 | PrimaryExpression : 85 | `this` 86 | `%` 87 | Literal 88 | ArrayLiteral 89 | ObjectLiteral 90 | FunctionExpression 91 | ClassExpression 92 | GeneratorExpression 93 | AsyncFunctionExpression 94 | AsyncGeneratorExpression 95 | RegularExpressionLiteral 96 | TemplateLiteral 97 | CoverParenthesizedExpressionAndArrowParameterList 98 | 99 | 100 | 1. Return *false*. 101 | 102 |
    103 |
    104 | 105 | 106 |

    Contains

    107 | 108 | 109 |

    Static Semantics: ContainsOuterTopic

    110 | 111 |

    This section is a wholly new sub-clause of the original Contains clause.

    114 |
    115 | 116 | 117 |

    Several early error rules for |ScriptBody| and for 118 | |ModuleItemList|, as well as a step in CreateDynamicFunction, 119 | use the ContainsOuterTopic operation to check for any unbound topic reference `%`. 120 | Any inner topic reference within a |PipeBody| is hidden from these rules, 121 | preventing them from triggering the rules during program 122 | compilation.

    123 | 124 |

    This guarantees that any topic reference in a program must be 125 | present within a topic-binding environment 126 | created by a |PipeBody| within that program.

    127 |
    128 | 129 |

    Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of ContainsOuterTopic:

    130 | 131 | 132 | 1. For each child node _child_ of this Parse Node, do 133 | 1. If _child_ is an instance of `%`, return *true*. 134 | 1. If _child_ is an instance of a nonterminal, and if ContainsOuterTopic of _child_ is *true*, return *true*. 135 | 1. Return *false*. 136 | 137 | 138 | MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression 139 | 140 | 141 | 1. If ContainsOuterTopic of |MultiplicativeExpression| is *true*, or if ContainsOuterTopic of |ExponentiationExpression| is *true*, return *true*. 142 | 1. Return *false*. 143 | 144 | 145 | PipeBody : AssignmentExpression 146 | 147 | 148 | 1. Return *false*. 149 | 150 |
    151 |
    152 | 153 | 154 |

    Miscellaneous

    155 | 156 | 158 |

    Static Semantics: AssignmentTargetType

    159 | 160 | 161 |

    This section augments the original 163 | AssignmentTargetType clause.

    164 | 165 |

    It presumptively uses `%` as the placeholder token for the 166 | topic reference. This choice of token is not a final decision; `%` 167 | could instead be `^` or some other token.

    168 |
    169 | 170 | 171 | PrimaryExpression : 172 | `this` 173 | `%` 174 | Literal 175 | ArrayLiteral 176 | ObjectLiteral 177 | FunctionExpression 178 | ClassExpression 179 | GeneratorExpression 180 | AsyncFunctionExpression 181 | AsyncGeneratorExpression 182 | RegularExpressionLiteral 183 | TemplateLiteral 184 | 185 | PipeExpression : 186 | ShortCircuitExpression `|>` PipeBody 187 | 188 | 189 | 1. Return ~invalid~. 190 | 191 |
    192 |
    193 |
    194 | 195 | 196 |

    Executable Code and Execution Contexts

    197 | 198 | 199 |

    Environment Records

    200 | 201 | 202 |

    The Environment Record Type Hierarchy

    203 | 204 | 205 |

    This section augments the original 207 | Environment Records clause.

    208 |
    209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 223 | 226 | 227 | 228 |
    MethodPurpose
    HasTopicBinding()Determine whether an Environment Record is a 224 | topic-binding environment. Return *true* if it establishes a 225 | topic binding and *false* if it does not.
    229 |
    230 | 231 | 232 |

    Declarative Environment Records

    233 | 234 | 235 |

    This section augments the original Declarative Environment Records clause.

    238 | 239 |

    It presumptively uses `%` as the placeholder token for the 240 | topic reference. This choice of token is not a final decision; `%` 241 | could instead be `^` or some other token.

    242 |
    243 | 244 | 245 |

    Declarative Environment Records have the additional state fields 246 | listed in .

    247 | 248 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 268 | 269 | 270 |
    MethodValuePurpose
    [[TopicValues]]List of anyIf the declarative Environment Record is a topic-binding 264 | environment, then [[TopicValues]] is a List containing the one element 265 | which is the environment's topic value (that is, the value of 266 | the topic reference within its program scope). 267 | Otherwise, the value of [[TopicValues]] is an empty List.
    271 |
    272 | 273 | 274 |

    [[TopicValues]] is a List in order to be forward compatible with 275 | future extensions that would use more than one topic value, e.g., "pipe functions".

    278 |
    279 | 280 |

    Declarative Environment Records support all of the abstract methods 281 | of Environment Records listed in . 282 | In addition, declarative Environment Records support the methods listed 283 | in .

    284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 305 | 306 | 307 |
    MethodPurpose
    BindTopicValues(V)Establish the immutable topic binding of this 297 | Environment Record and set the topic binding's value. 298 | _V_ is a List containing the one element which is the 299 | topic value and is a value of any ECMAScript language 300 | type. Afterward, the Environment Record is a 301 | topic-binding environment, and the value returned by the 302 | Environment Record's HasTopicBinding method is *true*. 303 | This method cannot be called more than once on any 304 | single Environment Record.
    308 |
    309 | 310 | 311 |

    BindTopicValues accepts a List argument rather than a single-value 312 | argument in order to be forward compatible with future extensions that 313 | would use more than one topic value, e.g., "pipe functions".

    316 |
    317 |
    318 | 319 |

    The behaviour of the concrete and additional specification 320 | methods for declarative Environment Records is defined by the following 321 | algorithms.

    322 | 323 | 324 |

    HasTopicBinding ( )

    325 | 326 |

    This section is a wholly new sub-clause of the original Declarative Environment Records clause.

    329 |
    330 | 331 |

    The concrete Environment Record method HasTopicBinding for 332 | declarative Environment Records returns whether the Environment Record 333 | is a topic-binding environment. The value is *true* only if its 334 | BindTopicValues method has been called.

    335 | 336 | 1. Let _envRec_ be the declarative Environment Record for which the 337 | method was invoked. 338 | 1. Assert: _envRec_.[[TopicValues]] is a List. 339 | 1. If _envRec_.[[TopicValues]] is an empty List, then return *false*. 340 | 1. Return *true*. 341 | 342 |
    343 | 344 | 345 |

    BindTopicValues ( _V_ )

    346 | 347 |

    This section is a wholly new sub-clause of the original Declarative Environment Records clause.

    350 |
    351 |

    The method BindTopicValues for declarative Environment Records may 352 | only be called on an Environment Record when it is not yet a 353 | topic-binding environment, after which it does become a topic-binding 354 | environment.

    355 | 356 | 1. Assert: _V_ is a List. 357 | 1. Let _envRec_ be the declarative Environment Record for which the 358 | method was invoked. 359 | 1. Assert: _envRec_.HasTopicBinding() is *false*. 360 | 1. Set _envRec_.[[TopicValues]] to _V_. 361 | 1. Assert: _envRec_.HasTopicBinding() is *true*. 362 | 1. Return NormalCompletion(~empty~). 363 | 364 |
    365 |
    366 | 367 | 368 |

    Object Environment Records

    369 | 370 | 371 |

    HasTopicBinding ( )

    372 | 373 | 374 |

    This section is a wholly new sub-clause of the 376 | original Object Environment Records clause.

    377 |
    378 | 379 |

    An Object Environment Record may never have a topic binding.

    380 | 381 | 1. Return *false*. 382 | 383 |
    384 |
    385 | 386 | 387 |

    Global Environment Records

    388 | 389 | 390 |

    HasTopicBinding ( )

    391 | 392 | 393 |

    This section is a wholly new sub-clause of the 395 | original Global Environment Records clause.

    396 |
    397 | 398 |

    A Global Environment Record may never have a topic binding.

    399 | 400 | 1. Return *false*. 401 | 402 |
    403 |
    404 |
    405 | 406 | 407 |

    Topic Bindings

    408 | 409 | 410 |

    This section is a wholly new sub-clause of the original 412 | Environment Records clause.

    413 | 414 |

    It presumptively uses `%` as the placeholder token for the 415 | topic reference. This choice of token is not a final decision; `%` 416 | could instead be `^` or some other token.

    417 |
    418 | 419 |

    The topic binding of a declarative Environment Record 420 | immutably binds the topic reference `%` to one value of any 421 | ECMAScript language type (called the topic value or simply 422 | the topic), within that declarative Environment Record, at 423 | the time of the Environment Record's instantiation. The topic of a 424 | declarative Environment Record conceptually serves as the value that its 425 | lexical context is "about".

    426 | 427 |

    A topic-binding environment is a declarative Environment 428 | Record that establishes a topic binding. 429 | The topic environment of the running execution context is its 430 | LexicalEnvironment's innermost Environment Record that is also a 431 | topic-binding environment (or *null* if no such Environment Record 432 | exists), as defined by the abstract operator GetTopicEnvironment.

    433 | 434 | 435 |

    An Environment Record is a topic-binding environment 436 | only when it is a declarative Environment Record that 437 | was created by a |PipeBody|.

    438 |
    439 |
    440 |
    441 | 442 | 443 |

    Execution Contexts

    444 | 445 | 446 |

    This section augments the original 448 | Execution Contexts clause.

    449 |
    450 | 451 | 452 |

    453 | EvaluateWithTopics ( 454 | _topicValues_: a List, 455 | _expression_: a Parse Node, 456 | ) 457 |

    458 |
    459 | 460 | 1. Assert: _topicValues_ is a List. 461 | 1. Let _outerEnv_ be the running execution context's LexicalEnvironment. 462 | 1. Let _topicEnv_ be NewDeclarativeEnvironment(_outerEnv_). 463 | 1. Perform ! _topicEnv_.BindTopicValues(_topicValues_). 464 | 1. Set the running execution context's LexicalEnvironment to 465 | _topicEnv_. 466 | 1. Let _result_ be the result of evaluating _expression_. 467 | 1. Set the running execution context's LexicalEnvironment to _outerEnv_. 468 | 1. Return _result_. 469 | 470 | 471 |

    EvaluateWithTopics creates a new topic-binding environment and 472 | evaluates the given _expression_ with that as its topic environment. 473 | The previous Lexical Environment is restored afterward.

    474 |
    475 |
    476 | 477 | 478 |

    GetTopicEnvironment ( )

    479 |
    480 | 481 | 1. Let _envRec_ be the running execution context's LexicalEnvironment. 482 | 1. Repeat, 483 | 1. Let _status_ be _envRec_.HasTopicBinding(). 484 | 1. If _status_ is *true*, return _envRec_. 485 | 1. If _envRec_ is a global Environment Record, return *null*. 486 | 1. Let _outer_ be the value of _envRec_.[[OuterEnv]]. 487 | 1. Set _envRec_ to _outer_. 488 | 1. Return _envRec_. 489 | 490 | 491 |

    GetTopicEnvironment returns the running execution context's topic environment 492 | (i.e., its LexicalEnvironment's innermost topic-binding environment) 493 | or *null* if the running execution context has no topic binding.

    494 |
    495 |
    496 | 497 | 498 |

    GetPrimaryTopicValue ( )

    499 |
    500 | 501 | 1. Let _topicEnv_ be GetTopicEnvironment(). 502 | 1. Assert: _topicEnv_ is a declarative Environment Record. 503 | 1. Assert: _topicEnv_.HasTopicBinding() is *true*. 504 | 1. Let _topicValues_ be _envRec_.[[TopicValues]]. 505 | 1. Assert: _topicValues_ has at least one element. 506 | 1. Return _topicValues_[0]. 507 | 508 | 509 |

    GetPrimaryTopicValue returns the topic value 510 | of the running execution context's topic environment. 511 | It may be called only when the running execution context's topic environment 512 | is not *null*.

    513 |
    514 |
    515 |
    516 |
    517 | 518 | 519 |

    ECMAScript Language: Lexical Grammar

    520 | 521 | 522 |

    Punctuators

    523 | 524 | 525 |

    This section augments the original 527 | Punctuators clause.

    528 | 529 |

    It presumptively uses `%` as the placeholder token for the 530 | topic reference. This choice of token is not a final decision; `%` 531 | could instead be `^` or some other token.

    532 |
    533 | 534 | 535 | OtherPunctuator :: one of 536 | `{` `(` `)` `[` `]` 537 | `.` `...` `;` `,` 538 | `<` `>` `<=` `>=` 539 | `==` `!=` `===` `!==` 540 | `+` `-` `*` `%` `**` 541 | `++` `--` 542 | `<<` `>>` `>>>` 543 | `&` `|` `%` 544 | `!` `~` 545 | `&&` `||` `??` 546 | `?` `:` 547 | `|>` 548 | `=` `+=` `-=` `*=` `%=` `**=` 549 | `<<=` `>>=` `>>>=` `&=` `|=` `^=` 550 | `&&=` `||=` `??=` 551 | `=>` 552 | 553 | DivPunctuator :: 554 | `/` 555 | `/=` 556 | `%=` 557 | 558 |
    559 |
    560 | 561 | 562 |

    ECMAScript Language: Expressions

    563 | 564 | 565 |

    Primary Expression

    566 | 567 | 568 |

    This section augments the original 570 | Primary Expression clause.

    571 | 572 |

    It presumptively uses `%` as the placeholder token for the 573 | topic reference. This choice of token is not a final decision; `%` 574 | could instead be `^` or some other token.

    575 |
    576 | 577 |

    Syntax

    578 | 579 | PrimaryExpression[Yield, Await] : 580 | `this` 581 | `%` 582 | IdentifierReference[?Yield, ?Await] 583 | Literal 584 | ArrayLiteral[?Yield, ?Await] 585 | ObjectLiteral[?Yield, ?Await] 586 | FunctionExpression 587 | ClassExpression[?Yield, ?Await] 588 | GeneratorExpression 589 | AsyncFunctionExpression 590 | AsyncGeneratorExpression 591 | RegularExpressionLiteral 592 | TemplateLiteral[?Yield, ?Await, ~Tagged] 593 | CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] 594 | 595 | 596 | 597 |

    Topic Reference

    598 | 599 | 600 |

    This section is a wholly new sub-clause to be inserted between the original `this` 602 | Keyword clause and the original 604 | Identifier Reference clause.

    605 | 606 |

    It presumptively uses `%` as the placeholder token for the 607 | topic reference. This choice of token is not a final decision; `%` 608 | could instead be `^` or some other token.

    609 |
    610 | 611 | 612 |

    The topic reference, which is the token `%`, is a 613 | nullary operator that evaluates to the current Environment Record's 614 | topic value. The topic reference acts as if it were a special variable, 615 | implicitly bound to the topic value, yet still lexically scoped. But 616 | `%` is not actually an |IdentifierName| and the topic reference is 617 | not a variable, and it cannot be bound by typical assignment. 618 | Instead, the topic reference is immutably bound to a value 619 | during the instantiation of any topic-binding environment by a |PipeBody|.

    620 | 621 |

    The concept of the topic binding is further discussed in Topic Bindings and in Declarative Environment 624 | Records.

    625 |
    626 | 627 | 628 |

    An unbound topic reference is a topic reference that 629 | is not present within any topic-binding environment created by a |PipeBody|. 630 | All unbound topic references are invalid syntax. 631 | Several early error rules for |ScriptBody| and for 632 | |ModuleItemList|, as well as a step in CreateDynamicFunction, 633 | use ContainsOuterTopic to check for any unbound topic reference `%`. 634 | Any inner topic reference within a |PipeBody| is hidden from these rules, 635 | preventing them from triggering the rules during program 636 | compilation.

    637 | 638 |

    This guarantees that every topic reference in a program must be 639 | present within a topic-binding environment 640 | created by a |PipeBody| within that program.

    641 |
    642 | 643 | 644 |

    Runtime Semantics: Evaluation

    645 | 646 |

    A topic reference may be evaluated only when 647 | the running execution context's topic environment is not *null*. 648 | This is syntactically enforced by early error rules 649 | for |ScriptBody| and for |ModuleItemList|, 650 | as well as a step in CreateDynamicFunction. 651 | These rules use ContainsOuterTopic to check for any unbound topic reference.

    652 |
    653 | 654 | PrimaryExpression : `%` 655 | 656 | 1. Return GetPrimaryTopicValue(). 657 | 658 |
    659 |
    660 |
    661 | 662 | 663 |

    Pipe Operator

    664 | 665 | 666 |

    This section is a wholly new sub-clause to be inserted between the original 668 | Conditional Operator (`?` `:`) clause and the original 670 | Assignment Operators clause.

    671 |
    672 | 673 |

    Syntax

    674 | 675 | PipeExpression[In, Yield, Await] : 676 | ShortCircuitExpression[?In, ?Yield, ?Await] `|>` PipeBody[?In, ?Yield, ?Await] 677 | 678 | PipeBody[In, Yield, Await] : 679 | AssignmentExpression[?In, ?Yield, ?Await] 680 | 681 | 682 | 683 |

    Static Semantics: Early Errors

    684 | 685 |

    This section is a wholly new sub-clause.

    686 | 687 |

    It presumptively uses `%` as the placeholder token for the 688 | topic reference. This choice of token is not a final decision; `%` 689 | could instead be `^` or some other token.

    690 |
    691 | 692 | PipeBody : AssignmentExpression 693 | 694 | 1. It is a Syntax Error if |PipeBody| ContainsOuterTopic is *false*. 695 | 696 | 697 | 698 |

    A |PipeBody| must use its topic at least once. 699 | `value |> foo + 1` is an early error, 700 | because ContainsOuterTopic of its |PipeBody| is *false*. 701 | This design is such because omission of any topic reference from a |PipeBody| 702 | is almost certainly an accidental programmer error.

    703 |
    704 | 705 | PipeBody : AssignmentExpression 706 | 707 | 1. It is a Syntax Error if one of the following productions is covering |PipeBody|: 708 | * |ShortCircuitExpression| ? |AssignmentExpression| : |AssignmentExpression| 709 | * |YieldExpression| 710 | * |ArrowFunction| 711 | * |AsyncArrowFunction| 712 | * |LeftHandSideExpression| `=` |AssignmentExpression| 713 | * |LeftHandSideExpression| |AssignmentOperator| |AssignmentExpression| 714 | * |LeftHandSideExpression| `&&=` |AssignmentExpression| 715 | * |LeftHandSideExpression| `||=` |AssignmentExpression| 716 | * |LeftHandSideExpression| `??=` |AssignmentExpression| 717 | 718 | 719 | 720 |

    A |PipeBody| must not be an unparenthesized |AssignmentExpression|, such as |YieldExpression|, |ArrowFunction|, or |ConditionalExpression|—unless it is a |ShortCircuitExpression|.

    721 |

    This is to prevent confusing expressions from being valid, such as:

    722 |
    
    723 |           x |> yield % |> % + 1 // Syntax Error
    724 |         
    725 |

    This expression would otherwise be equivalent to:

    726 |
    
    727 |           x |> (yield % |> % + 1)
    728 |         
    729 |

    Likewise, this expression:

    730 |
    
    731 |           x |> y ? % : z |> % + 1 // Syntax Error
    732 |         
    733 |

    …would otherwise be equivalent to:

    734 |
    
    735 |           x |> (y ? % : z |> % + 1)
    736 |         
    737 |

    These expressions are visually unclear and are therefore made invalid. The developer may make them valid with explicit parentheses:

    738 |
    
    739 |           x |> (yield %) |> % + 1
    740 |           x |> (yield % |> % + 1)
    741 |           x |> (y ? % : z) |> % + 1
    742 |           x |> (y ? % : z |> % + 1)
    743 |         
    744 |
    745 |
    746 | 747 | 748 |

    Runtime Semantics: Evaluation

    749 | 750 | PipeExpression : ConditionalExpression `|>` PipeBody 751 | 752 | 1. Let _inputRef_ be the result of evaluating _ConditionalExpression_. 753 | 1. Let _inputValues_ be « ? GetValue(_inputRef_) ». 754 | 1. Let _outputValue_ be ? EvaluateWithTopics(_inputValues_, |PipeBody|). 755 | 1. Return _outputValue_. 756 | 757 |
    758 |
    759 |
    760 | 761 | 762 |

    ECMAScript Language: Scripts and Modules

    763 | 764 | 765 |

    Scripts

    766 | 767 | 768 |

    This section augments the original 770 | Scripts clause.

    771 | 772 |

    It presumptively uses `%` as the placeholder token for the 773 | topic reference. This choice of token is not a final decision; `%` 774 | could instead be `^` or some other token.

    775 |
    776 | 777 | 778 |

    Static Semantics: Early Errors

    779 | 780 | Script : ScriptBody 781 |
      782 |
    • 783 | It is a Syntax Error if ContainsOuterTopic of |ScriptBody| is *true*. 784 |
    • 785 |
    786 | 787 | 788 |

    An early error rule uses ContainsOuterTopic 789 | to check for any unbound topic reference. 790 | Any inner topic reference within a |PipeBody| is hidden from this rule, 791 | preventing them from triggering the rule during program 792 | compilation.

    793 | 794 |

    This guarantees that every topic reference in a |Script| must be 795 | present within a topic-binding environment created 796 | by a |PipeBody| within that |Script|.

    797 |
    798 |
    799 |
    800 |
    801 | 802 | 803 |

    Modules

    804 | 805 | 806 |

    Module Semantics

    807 | 808 | 809 |

    This section augments the original 811 | Module Semantics clause.

    812 | 813 |

    It presumptively uses `%` as the placeholder token for the 814 | topic reference. This choice of token is not a final decision; `%` 815 | could instead be `^` or some other token.

    816 |
    817 | 818 | 819 |

    Static Semantics: Early Errors

    820 | ModuleBody : ModuleItemList 821 |
      822 |
    • 823 | It is a Syntax Error if ContainsOuterTopic of |ModuleItemList| 824 | is *true*. 825 |
    • 826 |
    827 | 828 | 829 | 830 |

    An early error rule uses ContainsOuterTopic 831 | to check for any unbound topic reference. 832 | Any inner topic reference within a |PipeBody| is hidden from this rule, 833 | preventing them from triggering the rule during program 834 | compilation.

    835 | 836 |

    This guarantees that every topic reference in a |ModuleBody| must be 837 | present within a topic-binding environment created 838 | by a |PipeBody| within that |ModuleBody|.

    839 |
    840 |
    841 |
    842 |
    843 |
    844 |
    845 | 846 | 847 |

    Fundamental Objects

    848 | 849 | 850 |

    Function Objects

    851 | 852 | 853 |

    The Function Constructor

    854 | 855 | 856 |

    Function ( _p1_, _p2_, … , _pn_, _body_ )

    857 | 858 | 859 |

    CreateDynamicFunction ( _constructor_, _newTarget_, _kind_, _args_ )

    860 | 861 |

    This section augments the original 863 | CreateDynamicFunction clause.

    864 | 865 |

    It presumptively uses `%` as the placeholder token for the 866 | topic reference. This choice of token is not a final decision; `%` 867 | could instead be `^` or some other token.

    868 |
    869 | 870 | 871 | 1. Assert: The execution context stack has at least two elements. 872 | 1. Let _callerContext_ be the second to top element of the execution context stack. 873 | 1. Let _callerRealm_ be _callerContext_'s Realm. 874 | 1. Let _calleeRealm_ be the current Realm Record. 875 | 1. Perform ? HostEnsureCanCompileStrings(_callerRealm_, _calleeRealm_). 876 | 1. If _newTarget_ is *undefined*, set _newTarget_ to _constructor_. 877 | 1. If _kind_ is ~normal~, then 878 | 1. Let _exprSym_ be the grammar symbol |FunctionExpression|. 879 | 1. Let _bodySym_ be the grammar symbol |FunctionBody[~Yield, ~Await]|. 880 | 1. Let _parameterSym_ be the grammar symbol |FormalParameters[~Yield, ~Await]|. 881 | 1. Let _fallbackProto_ be *"%Function.prototype%"*. 882 | 1. Else if _kind_ is ~generator~, then 883 | 1. Let _exprSym_ be the grammar symbol |GeneratorExpression|. 884 | 1. Let _bodySym_ be the grammar symbol |GeneratorBody|. 885 | 1. Let _parameterSym_ be the grammar symbol |FormalParameters[+Yield, ~Await]|. 886 | 1. Let _fallbackProto_ be *"%GeneratorFunction.prototype%"*. 887 | 1. Else if _kind_ is ~async~, then 888 | 1. Let _exprSym_ be the grammar symbol |AsyncFunctionExpression|. 889 | 1. Let _bodySym_ be the grammar symbol |AsyncFunctionBody|. 890 | 1. Let _parameterSym_ be the grammar symbol |FormalParameters[~Yield, +Await]|. 891 | 1. Let _fallbackProto_ be *"%AsyncFunction.prototype%"*. 892 | 1. Else, 893 | 1. Assert: _kind_ is ~asyncGenerator~. 894 | 1. Let _exprSym_ be the grammar symbol |AsyncGeneratorExpression|. 895 | 1. Let _bodySym_ be the grammar symbol |AsyncGeneratorBody|. 896 | 1. Let _parameterSym_ be the grammar symbol |FormalParameters[+Yield, +Await]|. 897 | 1. Let _fallbackProto_ be *"%AsyncGeneratorFunction.prototype%"*. 898 | 1. Let _argCount_ be the number of elements in _args_. 899 | 1. Let _P_ be the empty String. 900 | 1. If _argCount_ = 0, let _bodyArg_ be the empty String. 901 | 1. Else if _argCount_ = 1, let _bodyArg_ be _args_[0]. 902 | 1. Else, 903 | 1. Assert: _argCount_ > 1. 904 | 1. Let _firstArg_ be _args_[0]. 905 | 1. Set _P_ to ? ToString(_firstArg_). 906 | 1. Let _k_ be 1. 907 | 1. Repeat, while _k_ < _argCount_ - 1, 908 | 1. Let _nextArg_ be _args_[_k_]. 909 | 1. Let _nextArgString_ be ? ToString(_nextArg_). 910 | 1. Set _P_ to the string-concatenation of _P_, *","* (a comma), and _nextArgString_. 911 | 1. Set _k_ to _k_ + 1. 912 | 1. Let _bodyArg_ be _args_[_k_]. 913 | 1. Let _bodyString_ be the string-concatenation of 0x000A (LINE FEED), ? ToString(_bodyArg_), and 0x000A (LINE FEED). 914 | 1. Let _prefix_ be the prefix associated with _kind_ in . 915 | 1. Let _sourceString_ be the string-concatenation of _prefix_, *" anonymous("*, _P_, 0x000A (LINE FEED), *") {"*, _bodyString_, and *"}"*. 916 | 1. Let _sourceText_ be ! StringToCodePoints(_sourceString_). 917 | 1. Let _parameters_ be ParseText(! StringToCodePoints(_P_), _parameterSym_). 918 | 1. If _parameters_ is a List of errors, throw a *SyntaxError* exception. 919 | 1. Let _body_ be ParseText(! StringToCodePoints(_bodyString_), _bodySym_). 920 | 1. If _body_ is a List of errors, throw a *SyntaxError* exception. 921 | 1. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, `new Function("/*", "*/ ) {")` is not legal. 922 | 1. NOTE: If this step is reached, _sourceText_ must match _exprSym_ (although the reverse implication does not hold). The purpose of the next two steps is to enforce any Early Error rules which apply to _exprSym_ directly. 923 | 1. Let _expr_ be ParseText(_sourceText_, _exprSym_). 924 | 1. If _expr_ is a List of errors, throw a *SyntaxError* exception. 925 | 1. NOTE: The dynamic function must not contain an unbound topic reference `%`.) 926 | 1. If ContainsOuterTopic of _expr_ is *true*, throw a *SyntaxError* exception. 927 | 1. Let _proto_ be ? GetPrototypeFromConstructor(_newTarget_, _fallbackProto_). 928 | 1. Let _realmF_ be the current Realm Record. 929 | 1. Let _scope_ be _realmF_.[[GlobalEnv]]. 930 | 1. Let _privateScope_ be *null*. 931 | 1. Let _F_ be ! OrdinaryFunctionCreate(_proto_, _sourceText_, _parameters_, _body_, ~non-lexical-this~, _scope_, _privateScope_). 932 | 1. Perform SetFunctionName(_F_, *"anonymous"*). 933 | 1. If _kind_ is ~generator~, then 934 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%). 935 | 1. Perform DefinePropertyOrThrow(_F_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 936 | 1. Else if _kind_ is ~asyncGenerator~, then 937 | 1. Let _prototype_ be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%). 938 | 1. Perform DefinePropertyOrThrow(_F_, *"prototype"*, PropertyDescriptor { [[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). 939 | 1. Else if _kind_ is ~normal~, perform MakeConstructor(_F_). 940 | 1. NOTE: Functions whose _kind_ is ~async~ are not constructible and do not have a [[Construct]] internal method or a *"prototype"* property. 941 | 1. Return _F_. 942 | 943 |
    944 |
    945 |
    946 |
    947 |
    948 | --------------------------------------------------------------------------------