## dist_zef-Scimon-Test-HTTP-Server.md
[![Build Status](https://travis-ci.org/Scimon/p6-Test-HTTP-Server.svg?branch=master)](https://travis-ci.org/Scimon/p6-Test-HTTP-Server)

# NAME

Test::HTTP::Server - Simple to use wrapper around HTTP::Server::Async designed for tests

# SYNOPSIS

```
use Test::HTTP::Server;

# Simple usage
# $path is a folder with a selection of test files including index.html
my $test-server = Test::HTTP::Server.new( :dir($path) );

# method-to-test expects a web host and will make a GET request to host/index.html
ok method-to-test( :host( "http://localhost:{$test-server.port}" ) ), "This is a test";
# Other tests on the results here.

my @events = $test-server.events;
is @events.elems, 1, "One request made";
is @events[0].path, '/index.html', "Expected path called";
is @events[0].method, 'GET', "Expected method used";
is @events[0].code, 200, "Expected response code";
$test-server.clear-events;

```

# DESCRIPTION

Test::HTTP::Server is a wrapper around HTTP::Server::Async designed to allow for simple Mock testing of web services.

The constructor accepts a 'dir' and an optional 'port' parameter.

The server will server up any files that exist in 'dir' on the given port (if not port is given then one will be assigned, the '.port' method can be accessed to find what port is being used).

All requests are logged in a basic even log allowing for testing. If you make multiple async requests to the server the ordering of the events list cannot be assured and tests should be written based on this.

If a file doesn't exist then the server will return a 404.

Currently the server returns all files as 'text/plain' except files with the following extensions :

* `html` => `text/html`
* `png` => `image/png`
* `jpg` => `image/jpeg`
* `jpeg` => `image/jpeg`
* `gif` => `image/gif`
* `js` => `application/javascript`
* `json` => `application/json`
* `css` => `text/css`
* `xml` => `application/xml`

## CONFIG

You can include a file called `config.yml` in the file which allows for additional control over the responses. The following keys are available :

### mime

Hash representation of extension and mime type header allows adding additional less common mime types.

### paths

Hash where keys are paths to match (including leading `/`), values are hashes with the currently allowed keys :

#### returns

A list of commands to specify the return result, currently valid values.

* Any 3 digit code => returns that HTTP status.
* "file" => returns the file at the given path.
* "loop" => goes to the top of the list and processes that

Each time a request is made to the given path the next response in the list will be given. If the end of the list is reached then this result will be returned from then on.

## METHODS

### events

Returns the list of event objects giving the events registered to the server. Note if async requests are being made the order of events cannot be assured.

Events objects have the following attributes :

* `path` Path of the request
* `method` Method of the request
* `code` HTTP code of the response

### clear-events

Clear the event list allowing the server to be reused in further tests. Calling this method will also reset all the indexes on 'returns' in the config files. Further requests will start from the first registered response.

### mime-types

Returns a hash of mime-types registered with the server including any added in `config.yml` file.

## TODO

This is a very basic version of the server in order to allow other development to be worked on. Planned is to allow a config.yml file to exist in the top level directory. If the file exists it will allow you control different paths and their responses.

This is intended to allow the system to replicate errors to allow for error testing.

# AUTHOR

Simon Proctor [simon.proctor@gmail.com](mailto:simon.proctor@gmail.com)

# COPYRIGHT AND LICENSE

Copyright 2018 Simon Proctor

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_cpan-TYIL-I18n-Simple.md
# NAME

I18n::Simple

# AUTHOR

Patrick Spek [p.spek@tyil.work](mailto:p.spek@tyil.work)

# VERSION

0.0.0

# Description

A simple internationalisation module.

# Installation

Install this module through [zef](https://github.com/ugexe/zef):

```
zef install Text::I18n

```

# Using the module

# Examples

Take the following YAML file, and save it in your module's `resources` directory. These examples assume the file being saved at `resources/i18n/en.yml`.

```
---
foo: This is a template!
bar: This template is for you, $(user).

```

Then use the module as follows:

```
use I18n::Simple;

# Load the templates. You can make the `en` part a variable to easily switch
# between different languages in your program.
i18n-init(%?RESOURCES<i18n/en.yml>);

# Call a template without placeholders
dd i18n("foo"); # "This is a template!"

# Call a template with placeholders
dd i18n("bar", user => "Bob"); # "This template is for you, Bob."

```

# License

This module is distributed under the terms of the AGPL-3.0.


## dist_github-wollmers-LCS-BV.md
# NAME

LCS::BV - Bit Vector (BV) implementation of the Longest Common Subsequence (LCS) Algorithm

# html

[![P6-LCS-BV](https://travis-ci.org/wollmers/P6-LCS-BV.png)](https://travis-ci.org/wollmers/P6-LCS-BV)

# SYNOPSIS

```
  use LCS::BV;

  $lcs = LCS::BV::LCS($a,$b);

```

# ABSTRACT

LCS::BV implements the Longest Common Subsequence (LCS) Algorithm and is more than double as fast (Jan 2016) than Algorithm::Diff::LCSidx().

# DESCRIPTION

This module is a port from the Perl5 module with the same name.

The algorithm used is based on

```
H. Hyyroe. A Note on Bit-Parallel Alignment Computation. In
M. Simanek and J. Holub, editors, Stringology, pages 79-87. Department
of Computer Science and Engineering, Faculty of Electrical
Engineering, Czech Technical University, 2004.

```

## METHODS

* LCS($a,$b)

Finds a Longest Common Subsequence, taking two arrayrefs as method arguments. It returns an array reference of corresponding indices, which are represented by 2-element array refs.

# SEE ALSO

Algorithm::Diff

# AUTHOR

Helmut Wollmersdorfer [lthelmut.wollmersdorfer@gmail.comgt](mailto:lthelmut.wollmersdorfer@gmail.comgt)


## dist_zef-lizmat-Ecosystem.md
[![Actions Status](https://github.com/lizmat/Ecosystem/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/Ecosystem/actions) [![Actions Status](https://github.com/lizmat/Ecosystem/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/Ecosystem/actions) [![Actions Status](https://github.com/lizmat/Ecosystem/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/Ecosystem/actions)

# NAME

Ecosystem - Accessing a Raku Ecosystem Storage

# SYNOPSIS

```
use Ecosystem;

my $eco = Ecosystem.new;  # access the REA ecosystem

say "Ecosystem has $eco.identities.elems() identities:";
.say for $eco.identities.keys.sort;

```

# DESCRIPTION

Ecosystem provides the basic logic to accessing a Raku Ecosystem, defaulting to the Raku Ecosystem Archive, a place where (almost) every distribution ever available in the Raku Ecosystem, can be obtained even after it has been removed (specifically in the case of the old ecosystem master list and the distributions kept on CPAN).

# COMMAND LINE INTERFACE

An `ecosystems` interactive interface is provided by the [App::Ecosystems](https://raku.land/zef:lizmat/App::Ecosystems) distribution.

# CONSTRUCTOR ARGUMENTS

## ecosystem

```
my $eco = Ecosystem.new(:ecosystem<fez>);

```

The `ecosystem` named argument is string that indicates which ecosystem (content-storage) should be used: it basically is a preset for the `meta-url` and `IO` arguments. The following names are recognized:

* p6c the original content storage / ecosystem
* cpan the content storage that uses CPAN
* fez the zef (fez) ecosystem
* rea the Raku Ecosystem Archive (default)

If this argument is not specified, then at least the `IO` named argument must be specified.

## IO

```
my $eco = Ecosystem.new(IO => "path".IO);

```

The `IO` named argument specifies the path of the file that contains / will contain the META information. If not specified, will default to whatever can be determined from the other arguments.

## meta-url

```
my $eco = Ecosystem.new(meta-url => "https://foo.bar/META.json");

```

The `meta-url` named argument specifies the URL that should be used to obtain the META information if it is not available locally yet, or if it has been determined to be stale. Will default to whatever can be determined from the other arguments. If specified, then the `IO` arguments **must** also be specified to store the meta information in.

## stale-period

```
my $eco = Ecosystem.new(stale-period => 3600);

```

The `stale-period` named argument specifies the number of seconds after which the meta information is considered to be stale and needs updating using the `meta-url`. Defaults to `86400`, aka 1 day.

## longname

```
my $eco = Ecosystem.new(longname => 'My very own ecosystem storage';

```

The long name with which the ecosystem is to be known. Defaults to sensible name for the 4 original ecosystems: p6c cpan fez rea.

# CLASS METHODS

## dependencies-from-meta

```
my $eco = Ecosystem.new;
.say for $eco.dependencies-from-meta(from-json $io.slurp);

```

The `dependencies-from-meta` class method returns the list of `use-targets` as specified in the `depends` field of the given hash with meta information.

## sort-identities

```
.say for Ecosystem.sort-identities(@identities);

```

The `sort-identities` class method sorts the given identities with the highest version first, and then by the `short-name` of the identity.

# INSTANCE METHODS

## authors

```
my $eco = Ecosystem.new;
.say for $eco.authors{ / eigenstates / }

```

The `authors` instance method returns a [Map::Match](https://raku.land/zef:lizmat/Map::Match) with the authors found in each distribution as the keys, and all of the identities each author was found in as the value.

## dependencies

```
my $eco = Ecosystem.new;
.say for $eco.dependencies("Ecosystem");

```

The `dependencies` instance method returns a sorted list of all `use-target`s (either directly or recursively) for an `identity`, `use-target` or `distro-name`.

## distro-names

```
my $eco = Ecosystem.new;
say "Found $eco.distro-names.elems() differently named distributions";

```

The `distro-names` instance method returns a `Map` keyed on distribution name, with a sorted list of the identities that have that distribution name (sorted by short-name, latest version first).

## distros-of-use-target

```
my $eco = Ecosystem.new;
.say for $eco.distros-of-use-target($target);

```

The `distro-of-use-target` instance method the names of the distributions that provide the given use target.

## ecosystem

```
my $eco = Ecosystem.new;
say "The ecosystem is $_" with $eco.ecosystem;

```

The `ecosystem` instance method returns the value (implicitely) specified with the `:ecosystem` named argument.

## find-distro-names

```
my $eco = Ecosystem.new;
.say for $eco.find-distro-names: / JSON /;

.say for $eco.find-distro-names: :auth<zef:lizmat>;

```

The `find-distro-names` instance method returns the distribution names that match the optional given string or regular expression, potentially filtered by a `:ver`, `:auth`, `:api` and/or `:from` value.

## find-identities

```
my $eco = Ecosystem.new;
.say for $eco.find-identities: / Utils /, :ver<0.0.3+>, :auth<zef:lizmat>;

.say for $eco.find-identities: :auth<zef:lizmat>, :all;

.say for $eco.find-identities: :latest;

```

The `find-identities` method returns identities (sorted by short-name, latest version first) that match the optional given string or regular expression, potentially filtered by `:ver`, `:auth`, `:api` and/or `:from` value.

The specified string is looked up / regular expression is matched in the distribution names, the use-targets and the descriptions of the distributions.

By default, only the identity with the highest `:ver` value will be returned: a `:all` flag can be specified to return **all** possible identities.

The `:latest` flag can be specified to apply heuristics on the identities so that only the most recent version of a distribution across ecosystems and authorities will be returned. This will e.g. return only `AccountableBagHash:ver<0.0.6>:auth<zef:lizmat>` from a list with:

```
AccountableBagHash:ver<0.0.3>:auth<cpan:ELIZABETH>
AccountableBagHash:ver<0.0.6>:auth<zef:lizmat>

```

## find-no-tags

```
my $eco = Ecosystem.new;
.say for $eco.find-no-tags;

.say for $eco.find-no-tags: / zef /;

.say for $eco.find-no-tags: / zef / :all;

```

The `find-no-tags` method returns identities (sorted by short-name, latest version first) that match the optional given string or regular expression (potentially filtered by `:ver`, `:auth`, `:api` and/or `:from` value) that do **not** have any tags specified.

The specified string is looked up / regular expression is matched in the distribution names, the use-targets and the descriptions of the distributions.

By default, only the identity with the highest `:ver` value will be returned: a `:all` flag can be specified to return **all** possible identities that do **not** have tags.

## find-use-targets

```
my $eco = Ecosystem.new;
.say for $eco.find-use-targets: / JSON /;

.say for $eco.find-use-targets: :auth<zef:lizmat>;

```

The `find-use-targets` instance method returns the strings that can be used in a `use` command that match the optional given string or regular expression, potentially filtered by a `:ver`, `:auth`, `:api` and/or `:from` value.

## identities

```
my $eco = Ecosystem.new;
my %identities := $eco.identities;
say "Found %identities.elems() identities";

```

The `identities` instance method returns a `Map` keyed on identity string, with a `Map` of the META information of that identity as the value.

## identity-dependencies

```
my $eco = Ecosystem.new;
.say for $eco.identity-dependencies($identity);

.say for $eco.identity-dependencies($identity, :all);

```

The `identity-dependencies` instance method returns a sorted list of the dependencies of the given **identity** string, if any. Takes an optional `:all` named to also return any dependencies of the initial dependencies, recursively.

## identity-release-Date

```
my $eco = Ecosystem.new;
say $eco.identity-release-Date($identity);

```

The `identity-release-Date` instance method returns the `Date` when the the distribution of the given identity string was released, or `Nil` if either the identity could not be found, or if there is no release date information available.

## identity-release-yyyy-mm-dd

```
my $eco = Ecosystem.new;
say $eco.identity-release-yyyy-mm-dd($identity);

```

The `identity-release-yyyy-mm-dd` instance method returns a `Str` in YYYY-MM-DD format of when the the distribution of the given identity string was released, or `Nil` if either the identity could not be found, or if there is no release date information available.

## identity-url

```
my $eco = Ecosystem.new;
say $eco.identity-url($identity);

```

The `identity-url` instance method returns the `URL` of the distribution file associated with the given identity string, or `Nil`.

## IO

```
my $eco = Ecosystem.new(:IO("foobar.json").IO);
say $eco.IO;  # "foobar.json".IO

```

The `IO` instance method returns the `IO::Path` object of the file where the local copy of the META data lives.

## least-recent-release

```
my $eco = Ecosystem.new;
say $eco.least-recent-release;

```

The `least-recent-release` instancemethod returns the `Date` of the least recent release in the ecosystem, if any.

## longname

```
my $eco = Ecosystem.new;
say $eco.longname;  # Raku Ecosystem Archive

```

Return the long name of the ecosystem.

## matches

```
my $eco = Ecosystem.new;
.say for $eco.matches{ / Utils / }

```

The `matches` instance method returns a [Map::Match](https://raku.land/zef:lizmat/Map::Match) with the string that caused addition of an identity as the key, and a sorted list of the identities that either matched the distribution name or the description (sorted by short-name, latest version first). It is basically the workhorse of the [find-identities](#find-identities) method.

## meta

```
my $eco = Ecosystem.new;
say $eco.meta;  # ...

```

The `meta` instance method returns the JSON representation of the META data.

## meta-url

```
my $eco = Ecosystem.new(:ecosystem<fez>);
say $eco.meta-url;  # https://360.zef.pm/

```

The `meta-url` instance method returns the URL that is used to fetch the META data, if any.

## most-recent-release

```
my $eco = Ecosystem.new;
say $eco.most-recent-release;

```

The `most-recent-release` instance method returns the `Date` of the most recent release in the ecosystem, if any.

## resolve

```
my $eco = Ecosystem.new;
say $eco.resolve("eigenstates");  # eigenstates:ver<0.0.9>:auth<zef:lizmat>

```

The `resolve` instance method attempts to resolve the given string and the given `:ver`, `:auth`, `:api` and `:from` named arguments to the identity that would be assumed when specified with e.g. `dependencies`.

## reverse-dependencies

```
my $eco = Ecosystem.new;
my %reverse-dependencies := $eco.reverse-dependencies;
say "Found %reverse-dependencies.elems() reverse dependencies";

```

The `reverse-dependencies` instance method returns a `Map` keyed on resolved dependencies, with a list of identities that depend on it.

## reverse-dependencies-for-short-name

```
my $eco = Ecosystem.new;
.say for $eco.reverse-dependencies-for-short-name("File::Temp");

```

The `reverse-dependencies-for-short-name` instance method returns a unique list of short-names of identities that depend on any version of the given short-name.

## river

```
my $eco = Ecosystem.new;
say "Top five modules on the Raku Ecosystem River:";
.say for $eco.river.sort(-*.value.elems).map(*.key).head(5);

```

The `river` instance method returns a `Map` keyed on short-name of an identity, with as value a list of short-names of identities that depend on it **without** having pinned `:ver` and `:auth` in their dependency specification.

## stale-period

```
my $eco = Ecosystem.new;
say $eco.stale-period;  # 86400

```

The `stale-period` instance method returns the number of seconds after which any locally stored META information is considered to be stale.

## release-dates

```
my $eco = Ecosystem.new;
.say for $eco.release-dates{ / ^2024 / }

```

The `release-dates` instance method returns a [Map::Match](https://raku.land/zef:lizmat/Map::Match) with the release-dates (YYYY-MM-DD) found in each distribution as the keys, and all of the identities that were released on that date as the value.

## tags

```
my $eco = Ecosystem.new;
.say for $eco.tags{ / eigenstates / }

```

The `tags` instance method returns a [Map::Match](https://raku.land/zef:lizmat/Map::Match) with the tags found in each distribution as the keys, and all of the identities each tag was found in as the value.

## update

```
my $eco = Ecosystem.new;
$eco.update;

```

The `update` instance method re-fetches the META information from the `meta-url` and updates it internal state in a thread-safe manner.

## unresolvable-dependencies

```
my $eco = Ecosystem.new;
say "Found $eco.unresolvable-dependencies.elems() unresolvable dependencies";

```

The `unresolvable-dependencies` instance method returns a `Map` keyed on an unresolved dependency, and a `List` of identities that have this unresolvable dependency as the value. By default, only current (as in the most recent version) identities will be in the list. You can specify the named `:all` argument to have also have the non-current identities listed.

## unversioned-distros

```
my $eco = Ecosystem.new;
say "Found $eco.unversioned-distro-names.elems() unversioned distributions";

```

The `unversioned-distro-names` instance method returns a sorted list of distribution names (identity without `:ver`) that do not have any release with a valid `:ver` value (typically **:ver<\*>**).

## use-targets

```
my $eco = Ecosystem.new;
say "Found $eco.use-targets.elems() different 'use' targets";

```

The `use-targets` instance method returns a `Map` keyed on 'use' target, with a sorted list of the identities that provide that 'use' target (sorted by short-name, latest version first).

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/Ecosystem> . Comments and Pull Requests are welcome.

If you like this module, or what I’m doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2022, 2024, 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_cpan-TYIL-File-XML-DMARC-Google.md
# NAME

File::XML::DMARC::Google

# AUTHOR

Patrick Spek [p.spek@tyil.work](mailto:p.spek@tyil.work)

# VERSION

0.1.1

# Description

Parser for XML-formatted DMARC reports from Google

# Installation

Install this module through [zef](https://github.com/ugexe/zef):

```
zef install File::XML::DMARC::Google

```

# License

This module is distributed under the terms of the AGPL-3.0.


## dist_zef-tony-o-fez.md
# zef ecosystem - cli

To install:

```
$ zef install fez

```

***NOTE: you must have zlib installed if you are not on windows!***

## fez

fez is the command line tool used to manage your ecosystem user/pass.

* [installation](#installation)
* [current functionality](#current-functionality)
* [module management](#module-management)
* [plugins](#plugins)
* [faq](#faq)
* [articles-about-fez](#articles-about-fez)
* [license](#license)
* [authors](#authors)

### installation

as easy as: `zef install fez`

### current functionality:

* login
* register
* upload
* reset-password
* meta
* plugin management
* command extensions via plugins

if you have features or edge cases that would make your migration to fez easier, please open a bug here in github or message me in #raku on freenode (tonyo).

### register

```
λ local:~$ fez register
>>= Email: xyz@abc.com
>>= Username: tony-o
>>= Password:
>>= registration successful, requesting auth key
>>= login successful, you can now upload dists
>>= what would you like your display name to show? tony o
>>= what's your website? DEATHBYPERL6.com
>>= public email address? xxxx
=<< your meta info has been updated

```

### login

This is not necessary if you've just registered but you will eventually have to request a new key.

```
λ local:~$ fez login
>>= Username: tony-o
>>= Password:
>>= login successful, you can now upload dists

```

### meta

Update your meta info - this information is public.

```
λ local:~$ fez meta
>>= what would you like your display name to show? tony o
>>= what's your website? DEATHBYPERL6.com
>>= public email address? xxxx
=<< your meta info has been updated

```

### upload

If you're not logged in for this bit then it will prompt you to do so.

```
λ local:~/projects/perl6-slang-sql-master$ fez upload
>>= Slang::SQL:ver<0.1.2>:auth<zef:tony-o> looks OK
>>= Hey! You did it! Your dist will be indexed shortly.

```

or, if there are errors:

```
λ local:~/Downloads/perl6-slang-sql-master$ fez upload
=<< "tonyo" does not match the username you last logged in with (tony-o),
=<< you will need to login before uploading your dist

```

### reset password

If you've forgotten your password, use this little guy.

```
λ local:~$ fez reset-password
>>= Username: tony-o
>>= A reset key was successfully requested, please check your email
>>= New Password:
>>= What is the key in your email? abcdef...
>>= password reset successful, you now have a new key and can upload dists

```

### review

This is the check fez runs when you run `fez upload`. NOTE: the depends, build depends, and provides checks are disabled until RakuAST becomes available.

```
$ fez review
>= Bundle manifest:
    <..list of files fez will bundle for upload..>
>>= Build depends ok
>>= Depends ok
>>= Provides ok
>>= Resources ok
>>= Test depends ok

```

-or if you have errors-

```
$ fez review
>= Bundle manifest:
    <..list of files fez will bundle for upload..>
>>= Build depends ok
>>= Depends not ok
>>=   in meta but unexpected:
         raku-mailgun
>>= Provides ok
>>= Resources not ok
>>=   not in meta:
         usage/license
>>= Test depends ok

```

If you're rolling your own tarballs then you can specify the file to checkout with `--file=`, please keep in mind that checkbuild requires access to a tar that can work with compression for *some* of these checks.

## module management

### listing your modules

`fez list <filter?>`

```
$ fez list csv
>>= CSV::Parser:ver<0.1.2>:auth<zef:tony-o>
>>= Text::CSV::LibCSV:ver<0.0.1>:auth<zef:tony-o>

```

```
$ fez list
>>= Bench:ver<0.2.0>:auth<zef:tony-o>
>>= Bench:ver<0.2.1>:auth<zef:tony-o>
>>= CSV::Parser:ver<0.1.2>:auth<zef:tony-o>
>>= Data::Dump:ver<0.0.12>:auth<zef:tony-o>
...etc

```

### removing a module

This is highly unrecommended but a feature nonetheless. This requires you use the full dist name as shown in `list` and is only available within 24 hours of upload. If an error occurs while removing the dist, you'll receive an email.

```
$ fez remove 'Data::Dump:ver<0.0.12>:auth<zef:tony-o>'
>>= Request received

```

## plugins

### plugin

`fez plugin` lists the current plugins in your config file(s).

`fez plugin <key> 'remove'|'append'|'prepend' <value>` does the requested action to in your user config.

#### extensions

fez can now load extensions to `MAIN`. this happens as a catchall at the bottom of fez and uses the first available extensions that it can and exits afterwards. eg if two extensions provide a command `fez test` then the first one that successfully completes (doesn't die or exit) will be run and then fez will exit.

## faq

* [do I need to remove modules from cpan](#do-i-need-to-remove-modules-from-cpan)
* [which version will zef choose if my module is also on cpan](#which-version-will-zef-choose-if-my-module-is-also-on-cpan)
* [what's this sdist directory](#whats-this-sdist-directory)

### do i need to remove modules from cpan?

No. If you want your fez modules to be prioritized then simply bump the version. Note that you can upload older versions of your modules using a tar.gz and specifing `fez upload --file <path to tar.gz>`.

### which version will zef choose if my module is also on cpan?

zef will prioritize whichever gives the highest version and then the rest depends on which ecosystem is checked first which can vary system to system.

### what's this sdist directory?

when fez bundles your source it outputs to `sdist/<name>.tar.gz` and then uploads that package to the ecosystem. there are two ways that fez might try to bundle your package. as of `fez:ver<26+>` fez will attempt to remove the sdist/ directory *if no `--file` is manually specified*

#### using pax

pax is the bundler included with v38 onward to avoid compatibility issues with certain BSDs. git archive is no longer used as it caused a lot of confusion - this means that what's on disk is what is getting bundled rather than what is in main/master!

#### using git archive (deprecated with v38)

fez will attempt to run `git archive` which will obey your `.gitignore` files. it is a good idea to put sdist/ in your root gitignore to prevent previously uploaded modules.

#### using tar (deprecated with v38)

if there is a `tar` in path then fez will try to bundle everything not in hidden directories/files (anything starting with a `.`) and ignore the `sdist/` directory.

## articles about fez

if you'd like to see your article featured here, please send a pr.

* [faq: zef ecosystem](https://deathbyperl6.com/faq-zef-ecosystem/)
* [fez|zef - a raku ecosystem and auth](https://deathbyperl6.com/fez-zef-a-raku-ecosystem-and-auth/)

## license

[![](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)

## authors

@[tony-o](https://github.com/tony-o)

@[patrickbr](https://github.com/patrickbkr)

@[JJ](https://github.com/JJ)

@[melezhik](https://github.com/melezhik)


## dist_cpan-SAMGWISE-Lazy-Static.md
[![Build Status](https://travis-ci.org/samgwise/Lazy-Static.svg?branch=master)](https://travis-ci.org/samgwise/Lazy-Static)

# NAME

Lazy::Static - Lazy calculation of static values

# SYNOPSIS

```
use Lazy::Static;

# Something for our lazy static closure to pick from
my @options = <foo bar baz>;

my &result = lazy-static -> {
    sleep 2; # Some long running calculation;
    @options.pick
}

# It's thread safe
my @threads = start {
    say result; # This will be the same value, since the generator will only be called once.
} for 1..16;

say "Awaiting execution of lazy-static generator...";
await Promise.allof: @threads;

say '-' x 78;

# We can call it without the wait now, since now the result has been calculated
say result;

```

# DESCRIPTION

Lazy::Static is a thread-safe alternative to the the `state` keyword for working with static values.

# AUTHOR

Sam Gillespie [samgwise@gmail.com](mailto:samgwise@gmail.com)

# COPYRIGHT AND LICENSE

Copyright 2019 (c) Sam Gillespie

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

### sub lazy-static

```
sub lazy-static(
    &generator
) returns Mu

```

Creates a closure which lazily returns the result of the generator provided. The generator Callable is executed the first time the closure is called and all calls afterwards will receive the the value from the first call. If the result of the generator is never required it will never be generated. A value generated in a lazy-static closure will persist until it is garbage collected, like a normal scalar.


## dist_github-CurtTilmes-DBI-Async.md
# NAME

DBI::Async - Tiny async wrapper around DBIish

# SYNOPSIS

```
use DBI::Async;

# Pass any DBIish.connect() options
# connections defaults to 5

my $db = DBI::Async.new('Pg', connections => 5);

# Make blocking requests:

my $result = $db.query("select version()");
say $result.row[0];
$result.finish;

# Use array() instead of row() to auto-finish the results:

say $db.query("select version()").array[0];  # array() auto-finishes

# Use :async to immediately get a Promise:

my $promise = $db.query("select version()", :async);

await $promise.then(-> $p
{
    say $p.result.array[0];
});

# Or even start a bunch of background queries in parallel,
# then check the results

await do for 1..10
{
    start {
        say "starting $_";
        say "Done #", $db.query("select pg_sleep(1)::text, ?::int as val",
                                $_).array[1];
    }
}

# same

await do for 1..10
{
    say "starting $_";
    $db.query("select pg_sleep(1)::text, ?::int as val", $_, :async).then(
              -> $p { say "Done #", $p.result.array[1] });
}

$db.dispose; # Drop all queued handles

```

# DESCRIPTION

This is deprecated in favor of DB::Pg.

`DBI::Async` is an experimental wrapper around DBIish that does all the heavy lifting. It manages a pool of connections and as queries are issued, it queues them and allocates them to a connection, gets the results and returns them asynchronously. You can issue queries from multiple threads without worrying about managing connections. It also wraps some of the mechanics of dealing with results.

Passes all arguments to DBI::Async.new() through to DBIish.connect() except connections.

```
my $db = DBI::Async.new('Pg', connections => 5);

```

Connections constrains the object from creating more than $connections database handles.

Each call to query() queues the database query for the query scheduler.

To process each query, it will use a free database handle from the handle pool. It will create up to $connections new handles. If no handles are available, it wait until another query completes and returns a handle.

query() returns a DBI::Async::Results object. It supports the basic methods from DBIish statement handles:

```
.column-names()  # Array of column names
.column-types()  # Array of column types
.rows()          # Count of rows returns
.row()           # Get a single row, call repeatedly to get all
.allrows()       # Lazy list of all rows suitable for iteration

```

It has a special version of .finish() that returns the database handle to the pool to be reused by other queries. If you access your results with the methods above, you must explicitly call .finish() to return the handle. (Otherwise they will leak and not be available for use until the garbage collector gets around to reaping them.)

```
my $result = $db.query("select version()");
say $result.row[0];
$result.finish;

```

To make this a little easier for common cases, the Results object has some extra methods that automatically grab the results and finish() for you.

```
.array()     # Return a single row as an array
.hash()      # Return a single row as a hash
.arrays()    # Eagerly get all rows and return as an array of arrays
.flatarray() # Flatten all elements of all rows into a single array
.hashes()    # Eagerly get all rows and return as an array of hashes

```

If and only if you use those methods to get results, the finish() will be automatically called.

```
say $db.query("select version()").array[0];

```

If you do want to use, e.g. .allrows() to process your results, the LEAVE phaser or corresponding 'will leave' trait, can help assure that the .finish() gets called, even if the processing code throws an exception.

These are identical:

```
{
    my $res = $db.query(blah blah);
    LEAVE $res.finish;
    while $res.allrows -> $r {
       ...do something...
    }
}

```

or

```
{
    my $res will leave { .finish } = $db.query(blah blah);
    while $res.allrows -> $r {
       ...do something...
    }
}

```

## PROMISES

If you include the :async adverb in a call to query(), instead of waiting for the result, a Promise will be returned that will be kept when the results of the database query are available.

```
my $promise = $db.query("select version()", :async);

await $promise.then(-> $p
{
    say $p.result.array[0];
});

```

You can have more outstanding queries than you have database connections available. The additional queries will queue up and get executed once previous queries complete and their results are processed.

```
my $db = DBI::Async.new('Pg', connections => 10);

await do for 1..100
{
    say "starting $_";
    $db.query("select pg_sleep(1)::text, ?::int as val", $_, :async).then(
              -> $p { say "Done #", $p.result.array[1] });
}

```

This allocates 10 database handles, then processes the 100 queries in parallel, 10 at a time. Since the results are processed with array(), the handles are returned to the pool immediately when the result is returned.

Make sure you don't take up too many waiting threads without leaving enough open threads to get work done and return handles for the rest of the waiting queries. You may be able to get around this by increasing $RAKUDO\_MAX\_THREADS. Also see: <https://github.com/rakudo/rakudo/pull/1004>

## RETRIES

DBI::Async aggressively tries to open a database connection. If the connection can't be made immediately, it will sleep a while and try again, 1 second, then 2 seconds, then 3 seconds... up to 60 seconds, finally trying to open the database connection every 60 seconds. This happens both on inital database handle creation, or on subsequent reuse of an existing handle where the connection is dropped.

# COPYRIGHT

Copyright © 2017 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S.Code. All Other Rights Reserved.


## dist_zef-lizmat-Ecosystem-Archive-Update.md
[![Actions Status](https://github.com/lizmat/Ecosystem-Archive-Update/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/Ecosystem-Archive-Update/actions) [![Actions Status](https://github.com/lizmat/Ecosystem-Archive-Update/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/Ecosystem-Archive-Update/actions)

# NAME

Ecosystem::Archive::Update - Updating the Raku Ecosystem Archive

# SYNOPSIS

```
use Ecosystem::Archive::Update;

my $ea = Ecosystem::Archive::Update.new(
  shelves     => 'archive',
  jsons       => 'meta',
);

say "Archive has $ea.meta.elems() identities:";
.say for $ea.meta.keys.sort;

```

# DESCRIPTION

Ecosystem::Archive::Update provides the basic logic to updating the Raku Ecosystem Archive, a place where (almost) every distribution ever available in the Raku Ecosystem, can be obtained even after it has been removed (specifically in the case of the old ecosystem master list and the distributions kept on CPAN).

## ARGUMENTS

* shelves

The name (or an `IO` object) of a directory in which to place distributions. This is usually a symlink to the "archive" directory of the actual [Raku Ecosystem Archive repository](https://github.com/lizmat/REA). The default is 'archive', aka the 'archive' subdirectory from the current directory.

* jsons

The name (or an `IO` object) of a directory in which to store `META6.json` files as downloaded. This is usually a symlink to the "meta" directory of the actual [Raku Ecosystem Archive repository](https://github.com/lizmat/REA). The default is 'meta', aka the 'meta' subdirectory from the current directory.

* degree

The number of CPU cores that may be used for parallel processing. Defaults to the **half** number of `Kernel.cpu-cores`.

* batch

The number of objects to be processed in parallel per batch. Defaults to **64**.

# METHODS

## batch

```
say "Processing with batches of $ea.batch() objects in parallel";

```

The number of objects per batch that will be used in parallel processing.

## clear-notes

```
my @cleared = $ea.clear-notes;
say "All notes have been cleared";

```

Returns the `notes` of the object as a `List`, and removes them from the object.

## degree

```
say "Using $ea.degree() CPUs";

```

The number of CPU cores that will be used in parallel processing.

## investigate-repo

```
my @found = $ea.investigate-repo($url, "lizmat");

```

Performs a `git clone` on the given URL, scans the repo for changes in the `META6.json` file that would change the version, and downloads and saves a tar-file of the repository (and the associated META information in `git-meta`) at that state of the repository.

The second positional parameter indicates the default `auth` value to be applied to any JSON information, if no `auth` value is found or it is invalid.

Only `Github` and `Gitlab` URLs are currently supported.

Returns a list of `Pair`s of the distributions that were added, with the identity as the key, and the META information hash as the value.

Updates the `.meta` information in a thread-safe manner.

## jsons

```
indir $ea.jsons, {
    my $jsons = (shell 'ls */*', :out).out.lines.elems;
    say "$jsons different distributions";
}

```

The `IO` object of the directory in which the JSON meta files are being stored. For instance the `IRC::Client` distribution:

```
meta
  |- ...
  |- I
     |- ...
     |- IRC::Client
         |- IRC::Client:ver<1.001001>:auth<github:zoffixznet>.json
         |- IRC::Client:ver<1.002001>:auth<github:zoffixznet>.json
         |- ...
         |- IRC::Client:ver<3.007010>:auth<github:zoffixznet>.json
         |- IRC::Client:ver<3.007011>:auth<cpan:ELIZABETH>.json
         |- IRC::Client:ver<3.009990>:auth<cpan:ELIZABETH>.json
     |- ...
  |- ...

```

## identities

```
say "Archive has $ea.identities.elems() identities, they are:";
.say for $ea.identities.keys.sort;

```

Returns a hash of all of the META information of all distributions, keyed by identity (for example "Module::Name:ver<0.1>:authfoo:bar:api<1>"). The value is a hash obtained from the distribution's meta data.

## meta-as-json

```
say $ea.meta-as-json;  # at least 3MB of text

```

Returns the JSON of all the currently known meta-information. The JSON is ordered by identity in the top level array.

## note

```
$ea.note("something's wrong");

```

Add a note to the `notes` of the object.

## notes

```
say "Found $ea.notes.elems() notes:";
.say for $ea.notes;

```

Returns the `notes` of the object as a `List`.

## shelves

```
indir $ea.shelves, {
    my $distro-names = (shell 'ls */*/*', :out).out.lines.elems;
    say "$distro-names different distributions in archive";
}

```

The `IO` object of the directory where distributions are being stored in a subdirectory by the name of the module in the distribution. For instance the `silently` distribution:

```
archive
 |- ...
 |- S
    |- ...
    |- silently
        |- silently:ver<0.0.1>:auth<cpan:ELIZABETH>.tar.gz
        |- silently:ver<0.0.2>:auth<cpan:ELIZABETH>.tar.gz
        |- silently:ver<0.0.3>:auth<cpan:ELIZABETH>.tar.gz
        |- silently:ver<0.0.4>:auth<zef:lizmat>.tar.gz
    |- ...
 |- ...

```

Note that a subdirectory will contain **all** distributions of the name, regardless of version, authority or API value.

## update

```
my %updated = $ea.update;

```

Updates all the meta-information and downloads any new distributions. Returns a hash with the identities and the meta info of any distributions that were not seen before. Also updates the `.identities` information in a thread-safe manner.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/Ecosystem-Archive-Update> . Comments and Pull Requests are welcome.

If you like this module, or what I’m doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2021, 2022, 2023, 2024 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-dwarring-PDF-Content.md
[[Raku PDF Project]](https://pdf-raku.github.io)
/ [PDF::Content](https://pdf-raku.github.io/PDF-Content-raku)

[![Actions Status](https://github.com/pdf-raku/PDF-Content-raku/workflows/test/badge.svg)](https://github.com/pdf-raku/PDF-Content-raku/actions)

# PDF::Content

This Raku module is a library of roles, modules and classes for basic PDF content creation and rendering, including text, images, basic colors, core fonts, marked content and general graphics.

It is centered around implementing a graphics state machine and provding support for the operators and graphics variables
as listed in the [PDF::API6 Graphics Documentation](https://pdf-raku.github.io/PDF-API6#appendix-i-graphics).

## Key classes and modules:

* [PDF::Content](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content) manages content stream graphics and related resources
* [PDF::Content::Canvas](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Canvas) manages a canvas that contains a content stream
* [PDF::Content::Ops](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Ops) implements a content stream as a graphics state machine
* [PDF::Content::Image](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Image) loading and manipulation of PDF images
* [PDF::Content::Font::CoreFont](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Font/CoreFont) provides simple support for core fonts
* [PDF::Content::Text::Box](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Text/Box) a utility class for creating boxed text content for output by `print()` or `say()`
* [PDF::Content::Text::Style](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Text/Style) text styling class for text boxes.
* [PDF::Content::Text::Line](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Text/Line) an individual text box line.
* [PDF::Content::Color](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Color) A module of color construction functions
* [PDF::Content::Tag](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Tag) Tagged content detection and construction
* [PDF::Content::PageTree](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/PageTree) PDF Page-tree related methods

## See Also

* [PDF::Font::Loader](https://pdf-raku.github.io/PDF-Font-Loader-raku) provides the ability to load and embed Type-1, True-Type and Open-Type fonts.
* [PDF::Lite](https://pdf-raku.github.io/PDF-Lite-raku) minimal creation and manipulation of PDF documents. Built directly from PDF and this module.
* [PDF::API6](https://pdf-raku.github.io/PDF-API6) PDF manipulation library. Uses this module. Adds handling of outlines, options annotations, separations and device-n colors
* [PDF::Tags](https://pdf-raku.github.io/PDF-Tags-raku) DOM-like creation and reading of tagged PDF structure (under construction)


## dist_zef-lizmat-OneSeq.md
[![Actions Status](https://github.com/lizmat/OneSeq/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/OneSeq/actions) [![Actions Status](https://github.com/lizmat/OneSeq/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/OneSeq/actions) [![Actions Status](https://github.com/lizmat/OneSeq/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/OneSeq/actions)

# NAME

OneSeq - turn two or more Iterables into a single Seq

# SYNOPSIS

```
use OneSeq;

my @a = ^5;
my @b = <a b c d e>;
my @c = @a >>> @b;
say @c;  # [0 1 2 3 4 a b c d e]

my @d = @a <<< @b;
say @d;  # [e d c b a 4 3 2 1 0]

# as a meta-op
my %h = a => [0,1,2], b => [3,4,5], c => [6,7,8,9];
my @e;
@e[$_] = $_ + 1 for [>>>] %h.values;
say @e;  # [1 2 3 4 5 6 7 8 9 10]

```

# DESCRIPTION

The `OneSeq` distribution provides two infix operators: `>>>` and `<<<`, each of which produces a single `Seq` object from the given arguments.

Their functionality is similar to the [`flat`](https://docs.raku.org/routine/flat) method, but with the important distinction that it does **NOT** look at the containerization of the arguments. So any iterable such as a `Array` or `List` inside a `Hash` or an `Array`, **will** produce all of its values.

And it also does **NOT** recurse into any `Iterable` values that it encounters, so in that aspect it is **NOT** like `flat` at all.

## infix >>>

The infix `>>>` operator takes any number of arguments (usually `Iterable` objects), takes the **first** argument and calls the `.iterator` method on it, then then produces the values for that iterator until exhausted, and then switches to the next argument. Until there are no arguments left.

## infix <<<

The infix `<<<` operator takes any number of arguments (usually `Iterable` objects), takes the **last** argument and calls the `.iterator` method on it, then then produces the values for that iterator until exhausted **in reverse order**, and then switches to the previous argument. Until there are no arguments left.

## PERFORMANCE

Depending on the situation, the use of these infix operators can be anywhere to 1.5x to 3x as fast as the equivalent code using `.flat`.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/OneSeq> . Comments and Pull Requests are welcome.

If you like this module, or what I'm doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2024, 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-tbrowder-PDF-Document.md
[![Actions Status](https://github.com/tbrowder/PDF-Document/actions/workflows/linux.yml/badge.svg)](https://github.com/tbrowder/PDF-Document/actions) [![Actions Status](https://github.com/tbrowder/PDF-Document/actions/workflows/macos.yml/badge.svg)](https://github.com/tbrowder/PDF-Document/actions) [![Actions Status](https://github.com/tbrowder/PDF-Document/actions/workflows/windows.yml/badge.svg)](https://github.com/tbrowder/PDF-Document/actions)

# WARNING - A WORK IN PROGRESS - EXPECT CHANGES

# NAME

**PDF::Document** - Provides high-level classes and routines to create original documents in Portable Document Format (PDF)

This module is currently functioning as a laboratory to create routines and classes to support other PDF modules. As such, its API is subject to change until version 1.0.0+.

In the meantime, users are encouraged to use it, report issues, and submit feature requests.

See the `dev` directory in the source repository for examples of use. The example in the **SYNOPSIS** is program `./dev/make-example-doc.raku`.

# SYNOPSIS

```
#!/usr/bin/env raku
use PDF::Document;

# We change only three of the many defaults for this
# example: (1) output file name, (2) force option to
# allow overwriting that file if it exists, and (3)
# turn page numbering on:
my \d = Doc.new: :pdf-name<example-letter>, :force, :page-numbering, :$debug;

#=========== THE LETTER =================
# starts with a new page, current position top baseline, left margin

# put the date at the top-right corner
d.print: "2021-03-04", :tr, :align<right>, :valign<top>;
d.nl; # adds the newline, resets x to left margin, moves y down one line

d.say: "Dear Mom,"; # SHOULD automatically add a newline
d.nl: 1; # moves y down one line, resets x=0 (left margin)
d.say: "I am fine.";
d.nl: 1;
d.say: "How are you?";

# simple graphics: circle, etc.
d.nl: 30;
d.say: "circle: radius = 36 pts, linewidth = 4 points";
d.save; # save the current position and graphics state
d.setlinewidth: 4; # points
d.circle: :x<5in>, :y<3in>, :radius(36); # default points (or in, cm)
d.restore; # don't forget to go back to normal!

d.np; # new page, current position top baseline, left margin
d.say: q:to/PARA/;
Pretend this is a VERY long para
that extends at least more than one line length in the
current font so we can observe the effect of  paragraph
wrapping. Isn't this swell!
PARA

d.nl: 3;

d.say: "Thats all, folks, but see following pages for other bells and whistles!";
d.nl: 2;
d.say: "Love,";
d.nl: 2;
d.say: "Isaiah";

d.np; # for some graphics examples

d.say: "ellipse: a = 1 in, b = 0.5 in", :y<8in>;
d.ellipse: :x<5in>, :y<8in>, :a<1in>, :b<.5in>;

d.say: "ellipse: a = 0.3 in, b = 2 cm", :y<6in>;
d.ellipse: :x<5in>, :y<6in>, :a<.3in>, :b<2cm>;

d.say: "circle: radius = 24 mm", :y<4in>;
d.circle: :x<5in>, :y<4in>, :radius<24mm>;

d.say: "rectangle: width = 2 in, height = 2 cm", :y<2in>;
d.rectangle: :llx<5in>, :lly<2in>, :width<2in>, :height<2cm>;

d.np; # for some more graphics examples

d.say: "polyline:", :y<7.5in>;
my @pts = 1*i2p, 7*i2p, 4*i2p, 6.5*i2p, 3*i2p, 5*i2p;
d.polyline: @pts;

d.say: "blue polygon:", :y<4.5in>;
@pts = 1*i2p, 4*i2p, 4*i2p, 3.5*i2p, 3*i2p, 2*i2p;
d.polygon: @pts, :fill, :color[0,0,1]; # rgb, 0-1 values

d.end-doc; # renders the pdf and saves the output
          # also numbers the pages if you requested it
#=========== END THE LETTER =================

```

# DESCRIPTION

Module `PDF::Document` leverages the power of lower-level modules `PDF::Lite`, `FontFactory`, and `FontFactory::Type1` and encapsulates some of its classes, routines, and variables into higher-level contructs to ease PDF document creation.

## PDF document generation process

This module is designed around the document generation process used by those who use PostScript (PS) code to create PS documents which are then transformed into PDF by the GNU program `ps2pdf`. That process is described in great detail in the classic PS books by Adobe (see REFERENCES).

The same sequence is also followed in the PDF document creation process:

* Define the `PDF::Lite` class instance (a heavy-weight instantiation, only one per document)

  ```
  my $pdf = PDF::Lite;

  ```
* Select the fonts (with size) to be used with either (1) the `FontFactory` or (2) the `FontFactory::Type1` or both. The advantage of (1) is the fonts are usually TrueType or OpenType with large numbers of Unicode glyphs. Any Type 1 fonts ('.t1') available may have more glyphs available than the fonts in (2). (There are 72 PS points per inch.)

  ```
  my $ff    = FontFactory.new;
  my $fft   = FontFactory::Type1.new: # uses PDF::Lite to access standard fonts
  my $t12d1 = $fft.get-font: 't12d1'  # Times-Roman at 12.1 points
  my $c10   = $fft.get-font: 'c10';   # Courier at 10 points
  my $ft1   = $ff.get-font: :name(), :size();
  my $ft2   = $ff.get-font: :index(), :size();

  ```
* Define each page

  ```
  my $page = $pdf.add-page;
  #...add text and graphics...
  #...add a new page...
  my $page = $pdf.add-page;
  #...add text and graphics...

  ```
* Create the document and exit

  ```
  $pdf.save-as<MyDoc.pdf>;

  ```

## Summary

As you can see the document steps are equivalent, but the steps in PDF page creation are much easier because common low-level code required in PS creation is available under the covers in `PDF::Lite` and accessed more easily by this module.

# CURRENT CAPABILITY

Currently the the module provides routines and constants as used in the example program shown in the **SYNOPSIS**. In addition, other graphics and text examples are shown in the `/dev` directory including showing phases of the Moon, creating grids, using landscape orientation, and using A4 paper.

There is also a font factory which eases selection and use of multiple fonts. Fonts included are all the standard PostScript fonts plus a font used to create bank checks: **MICREncoding**. The PS fonts are free for any use, but the MICR font is only free for non-commercial use. See its **license.txt** file in the `/dev/fonts/micr/unzipped` directory.

More work is planned including:

* font underlining
* font strikethrough

# FUTURE CAPABILITY

This module is being used during the development of the author's other PDF modules:

* `PDF::Writer`\*
* `PDF::Labelmaker`\*\*
* `PDF::Calendar`
* `PDF::ReWriter`
* `PDF::Forms`
* `CheckWriter`

This module will be updated with more items as the user modules are updated and published.

NOTE: The asterisk (`*`) indicates the module has been published, albeit of minimal use. Two asterisks means the published module is not even minimally useful, but it is exposed to issues or feature requests from interested parties.

# CREDITS

The author is indebted to the tremendous amount of work done by his Raku friend, David Warring. David's voluminous project, hosted at <https://github.com/PDF-Raku>, provides all the tools needed to manipulate PDF files using our wonderful Raku language. Thank you David!

# REFERENCES

##### 1. *PostScript Language Reference Manual* (the "Red Book"), 2nd Edition, Adobe Systems Inc., 1990

##### 2. *PostScript Language Tutorial and Cookbook* (the "Blue Book"), Adobe Systems Inc., 1986

# AUTHOR

Tom Browder [tbrowder@acm.org](mailto:tbrowder@acm.org)

# COPYRIGHT and LICENSE

Copyright © 2021-2023 Tom Browder

This library is free software; you may redistribute it or modify it under the Artistic License 2.0.


## dist_zef-guifa-Intl-Format-DateTime.md
# IntlFormatDateTime

> Hoy es siempre todavía, toda la vida es ahora. Y ahora, ahora es el momento de cumplir las promesas que nos hicimos. Porque ayer no lo hicimos, porque mañana es tarde. Ahora.
> — *Proverbios y cantares* (Antonio Machado)

A module for formatting dates and times in a variety of languages and styles. To use, simple include the module:

```
use Intl::Format::DateTime

my $dt = DateTime.new: now;

format-date $dt;      # Format the date only
format-time $dt;      # Format the time only
format-datetime $dt;  # Format the date and time together

```

The command options are

* **`:length`**
  The main option, sets the length. Acceptable values are either *full*, *long*, *medium* (default), *short*. For the most verbose, choose *wide*. Defaults to *medium* which should be optimal in most cases.
* **`:skeleton`** (alias **`:like`**)
  Accepts a string representing various formatting options documented in [TR 35.4.8](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table). The optimal pattern is chosen based on the given skeleton, deferring to the skeleton for minor differences (e.g. number of digits). If used, **length** option is ignored.
* **`:language`**
  Sets the language to be used in formatting. Acceptable values are a `LanguageTag` or a `Str` representation thereof. Defaults to whatever `User::Language` provides, which itself defaults to `en` (English).
* **`:relative-to`**
  **NYI**. This option will create a relative time offset based on the the interval. Generally `:relative-to(now)` is what you will want to use, but you can use anything that can coerce to a DateTime.

If you will be constantly reusing a formatter, you can also obtain a `Callable` form which will reduce some of the overhead and be more performant:

```
my &formatter =    local-datetime-formatter :$language, :$length, :$skeleton;
              # or local-date-formatter
              # or local-time-formatter

formatter DateTime.now

```

Current performance is about an order of magnitude slower than `DateTime.Str` and is about as fast as vanilla Raku can get.
The performance gap can be narrowed if alternate `nqp` versions of formatters are written, but that is not a priority at the moment.

## To do

* Finish skeleton patterns support (allowing selection of more specific formats).
* Respect capitalization rules per CLDR casing data.
* Handle non-Gregorian calendars (once a `DateTime::Calendars` module or similar is available)
* Handle relative time formats (though this may ultimately go into a separate module).

## Dependencies

* `Intl::LanguageTag`
  Used for introspection of language tags.
* `Intl::UserLanguage`
  Determines the default language for formatting).
* `Intl::CLDR`
  Contains formatting information.
* `DateTime::Timezones`
  Ensures that `DateTime` objects are timezone aware.

These modules are designed to work together, and as of 2023, are maintained by the same person so should not have issues if fully updated.

## Version history

* **v0.3.0**
  * All code now runs with RakuAST for improved performance
  * Added `local-datetime-formatter` calls for enhanced performance in some situations
  * Proper week-of-year/weekyear support
  * Non-Latin digit support
  * Restructured file hierarchy for better long term maintenance
* **v0.2.0**
  * Skeleton formats supported for `format-datetime` (NYI: missing fields and C/j/J formatters NYI)
* **v0.1**
  * Initial release

## Copyright and License

© 2021–2023 Matthew Stephen Stuckwisch. All files licensed under the Artistic License 2.0 except for `resources/metaZones.xml` which is owned by Unicode, Inc. and licensed under the Unicode License Agreement (found at `resources/unicode-license.txt`)


## excludes-max.md
excludes-max

Combined from primary sources listed below.

# [In Range](#___top "go to top of document")[§](#(Range)_method_excludes-max "direct link")

See primary documentation
[in context](/type/Range#method_excludes-max)
for **method excludes-max**.

```raku
method excludes-max(Range:D: --> Bool:D)
```

Returns `True` if the end point is excluded from the range, and `False` otherwise.

```raku
say (1..5).excludes-max;                          # OUTPUT: «False␤»
say (1^..^5).excludes-max;                        # OUTPUT: «True␤»
```


## dist_zef-Kaiepi-Data-Record.md
![Build Status](https://github.com/Kaiepi/ra-Data-Record/actions/workflows/test.yml/badge.svg)

# NAME

Data::Record - Record types!

# SYNOPSIS

```
use Data::Record;

# Data::Record introduces record types for maps, lists, and tuples:
my constant Schema = {@
    name  => Str:D,
    items => [@ <@ Int:D, Str:D @> @]
@} :name('Schema');

# With the type we just made, we can typecheck data structures to ensure they
# match it:
my %valid =
    name  => 'Kaiepi',
    items => [(1, 'Item 1'), (2, 'Item 2')];
my %invalid =
    name        => 'Mrofnet',
    items       => [],
    constructor => 'Thanks, JavaScript.';
say %valid ~~ Schema;   # OUTPUT: True
say %invalid ~~ Schema; # OUTPUT: False

# ...but typechecking this way is inefficient, and is always done eagerly!
# Using the (<<), (>>), (<>), and (><) operators provided, data can be coerced
# to our record type by various means:
%valid   := %valid (><) Schema;
%invalid := %invalid (<<) Schema;
say %invalid; # OUTPUT: {items => [], name => Mrofnet}

# For the most part, coerced data can be used the same way as the original
# data, with the bonus of extra typechecking:
{
    CATCH { default { say .^name } }
    %invalid<items>.push: (3, 'Item 3');        # OK!
    %invalid<items>.push: "OOPSIE WOOPSIE OwO"; # OUTPUT: X::Data::Record::TypeCheck
}

# Finally, to restore the data's original typing, simply call the unrecord
# method on it:
my %now-valid := %invalid.unrecord;
say %now-valid.^name;           # OUTPUT: Hash
say %now-valid<items>.^name;    # OUTPUT: Array
say %now-valid<items>[0].^name; # OUTPUT: List

```

# DESCRIPTION

`Data::Record` is a library that adds support for record types to Raku. Operators for creating record types for maps, lists, and tuples are included. Data structures can then be coerced to these record types using the coercion operators provided, some of which will sanitize them, all of which allow for efficient typechecking for common operations you can do with them.

For documentation on how this library can be used, refer to the [wiki](https://github.com/Kaiepi/p6-Data-Record/wiki/).

# AUTHOR

Ben Davies (Kaiepi)

# COPYRIGHT AND LICENSE

Copyright 2022 Ben Davies

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-bbkr-HomoGlypher.md
# Homoglyph toolset for [Raku](https://www.raku.org) language

[![.github/workflows/test.yml](https://github.com/bbkr/HomoGlypher/actions/workflows/test.yml/badge.svg)](https://github.com/bbkr/HomoGlypher/actions/workflows/test.yml)

[Homoglyph](https://en.wikipedia.org/wiki/Homoglyph) is set of one or more graphemes that has identical or very similar look to some other set of graphemes.

For example:

* `6` (DIGIT SIX) and `б` (CYRILLIC SMALL LETTER BE)
* `w` (LATIN SMALL LETTER W) and `ω` (GREEK SMALL LETTER OMEGA)
* `oo` (2 x LATIN SMALL LETTER O) and `က` (MYANMAR LETTER KA)
* `E` (LATIN CAPITAL LETTER E) and `Ε` (GREEK CAPITAL LETTER EPSILON) and `Е` (CYRILLIC CAPITAL LETTER IE)
* `V` (LATIN CAPITAL LETTER V) and `\/` (REVERSE SOLIDUS + SOLIDUS)

Homoglyphs are:

* Font dependent - two homoglyphs may be 100% identical in one font but have visual differences when rendered in other. Even cursive matters, for example `т` in cursive in some fonts looks like `m`.
* Subjective - similarity level cannot be measured and there is no fixed point where two sets of graphemes stops being homoglyphs. Are `a` and `а` homoglyphs? Sure! How about `ź` and `ž`? Probably yes. What will you say about `R` and `Я`? Er.... You see the point?
* Funny - replace `;` (SEMICOLON) with `;` (GREEK QUESTION MARK) in someone's code and watch them trying to debug code that looks perfectly fine :)
* Dangerous - someone can register [IDN domain](https://en.wikipedia.org/wiki/Internationalized_domain_name) that looks very similar to your business domain to swindle money out of your clients.

# TABLE OF CONTENTS

* [SYNOPSIS](#synopsis)
* [HINT](#hint)
* [METHODS](#methods)
  * [add-mapping](#add-mapping)
  * [unwind](#unwind)
  * [collapse](#collapse)
  * [tokenize](#tokenize)
  * [randomize](#randomize)
* [CONTACT](#contact)

# SYNOPSIS

```
use HomoGlypher;

my %cyrillic = (
    '6' => [ 'б' ],
    'a' => [ 'а' ],
    'b' => [ 'б', 'ь' ],
    'r' => [ 'г' ]
);

my %greek = (
    'a' => [ 'α' ],
    'o' => [ 'ο' ]
);

my %myanmar = (
    'oo' => [ 'က' ]
);

my $hg = HomoGlypher.new;

$hg.add-mapping( %cyrillic );
$hg.add-mapping( %greek );
$hg.add-mapping( %myanmar );

my @unwinded = $hg.unwind( 'foo' );    # [ 'foο', 'fοo', 'fοο', 'fက' ]

my @collapsed = $hg.collapse( 'бαг' ); # [ 'bar', '6ar' ]

my $randomized = $hg.randomize( 'bar', level => 80 ); # for example 'bαr'

my &tokenized = $hg.tokenize( );
say so 'bαг' ~~ / <&tokenized: 'bar'> /; # True

```

# HINT

When dealing with homoglyphs the easiest method to debug them is to use uniname(s) method:

```
$ raku -e '.say for "fοο".uninames'

LATIN SMALL LETTER F
GREEK SMALL LETTER OMICRON
GREEK SMALL LETTER OMICRON

```

# METHODS

## add-mapping

Merge given mapping (given as Hash of Arrays) with existed mappings.

Typically keys are composed from ASCII characters.
Duplicates are filtered out automatically.
Multi character glyphs can be used both in keys and values:

```
my %mapping = (
    'IO' => [ 'Ю' ],
    'P' => [ '|Ͻ']
);

```

You can inspect megred mappings under `$hg.mappings`, just ***do not modify it directly***.
If you want to fine tune it then fetch merged result, tweak it and add to new `HomoGlypher` object.

Few ready to use mappings are provided in [HomoGlypher::Mappings](https://github.com/bbkr/HomoGlypher/blob/master/lib/HomoGlypher/Mappings.rakumod):

* `@basic` - ASCII letters and digits that are faked by completely different characters: `ΤꜦꜪ QՍΙᴄк вᚱՕꓪɴ ꓝᏅХ` `jսოр𐑈 օ𐐷еᎱ tᏥе ιαzႸ Ժօց` `ОᛐշʒᏎƼỼ7ꝸᏭ`. Consists of:
  * `%armenian`
  * `%cherokee`
  * `%cyrillic`
  * `%deseret`
  * `%greek`
  * `%greek-mathematical-typeface`
  * `%georgian`
  * `%latin`
  * `%lisu`
  * `%myanmar`
  * `%roman-numerals`
  * `%runic`
  * `%math-symbols`
* `@typeface` - ASCII letters and digits that have typeface styles applied, base characters are not changed: `𝗧𝕳𝓔 𝒬𝕌𝕀𝙲𝔎 𝔹𝗥ＯＷ𝓝 𝘍𝕆𝗫` `𝒿𝓾𝗺𝚙𝕤 𝔬𝘃𝘦𝓇 𝔱𝘩𝘦 𝖑𝖆𝕫𝔂 𝗱𝓸𝔤` `𝟘𝟙２𝟹４𝟻𝟼𝟽𝟠𝟡`. Consists of:
  * `%ballot`
  * `%ballot-bold-script`
  * `%ballot-script`
  * `%bold`
  * `%bold-fraktur`
  * `%bold-italic`
  * `%bold-script`
  * `%doublestruck`
  * `%doublestruck-italic`
  * `%fraktur`
  * `%fullwidth`
  * `%heavy-ballot`
  * `%italic`
  * `%monospace`
  * `%sansserif`
  * `%sansserif-bold`
  * `%sansserif-bold-italic`
  * `%sansserif-italic`
  * `%script`
* `%accented` - ASCII letters that have accents applied, base characters are not changed: `ȚȞȆ ꝖṲÏÇꝂ ḂŔǾⱲṆ ḞṌẌ` `ĵữṁꝕṩ ǭⱱëȑ ʈẖḕ ļǟʐȳ ɗȫǵ`. Try to read it loud... Correctly :)
* `%control` - ASCII printable representations of non printable characters: `P␆ ␎ME ␖THE␏SE␞`. Have perfect similarity but letters are very crammed and those acronyms are unlikely to be found in regular language.
* `%flipped` - ASCII letters, digits and symbols that are faked by some completely different characters in various rotations and mirroring: `ꓕH⧢ Ꝺ⋂I𐐣ꓘ ꓭꓤOW𐐥 ꓞOX` `jᴝᴟpƨ ᴑ⋏ǝɹ ʇɥɘ ꞁɐzʎ dᴑᵷ` `0ᛚ2Ƹ4567∞9`

```
use HomoGlypher;
use HomoGlypher::Mappings;

my $hg = HomoGlypher.new;

$hg.add-mapping( $_ ) for @HomoGlypher::Mappings::basic;    # load all basic mappings
$hg.add-mapping( %HomoGlypher::Mappings::accented );        # load single, specific mapping

```

I won't tell you where to get perfect, complete, ultimate mapping because homoglyphs are font-dependent and similarity is subjective. Good start point for creating your own mappings are [\*\_alphabet](https://en.wikipedia.org/wiki/List_of_writing_systems) and [\*\_numeral](https://en.wikipedia.org/wiki/List_of_numeral_systems) pages on Wikipedia. Or you can borrow mappings from some other projects like [Codebox homoglyphs](https://github.com/codebox/homoglyph), [IronGeek Homoglyph Attack Generator](https://www.irongeek.com/homoglyph-attack-generator.php) and many others.

## unwind

Generates every possible mapping combination for your ASCII text.
Beware, ***this works only for short inputs*** and ***list grows really, really fast***.

```
my %cyrillic = (
    '6' => [ 'б' ],
    'a' => [ 'а' ],
    'b' => [ 'б', 'ь' ],
    'e' => [ 'е', 'ё' ],
    'm' => [ 'м' ],
    'p' => [ 'р' ],
    'r' => [ 'г' ],
    'x' => [ 'х' ]
);

my $hg = HomoGlypher.new;
$hg.add-mapping( %cyrillic );

.say for $hg.unwind( 'example' );

```

```
examplё
examрle
examрlе
examрlё
exaмple
exaмplе
exaмplё
exaмрle
...

```

(total 143 combinations)

Output list:

* Is lazy - so you can iterate over it without worrying about memory consumption.
* Has preserverd mappings order - so if you sort your mappings from most to less similar your result will have the same characteristics.

Main purpose of homoglyph unwinding is to check if someone is spoofing your domain.
See ready to use [IDN Checker](https://github.com/bbkr/HomoGlypher/blob/master/example/IDN-checker.raku) script.

## collapse

Opposite of [unwind](#unwind).
If you have suspicious, homoglyphed text you can check which ASCII texts it might be derived from.
Beware, ***this works only for short inputs***.

```
my %ascii-art = (
    'O' => [ '()' ],
    'V' => [ '\/' ],
    'W' => [ '\/\/' ]
);

my $hg = HomoGlypher.new;
$hg.add-mapping( %ascii-art );

.print for $hg.collapse( '\/()\/\/EL' );

```

```
VOVVEL
VOWEL

```

(as you can see sometimes it may return more than one possible ASCII text)

Main purpose of homoglyph collapsing is to check if someone is using your forums, hostings, or other services for phishing or false advertising.
Check also [tokenize](#tokenize) method.

[Unicode::Security](https://github.com/JJ/perl6-unicode-security) module does similar thing.

## tokenize

Construct token that can be used to match homoglyphed text in grammars.

```
my %greek = (
    'a' => [ 'α' ],
    'r' => [ 'Γ' ],
);

my $hg = HomoGlypher.new;
$hg.add-mapping( %greek );

my &homoglyphy = $hg.tokenize( );

'foobαΓbaz' ~~ / $<result>=<&homoglyphy: 'bar'> /;
say $/{ 'result' };

```

```
｢bαΓ｣

```

Beware, ***token uses mappings present at match time***.
You can create token without any mappings added, define grammar that uses this token and then add mappings before text is actually matched against grammar.
If you need tokens with different set of mapping in one grammar you can create and tokenize many `HomoGlypher` instances.

[Regex::FuzzyToken](https://github.com/alabamenhu/RegexFuzzyToken) module can be used to catch misspelled phrases. Homoglypher and FuzzyToken can coexist in single grammar:

```
say 'Suspicious!' if $email-text ~~ / [ <fuzzy: 'paypal'> | <&homoglyphy: 'paypal'> ] /;

```

Will catch both `papyal` (misspelled) and `pαypαl` (homoglyphed). And yes, you can throw nuke on phishers and catch misspells and homoglyphs at the same time:

```
say 'Suspicious!' if $email-text ~~ / <fuzzy: $hg.unwind('paypal')> /;

```

Will catch such sneaky phrases as `pαpyαl`.

## randomize

Replace characters in text with homoglyphs with given probability.

```
my $hg = HomoGlypher.new;
$hg.add-mapping( %HomoGlypher::Mappings::flipped );

say $hg.randomize( 'DIRECTIONS & CAKE ARE A LIE', level => 100 );

```

```
⫏Iя∃C⟘IOИƧ ⅋ C∀K⧢ ∀Я∃ ∀ LI∃

```

Level can be given as percentage value from 1 to 100 (default 50). It decides if ***possible*** mapping should be used at given position. Do not confuse that with amount of replaced characters. For example you have mapping `'a' => [ 'α' ]` and level set to 50%. Transforming `barrrr` will result with unmodified `barrrr` with 50% probability (at second position transformation was possible but not used) and modified `bαrrrr` with 50% probability (at second position transformation was possible and used). Each position is rolled individually against level. Each possible replacement glyph has equal chance to be picked.

[Text::Homoglyph](https://github.com/MattOates/Text--Homoglyph) module does similar thing.


## dist_zef-grizzlysmit-File-Utils.md
# File::Utils

## Table of Contents

* [NAME](#name)
* [AUTHOR](#author)
* [VERSION](#version)
* [TITLE](#title)
* [SUBTITLE](#subtitle)
* [COPYRIGHT](#copyright)
* [Introduction](#introduction)
* [CorruptFile](#corruptfile)
* [symbolic-perms(…)](#symbolic-perms)
* [format-bytes(…)](#format-bytes)
* [uid2username(…)](#uid2username)
* [gid2groupname(…)](#gid2groupname)

# NAME

File::Utils

# AUTHOR

Francis Grizzly Smit ([grizzly@smit.id.au](mailto:grizzly@smit.id.au))

# VERSION

0.1.2

# TITLE

File::Utils

# SUBTITLE

A Raku module for converting various File system properties to symbolic form.

# COPYRIGHT

LGPL V3.0+ [LICENSE](https://github.com/grizzlysmit/File-Utils/blob/main/LICENSE)

[Top of Document](#table-of-contents)

# Introduction

A **Raku** module for converting various File system properties to symbolic form. For instance **`symbolic-perms(…)`** will give you the **.rwxr-xr-x** type representation of the file type and permissions like used by **`ls`** and **`exa`**. And **`format-bytes(…)`** will convert the file size from bytes **B** to **TiB**, **GiB** etc.

[Top of Document](#table-of-contents)

### CorruptFile

**`CorruptFile`** is an exception class to be used if a corrupt file is encountered.

```
class CorruptFile is Exception is export {
    has Str:D $.msg = 'Error: File is Corrupt';
    method message( --> Str:D) {
        $!msg;
    }
}

```

[Top of Document](#table-of-contents)

### symbolic-perms(…)

A function for producing the **.rwxrwxrwx** form of a files type and permissions like that used by **ls** and **exa**. It also supports colourising and syntax highlighting of the perms.

```
sub symbolic-perms(IO::Path $path,
                   Bool:D :$colour is copy = False,
                   Bool:D :$syntax = False,
                   Bool:D :$highlighted = False,
                   Bool:D :$cond = False,
                   Str:D :$highlight-fg-colour = t.color(255, 0, 0),
                   Str:D :$fg-colour0 = t.color(255, 0, 0),
                   Str:D :$fg-colour1 = t.color(255, 0, 0) --> Str:D) is export {

```

* Where

  * **`$path`** Is the path of the file/directory to describe the perms for.
  * **`$colour`** If True colour the perms.
  * **`$syntax`** If true syntax highlight the perms.
  * **`$highlighted`** If true set the text colour to **`$highlight-fg-colour`**.
  * **`$cond`** If not highlighted and True set the text colour to **`$fg-color0`** else set text to **`$fg-color1`**.
  * **`$highlight-fg-colour`** Colour to set the text to if **`$highlighted`**.
  * **`$fg-colour0`** Colour to set the text to if not **`$highlighted`** and **`$cond`**.
  * **`$fg-colour1`** Colour to set the text to if not **`$highlighted`** and not **`$cond`**.

**NB: Only recognises directory, link and regular file just now.**

### format-bytes(…)

Format a number in bytes into **KiB**, **MiB**, **GiB**, **TiB**, …… also appends the **GiB**, **TiB** designator.

```
sub format-bytes(Int:D $bytes, Int:D :$width = 5,
                 Int:D :$precision = 1 --> Str:D) is export

```

### uid2username(…)

A function to convert a numeric **uid** into a **username**, will only work on a typical \***nix** file system requires **/etc/passwd** to exist, and be readable. Will fail if these conditions are not true.

```
sub uid2username(UInt:D $uid --> Str:D) is export

```

### gid2groupname(…)

A function to convert a numeric **gid** into a **groupname**, will only work on a typical \***nix** file system requires **/etc/group** to exist, and be readable. Will fail if these conditions are not true.

```
sub gid2groupname(UInt:D $gid --> Str:D) is export

```


## dist_zef-thundergnat-Math-Handy.md
[![Actions Status](https://github.com/thundergnat/Math-Handy/actions/workflows/test.yml/badge.svg)](https://github.com/thundergnat/Math-Handy/actions)

# NAME

Math::Handy - Handy math routines and operators that aren't in CORE Raku.

# SYNOPSIS

```
use Math::Handy;

say 25!;  # 15511210043330985984000000

say Γ 1/2; # 1.7724538509055163

say binomial(9, 5); # 126

say Σ (^1e2).grep: &is-prime; # 1060

say Π (^1e2).grep: &is-prime; # 2305567963945518424753102147331756070

say 33 divmod 5;   # (6 3)

say 33 divmod 5.1; # (6 3)

say 33 /% 5.1;     # (6 2.5)

say adr 16781; # (5 2)

say mdr 16781; # (0 4)

say 180°; # 3.141592653589793

say 200ᵍ; # 3.141592653589793

```

# DESCRIPTION

Math::Handy provides several handy functions and operators.

### Factorial operators

`factorial (Int)` - the product of the integers from one to $n. Also available as `postfix:<!> (Int)`.

Factorial is a discrete operation, only valid at integer values. For a continuous function, you want `gamma (Real $n)`.

`gamma (Real)` is a continuous factorial function. `Γ($n) =~= ($n - 1)!`. Also available as `Γ (Real $n)` (Greek uppercase gamma). Calculated using Lanczos approximation. (Only valid for positive arguments at this point.)

Also related to `factorial()` is `binomial()`.

`binomial(Int $n, Int $p)`, very commonly appears in combinatorics. Is equivalently expressed as: `n! / (p! × (n - p)!)`.

### Arithematic operators

Raku has the very convenient `sum` function. Traditional mathematics spells it `Σ`. This module provides a `Σ (*@list)` operator to remedy that.

Another common mathematical operator that Raku left out is `product()`. Raku has the `[*]` meta reduce operator, but that is difficult to chain with other operations. This module provides both a `product (*@list)` routine, and the more traditionally spelled: `Π (*@list)` (Greek uppercase pi)

Raku has `div`, Raku has `mod`, Raku has `polymod()`, but sometimes you may want a plain old `divmod`.

`infix:<divmod> (Real, Real)` coerces arguments to Int and returns the whole divisions and the remainder.

Also available as `infix:</%> (Real, Real)`: `Real %/ Real` which doesn't coerce.

### Digital roots

The `additive digital root` of an Integer in a particular base, is the recursive sum of the digits until only a single digit remains. The `persistance` is the number of times the function needs to recurse to reach a single digit.

Provides `digital-root (Int $n, :$base = 10)`. Calculates and returns the additive digital root and the persistance, by default in base 10. Pass in a named base (2 = 36) if a different base is desired. Also available as the abbreviated `adr (Int $n, :$base = 10)`

Similar to the additive `digital-root()` is the `multiplicative-digital-root()`. The `multiplicative-digital-root (Int $n, :$base = 10)` is the recursive product of the digits until only one digit remains. Returns the multiplicative digital root and the persistance. Also available as the abbreviated `mdr (Int $n, :$base = 10)`

### Radian conversions

Raku provides a multitude of trigonometric functions, but they all work with radian angle measurements by default. To make it easy to work with degrees (360° in 2π radians), or gradians (400ᵍ in 2π radians), provides two postfix conversion routines.

`postfix:<°> (Real $degrees)` converts degree measurments to radians.

`postfix:<ᵍ> (Real $gradians)` converts gradian measurments to radians.

# AUTHOR

Most of these were code snippets I or someone else wrote as helper functions for solving RosettaCode tasks.

If there is a routine you think should be added, or if I bungled one of the existing, please let me know.

Stephen Schulze (aka thundergnat [thundergnat@comcast.net](mailto:thundergnat@comcast.net))

# COPYRIGHT AND LICENSE

Copyright 2023 thundergnat

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_cpan-CTILMES-LibGit2.md
# LibGit2 -- Direct access to Git via libgit2 library

Note:

This is a WORK IN PROGRESS. The tests are under construction and many
of them probably won't work on your computer..

This module provides Raku access to [libgit2](https://libgit2.github.com/).

That library must be installed, and this module will be subject to the
features enabled during the build/install of that library.

This module is **EXPERIMENTAL**. In particular, I'm still trying to refine
the Raku API to be as friendly as possible, and also as Raku-ish as
possible. I've converted some callbacks into Channels, and some options
into :pairs, etc. If you see anything that could be done better, PLEASE
raise an issue.

There are also still some unimplemented corners, so if you see anything
you can't do, raise an issue and we can try to add more libgit2 bindings.
Also some functionality that looks like it should work doesn't seem to...
Debugging, test improvements, etc. are all appreciated -- feel free to
ask questions or offer patches!

For now, there are also some 64-bit assumptions. If there is demand for
a 32-bit version, there are ways to adapt it I can work with someone who
wants to tackle that. It also doesn't currently support Windows, but
could probably do so if someone wants to port it. Patches welcome!

## Global Initialization

Always start with `use LibGit2` rather than using individual `Git::*`
modules. That pulls in the rest of the modules, and also initializes
the library as a whole.

Query some global information about the library:

```
use LibGit2;
say LibGit2.version;
say LibGit2.features;

0.26.0
(GIT_FEATURE_NSEC GIT_FEATURE_SSH GIT_FEATURE_HTTPS GIT_FEATURE_THREADS)

```

## Tracing

If libgit2 is compiled with tracing support, you can enable that tracing
from Raku.

```
LibGit2.trace('debug');  # none,fatal,error,warn,info,debug,trace

```

The default trace callback just prints the message and its level to
STDOUT. You can also supply a callback:

```
use NativeCall;
sub my-trace($level, $message) { say "$level $message" }

LibGit2.trace('info', &my-trace);

```

## Init

```
my $repo = Git::Repository.init('/my/dir');

my $repo = Git::Repository.init('/my/dir', :bare);

my $repo = Git::Repository.init('/my/dir', :mkpath,
description => 'my description', ...);

```

See Git::Repository::InitOptions for the complete init option list.

## Clone

```
my $repo = Git::Repository.clone('https://github.com/...', '/my/dir');

my $repo = Git::Repository.clone('https://github.com/...', '/my/dir', :bare);

```

See Git::Clone::Options for the complete clone option list.

## Open

This will open an existing Git repo or throw an exception.

```
try my $repo = Git::Repository.open('/my/dir');
if not $repo {
    say "FATAL: '/my/dir' is not a Git repo.";
    exit;
}

my $repo = Git::Repository.open('/my/dir', :bare);

my $repo = Git::Repository.open('/my/dir/some/subdir', :search);

```

See Git::Repository::OpenOptions for the complete open options list.

## Config

From a `Git::Repository`, you can use the `.config` method to access
configuration information.

```
my $config = $repo.config;

```

## Status

Get status for a specific file/path:

```
my $status = $repo.status-file('afile');

say $status.status;
say $status.path;
say "new in workdir" if $status.is-workdir-new;

```

Other queries on status: is-current is-index-new is-index-modified
is-index-deleted is-index-renamed is-index-typechange is-workdir-new
is-workdir-modified is-workdir-deleted is-workdir-typechange
is-workdir-renamed is-workdir-unreadable is-ignored is-conflicted

Query for status of everything, or specific pathes/globs:

```
for $repo.status-each {
    say 'new' if .is-workdir-new;
}

say .path for $repo.status-each('*.p6', :include-untracked);

```

See `Git::Status::Options` for more information on status options.

## Index

Retrieve an object representing the repository's index with `.index`,
then you can add files to the index, either a specific file
`.add-bypath` or a group of files or all files with `.add-all`, or
just update with `.update-all`.

```
my $repo.index;
$index.add-bypath('afile.p6');  # Even works on ignored files
$index.add-all('*.p6');         # Add any new files or update any changes
$index.update-all('*.t');       # Just update, don't add new files

```

Remove from index with `.remove-bypath` or `.remove-all`.

The index is maintained in memory. To persist the changes to disk,
always `$index.write` after completeing changes. Use `.read(:force)`
to discard any changes and re-read index from disk.

See Git::Index for more information on options.

After adding new or changed files to the index, create a `Git::Tree`
representing the changes with `.write-tree` which returns a `Git::Oid`
for the new tree.

```
my $tree-id = $index.write-tree;

```

## Tree

```
my $tree = $repo.tree-lookup($tree-id);

```

## Signature

```
my $sig = $repo.signature-default;  # Fails if user.name, user.email not set
my $sig = Git::Signature('Full Name <name@address.com');
my $sig = Git::Signature('Full Name', 'name@address.com');
my $sig = Git::Signature('Full Name', 'name@address.com',
   DateTime.new('...'));

```

## Commit

A commit requires several components:

* **:update-ref** - Defaults to 'HEAD', the name of the reference that
  will be updated to point to this commit. If the reference is not
  direct, it will be resolved to a direct reference. Use "HEAD" to
  update the HEAD of the current branch and make it point to this
  commit. If the reference doesn't exist yet, it will be created. If
  it does exist, the first parent must be the tip of this branch.
* **:author** - Git::Signature of the commit author, defaults to
  $repo.signature-default.
* **:committer** - Git::Signature of the committer, defaults to the
  same as the author.
* **:messsage** - Commit message. Add **:prettify** option to prettify it.
* **:tree** -- Git::Tree of the changes to add to the commit. If not
  specified, $repo.tree-lookup($repo.index.write-tree) will be used, the
  tree of all changes to the index.
* **Git::Commit** - parents for this commit. Specify **:root** for a
  root commit with no parents. If no parents are specified, and
  **:root** is not included, the commit pointed to by 'HEAD' will be
  used as the only parent.

  $repo.commit(message => "This is my new commit.");

See ... for more information about commits.

## References

Look up references by name with:

```
 my $ref = $repo.reference-lookup('/refs/heads/master');

```

or by 'short name' (by git precedence rules) with:

```
my $ref = $repo.ref('master');

```

They return Git::Reference.

You can get list of names references:

```
.say for $repo.reference-list;

```

or a list of full references:

```
.name.say for $repo.references;  # Say each full name

refs/heads/master
refs/remotes/origin/master
refs/tags/0.1

.short.say for $repo.references;  # Say each short name

master
origin/master
0.1

```

or limit with a glob:

```
.name.say for $repo.references('refs/tags/*')

```

You can also get the Oid from a reference name:

```
my $oid = $repo.name-to-id('HEAD');

```

## Tags

## Branches

## Remotes

## Fetch

## Checkout

## Push

## Worktree

## Diff


## dist_zef-raku-community-modules-HTTP-HPACK.md
[![Actions Status](https://github.com/raku-community-modules/HTTP-HPACK/actions/workflows/linux.yml/badge.svg)](https://github.com/raku-community-modules/HTTP-HPACK/actions) [![Actions Status](https://github.com/raku-community-modules/HTTP-HPACK/actions/workflows/macos.yml/badge.svg)](https://github.com/raku-community-modules/HTTP-HPACK/actions) [![Actions Status](https://github.com/raku-community-modules/HTTP-HPACK/actions/workflows/windows.yml/badge.svg)](https://github.com/raku-community-modules/HTTP-HPACK/actions)

# NAME

HTTP::HPACK - Implementation of RFC 7541 HPACK: Header Compression for HTTP/2

# SYNOPSIS

```
use HTTP::HPACK;

# Decoding:
my $decoder = HTTP::HPACK::Decoder.new;
my @headers = $decoder.decode-headers($buf);
say "{.name}: {.value} ({.indexing})" for @headers;

# Encoding:
my @headers =
  HTTP::HPACK::Header.new(
    name  => ':method',
    value => 'GET'
  ),
  HTTP::HPACK::Header.new(
    name     => 'password',
    value    => 'correcthorsebatterystaple',
    indexing => HTTP::HPACK::Indexing::NeverIndexed
  );
my $encoder = HTTP::HPACK::Encoder.new;
my $buf = $encoder.encode-headers(@headers);

```

# DESCRIPTION

HPACK is the HTTP/2 header compression algorithm. This module implements encoding (compression) and decoding (decompression) of the HPACK format, as specified in RFC 7541. A HTTP/2 connection will typically have an instance of the decoder (to decompress incoming headers) and an instance of the encoder (to compress outgoing headers).

# Notes on specific features

## Huffman compression

Decoding of headers compressed using the Huffman codes (set out in the RFC) takes place automatically. By default, the encoder will not apply Huffman compression. To enable this, construct it with the `huffman` named argument set to `True`:

```
my $encoder = HTTP::HPACK::Encoder.new(:huffman);

```

## Dynamic table management

The dynamic table size can be limited by passing the `dynamic-table-limit` named argument when constructing either the encoder or decoder:

```
my $decoder = HTTP::HPACK::Decoder.new(dynamic-table-limit => 256);

```

It is also possible to introspect the current dynamic table size:

```
say $decoder.dynamic-table-size;

```

The size is computed according to the algorithm in RFC 7541 Section 4.1.

# Thread safety

Instances of HTTP::HPACK::Header are immutable and so safe to share and access concurrently. Instances of `HTTP::HPACK::Decoder` and `HTTP::HPACK::Encoder` are stateful (as a result of the dynamic table), and so a given instance may not be used concurrently. This is not a practical problem, since headers may only be processed in the order they are being received or transmitted anyway.

# Known issues

* The Huffman code termination handling has not been validated to be completely up to specification, and so may fail to signal errors in some cases where the Huffman code is terminated in a bogus way.

# AUTHOR

Jonathan Worthington

# COPYRIGHT AND LICENSE

Copyright 2016 - 2023 Jonathan Worthington

Copyright 2024 - 2025 Raku Community

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## maxpairs.md
maxpairs

Combined from primary sources listed below.

# [In Any](#___top "go to top of document")[§](#(Any)_method_maxpairs "direct link")

See primary documentation
[in context](/type/Any#method_maxpairs)
for **method maxpairs**.

```raku
multi method maxpairs(Any:D:)
```

Calls [`.pairs`](/routine/pairs) and returns a [`Seq`](/type/Seq) with all of the Pairs with maximum values, as judged by the [`cmp` operator](/routine/cmp):

```raku
<a b c a b c>.maxpairs.raku.put; # OUTPUT: «(2 => "c", 5 => "c").Seq␤»
%(:42a, :75b).maxpairs.raku.put; # OUTPUT: «(:b(75),).Seq␤»
```

# [In role Setty](#___top "go to top of document")[§](#(role_Setty)_method_maxpairs "direct link")

See primary documentation
[in context](/type/Setty#method_maxpairs)
for **method maxpairs**.

```raku
multi method maxpairs(Setty:D: --> Seq:D)
```

Returns the value of [`self.pairs`](/routine/pairs) (as all Pairs have maximum values). See also [`Any.maxpairs`](/routine/maxpairs)


## bridge.md
Bridge

Combined from primary sources listed below.

# [In role Rational](#___top "go to top of document")[§](#(role_Rational)_method_Bridge "direct link")

See primary documentation
[in context](/type/Rational#method_Bridge)
for **method Bridge**.

```raku
method Bridge()
```

Returns the number, converted to [`Num`](/type/Num).

# [In Num](#___top "go to top of document")[§](#(Num)_method_Bridge "direct link")

See primary documentation
[in context](/type/Num#method_Bridge)
for **method Bridge**.

```raku
method Bridge(Num:D:)
```

Returns the number.

# [In Int](#___top "go to top of document")[§](#(Int)_method_Bridge "direct link")

See primary documentation
[in context](/type/Int#method_Bridge)
for **method Bridge**.

```raku
method Bridge(Int:D: --> Num:D)
```

Returns the integer converted to [`Num`](/type/Num).

# [In role Real](#___top "go to top of document")[§](#(role_Real)_method_Bridge "direct link")

See primary documentation
[in context](/type/Real#method_Bridge)
for **method Bridge**.

```raku
method Bridge(Real:D:)
```

Default implementation coerces the invocant to [`Num`](/type/Num) and that's the behavior of this method in core `Real` types. This method primarily exist to make it easy to implement custom `Real` types by users, with the `Bridge` method returning *one of* the core `Real` types (*NOT* necessarily a [`Num`](/type/Num)) that best represent the custom `Real` type. In turn, this lets all the core operators and methods obtain a usable value they can work with.

As an example, we can implement a custom `Temperature` type. It has a unit of measure and the value, which are given during instantiation. We can implement custom operators or conversion methods that work with this type. When it comes to regular mathematical operators, however, we can simply use the `.Bridge` method to convert the `Temperature` to Kelvin expressed in one of the core numeric types:

```raku
class Temperature is Real {
    has Str:D  $.unit  is required where any <K F C>;
    has Real:D $.value is required;
    method new ($value, :$unit = 'K') { self.bless :$value :$unit }
    # Note: implementing .new() that handles $value of type Temperature is left as an exercise

    method Bridge {
        when $!unit eq 'F' { ($!value + 459.67) × 5/9 }
        when $!unit eq 'C' {  $!value + 273.15 }
        $!value
    }
    method gist { self.Str }
    method Str  { "$!value degrees $!unit" }
}

sub postfix:<℃> { Temperature.new: $^value, :unit<C> }
sub postfix:<℉> { Temperature.new: $^value, :unit<F> }
sub postfix:<K> { Temperature.new: $^value, :unit<K> }

my $human := 36.6℃;
my $book  := 451℉;
my $sun   := 5778K;
say $human;                # OUTPUT: «36.6 degrees C␤»
say $human + $book + $sun; # OUTPUT: «6593.677777777778␤»
say 123K + 456K;           # OUTPUT: «579␤»
```

As we can see from the last two lines of the output, the type of the bridged result is not forced to be any *particular* core type. It is a [`Rat`](/type/Rat), when we instantiated `Temperature` with a [`Rat`](/type/Rat) or when conversion was involved, and it is an [`Int`](/type/Int) when we instantiated `Temperature` with an [`Int`](/type/Int).


## dist_cpan-GARLANDG-LibUSB.md
[![Build Status](https://travis-ci.org/travis/Raku-LibUSB.svg?branch=master)](https://travis-ci.org/travis/Raku-LibUSB)

# NAME

LibUSB - OO binding to libusb

# SYNOPSIS

```
constant VID = <vid>
constant PID = <pid>

use LibUSB;
my LibUSB $dev .= new;
$dev.init;
$dev.get-device(VID, PID);
$dev.open()  # Will require elevated privileges

# Do things with the device

$dev.close();
$dev.exit()

```

# DESCRIPTION

LibUSB is an OO Raku binding to the libusb library, allowing for access to USB devices from Raku.

This interface is experimental and incomplete.

## Methods

### init

Initialize the libusb library for this device object.

### get-device (multi)

Find the first device that matches the parameters and select it.

#### Params

##### Int $vid

The VID of the device.

##### Int $pid

The PID of the device.

### get-device (multi)

Find the first device with a user-defined check.

#### Params

##### &check($desc)

Find the first device for which &check returns true. $desc is a libusb\_device\_descriptor as found in the libusb documentation.

### open()

Open the selected device.

### close()

Close the device.

### exit()

Close down the libusb library for this device object.

### vid()

Returns the VID of the device.

### pid()

Returns the PID of the device.

### bus-number()

Returns the bus number of the device.

### address()

Returns the address of the device.

### speed()

Returns the speed of the device.

### control-transfer

Perform a control transfer to the device. It supports named parameters in any order, or positional parameters in the order below.

#### Params

##### uint8 $request-type

The USB control transfer request type.

##### uint8 $request

The USB control transfer request.

##### uint16 $value

The USB control transfer value.

##### uint16 $index

The USB control transfer index.

##### blob8 $data

A buffer containing data to send, or containing space to receive data.

##### uint16 $elems

The number of elems in $data.

##### uint32 $timeout

How long to wait before timing out. Defaults to 0 (never time out).

### bulk-transfer

Perform a bulk transfer to the device. It supports named parameters in any order, or positional parameters in the order below.

#### Params

##### uint8 $endpoint

The target endpoint

##### blob8 $data

A buffer containing data to send, or containing space to receive data.

##### uint16 $elems

The number of elems in $data.

##### Int $transferred is rw

The amount of data transferred (output)

##### uint32 $timeout

How long to wait before timing out. Defaults to 0 (never time out).

### interrupt-transfer

Perform a interrupt transfer to the device. It supports named parameters in any order, or positional parameters in the order below.

#### Params

##### uint8 $endpoint

The target endpoint

##### blob8 $data

A buffer containing data to send, or containing space to receive data.

##### uint16 $elems

The number of elems in $data.

##### Int $transferred is rw

The amount of data transferred (output)

##### uint32 $timeout

How long to wait before timing out. Defaults to 0 (never time out).

# AUTHOR

Travis Gibson [TGib.Travis@protonmail.com](mailto:TGib.Travis@protonmail.com)

# COPYRIGHT AND LICENSE

Copyright 2020 Travis Gibson

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-lizmat-Net-servent.md
[![Actions Status](https://github.com/lizmat/Net-servent/workflows/test/badge.svg)](https://github.com/lizmat/Net-servent/actions)

# NAME

Raku port of Perl's Net::servent module

# SYNOPSIS

```
use Net::servent;
$s = getservbyname('ftp') || die "no service";
printf "port for %s is %s, aliases are %s\n",
   $s.name, $s.port, "@_aliases[]";

use Net::servent qw(:FIELDS);
getservbyname('ftp') || die "no service";
print "port for $s_name is $s_port, aliases are @s_aliases[]\n";

```

# DESCRIPTION

This module tries to mimic the behaviour of Perl's `Net::servent` module as closely as possible in the Raku Programming Language.

This module's exports `getservbyname`, `getservbyportd`, and `getservent` functions that return `Net::servent` objects. This object has methods that return the similarly named structure field name from the C's servent structure from servdb.h, stripped of their leading "s\_" parts, namely name, aliases, port and proto.

You may also import all the structure fields directly into your namespace as regular variables using the :FIELDS import tag. Access these fields as variables named with a preceding s\_ in front their method names. Thus, $serv\_obj.name corresponds to $s\_name if you import the fields.

The `getserv` function is a simple front-end that forwards a numeric argument to `getservbyport` and the rest to `getservbyname`.

# PORTING CAVEATS

This module depends on the availability of POSIX semantics. This is generally not available on Windows, so this module will probably not work on Windows.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/serv-servent> . Comments and Pull Requests are welcome.

# COPYRIGHT AND LICENSE

Copyright 2018, 2019, 2020, 2021 Elizabeth Mattijsen

Re-imagined from Perl as part of the CPAN Butterfly Plan.

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.