Actions, resources, and condition keys for AWS Storage Gateway
AWS Storage Gateway (service prefix:
storagegateway
) provides the following service-specific resources, actions, and condition context keys for use in IAM permission policies.
References:
-
Learn how to configure this service .
-
View a list of the API operations available for this service .
-
Learn how to secure this service and its resources by using IAM permission policies.
Topics
Actions defined by AWS Storage Gateway
You can specify the following actions in the
Action
element of an IAM policy statement. Use policies to grant permissions to perform an operation in AWS. When you use an action in a policy, you usually allow or deny access to the API operation or CLI command with the same name. However, in some cases, a single action controls access to more than one operation. Alternatively, some operations require several different actions.
The
Resource types
column of the Actions table indicates whether each action supports resource-level permissions. If there is no value for this column, you must specify all resources ("*") to which the policy applies in the
Resource
element of your policy statement. If the column includes a resource type, then you can specify an ARN of that type in a statement with that action. If the action has one or more required resources, the caller must have permission to use the action with those resources. Required resources are indicated in the table with an asterisk (*). If you limit resource access with the
Resource
element in an IAM policy, you must include an ARN or pattern for each required resource type. Some actions support multiple resource types. If the resource type is optional (not indicated as required), then you can choose to use one of the optional resource types.
The
Condition keys
column of the Actions table includes keys that you can specify in a policy statement's
Condition
element. For more information on the condition keys that are associated with resources for the service, see the
Condition keys
column of the Resource types table.
For details about the columns in the following table, see Actions table .
| Actions | Description | Access level | Resource types (*required) | Condition keys | Dependent actions |
|---|---|---|---|---|---|
| ActivateGateway | Grants permission to activate the gateway you previously deployed on your host | Write | |||
| AddCache | Grants permission to configure one or more gateway local disks as cache for a cached-volume gateway | Write | |||
| AddTagsToResource | Grants permission to add one or more tags to the specified resource | Tagging | |||
| AddUploadBuffer | Grants permission to configure one or more gateway local disks as upload buffer for a specified gateway | Write | |||
| AddWorkingStorage | Grants permission to configure one or more gateway local disks as working storage for a gateway | Write | |||
| AssignTapePool | Grants permission to move a tape to the target pool specified | Write | |||
| AssociateFileSystem | Grants permission to associate an Amazon FSx file system with the Amazon FSx file gateway | Write |
ds:DescribeDirectories ec2:DescribeNetworkInterfaces fsx:DescribeFileSystems iam:CreateServiceLinkedRole logs:CreateLogDelivery logs:GetLogDelivery logs:ListLogDeliveries logs:UpdateLogDelivery |
||
| AttachVolume | Grants permission to connect a volume to an iSCSI connection and then attaches the volume to the specified gateway | Write | |||
| BypassGovernanceRetention | Grants permission to allow the governance retention lock on a pool to be bypassed | Write | |||
| CancelArchival | Grants permission to cancel archiving of a virtual tape to the virtual tape shelf (VTS) after the archiving process is initiated | Write | |||
| CancelRetrieval | Grants permission to cancel retrieval of a virtual tape from the virtual tape shelf (VTS) to a gateway after the retrieval process is initiated | Write | |||
| CreateCachediSCSIVolume | Grants permission to create a cached volume on a specified cached gateway. This operation is supported only for the gateway-cached volume architecture | Write | |||
| CreateNFSFileShare | Grants permission to create a NFS file share on an existing file gateway | Write | |||
| CreateSMBFileShare | Grants permission to create a SMB file share on an existing file gateway | Write | |||
| CreateSnapshot | Grants permission to initiate a snapshot of a volume | Write | |||
| CreateSnapshotFromVolumeRecoveryPoint | Grants permission to initiate a snapshot of a gateway from a volume recovery point | Write | |||
| CreateStorediSCSIVolume | Grants permission to create a volume on a specified gateway | Write | |||
| CreateTapePool | Grants permission to create a tape pool | Write | |||
| CreateTapeWithBarcode | Grants permission to create a virtual tape by using your own barcode | Write | |||
| CreateTapes | Grants permission to create one or more virtual tapes. You write data to the virtual tapes and then archive the tapes | Write | |||
| DeleteAutomaticTapeCreationPolicy | Grants permission to delete the automatic tape creation policy configured on a gateway-VTL | Write | |||
| DeleteBandwidthRateLimit | Grants permission to delete the bandwidth rate limits of a gateway | Write | |||
| DeleteChapCredentials | Grants permission to delete Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target and initiator pair | Write | |||
| DeleteFileShare | Grants permission to delete a file share from a file gateway | Write | |||
| DeleteGateway | Grants permission to delete a gateway | Write | |||
| DeleteSnapshotSchedule | Grants permission to delete a snapshot of a volume | Write | |||
| DeleteTape | Grants permission to delete the specified virtual tape | Write | |||
| DeleteTapeArchive | Grants permission to delete the specified virtual tape from the virtual tape shelf (VTS) | Write | |||
| DeleteTapePool | Grants permission to delete the specified tape pool | Write | |||
| DeleteVolume | Grants permission to delete the specified gateway volume that you previously created using the CreateCachediSCSIVolume or CreateStorediSCSIVolume API | Write | |||
| DescribeAvailabilityMonitorTest | Grants permission to get the information about the most recent high availability monitoring test that was performed on the gateway | Read | |||
| DescribeBandwidthRateLimit | Grants permission to get the bandwidth rate limits of a gateway | Read | |||
| DescribeBandwidthRateLimitSchedule | Grants permission to get the bandwidth rate limit schedule of a gateway | Read | |||
| DescribeCache | Grants permission to get information about the cache of a gateway. This operation is supported only for the gateway-cached volume architecture | Read | |||
| DescribeCachediSCSIVolumes | Grants permission to get a description of the gateway volumes specified in the request. This operation is supported only for the gateway-cached volume architecture | Read | |||
| DescribeChapCredentials | Grants permission to get an array of Challenge-Handshake Authentication Protocol (CHAP) credentials information for a specified iSCSI target, one for each target-initiator pair | Read | |||
| DescribeFileSystemAssociations | Grants permission to get a description for one or more file system associations | Read | |||
| DescribeGatewayInformation | Grants permission to get metadata about a gateway such as its name, network interfaces, configured time zone, and the state (whether the gateway is running or not) | Read | |||
| DescribeMaintenanceStartTime | Grants permission to get your gateway's weekly maintenance start time including the day and time of the week | Read | |||
| DescribeNFSFileShares | Grants permission to get a description for one or more file shares from a file gateway | Read | |||
| DescribeSMBFileShares | Grants permission to get a description for one or more file shares from a file gateway | Read | |||
| DescribeSMBSettings | Grants permission to get a description of a Server Message Block (SMB) file share settings from a file gateway | Read | |||
| DescribeSnapshotSchedule | Grants permission to describe the snapshot schedule for the specified gateway volume | Read | |||
| DescribeStorediSCSIVolumes | Grants permission to get the description of the gateway volumes specified in the request | Read | |||
| DescribeTapeArchives | Grants permission to get a description of specified virtual tapes in the virtual tape shelf (VTS) | Read | |||
| DescribeTapeRecoveryPoints | Grants permission to get a list of virtual tape recovery points that are available for the specified gateway-VTL | Read | |||
| DescribeTapes | Grants permission to get a description of the specified Amazon Resource Name (ARN) of virtual tapes | Read | |||
| DescribeUploadBuffer | Grants permission to get information about the upload buffer of a gateway | Read | |||
| DescribeVTLDevices | Grants permission to get a description of virtual tape library (VTL) devices for the specified gateway | Read | |||
| DescribeWorkingStorage | Grants permission to get information about the working storage of a gateway | Read | |||
| DetachVolume | Grants permission to disconnect a volume from an iSCSI connection and then detaches the volume from the specified gateway | Write | |||
| DisableGateway | Grants permission to disable a gateway when the gateway is no longer functioning | Write | |||
| DisassociateFileSystem | Grants permission to disassociate an Amazon FSx file system from an Amazon FSx file gateway | Write | |||
| JoinDomain | Grants permission to enable you to join an Active Directory Domain | Write | |||
| ListAutomaticTapeCreationPolicies | Grants permission to list the automatic tape creation policies configured on the specified gateway-VTL or all gateway-VTLs owned by your AWS account | List | |||
| ListFileShares | Grants permission to get a list of the file shares for a specific file gateway, or the list of file shares owned by your AWS account | List | |||
| ListFileSystemAssociations | Grants permission to get a list of the file system associations for the specified gateway | List | |||
| ListGateways | Grants permission to list gateways owned by an AWS account in a region specified in the request. The returned list is ordered by gateway Amazon Resource Name (ARN) | List | |||
| ListLocalDisks | Grants permission to get a list of the gateway's local disks | List | |||
| ListTagsForResource | Grants permission to get the tags that have been added to the specified resource | List | |||
| ListTapePools | Grants permission to list tape pools owned by your AWS account | List | |||
| ListTapes | Grants permission to list virtual tapes in your virtual tape library (VTL) and your virtual tape shelf (VTS) | List | |||
| ListVolumeInitiators | Grants permission to list iSCSI initiators that are connected to a volume | List | |||
| ListVolumeRecoveryPoints | Grants permission to list the recovery points for a specified gateway | List | |||
| ListVolumes | Grants permission to list the iSCSI stored volumes of a gateway | List | |||
| NotifyWhenUploaded | Grants permission to send you a notification through CloudWatch Events when all files written to your NFS file share have been uploaded to Amazon S3 | Write | |||
| RefreshCache | Grants permission to refresh the cache for the specified file share | Write | |||
| RemoveTagsFromResource | Grants permission to remove one or more tags from the specified resource | Tagging | |||
| ResetCache | Grants permission to reset all cache disks that have encountered a error and makes the disks available for reconfiguration as cache storage | Write | |||
| RetrieveTapeArchive | Grants permission to retrieve an archived virtual tape from the virtual tape shelf (VTS) to a gateway-VTL | Write | |||
| RetrieveTapeRecoveryPoint | Grants permission to retrieve the recovery point for the specified virtual tape | Write | |||
| SetLocalConsolePassword | Grants permission to set the password for your VM local console | Write | |||
| SetSMBGuestPassword | Grants permission to set the password for SMB Guest user | Write | |||
| ShutdownGateway | Grants permission to shut down a gateway | Write | |||
| StartAvailabilityMonitorTest | Grants permission to start a test that verifies that the specified gateway is configured for High Availability monitoring in your host environment | Write | |||
| StartGateway | Grants permission to start a gateway that you previously shut down | Write | |||
| UpdateAutomaticTapeCreationPolicy | Grants permission to update the automatic tape creation policy configured on a gateway-VTL | Write | |||
| UpdateBandwidthRateLimit | Grants permission to update the bandwidth rate limits of a gateway | Write | |||
| UpdateBandwidthRateLimitSchedule | Grants permission to update the bandwidth rate limit schedule of a gateway | Write | |||
| UpdateChapCredentials | Grants permission to update the Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target | Write | |||
| UpdateFileSystemAssociation | Grants permission to update a file system association | Write |
logs:CreateLogDelivery logs:DeleteLogDelivery logs:GetLogDelivery logs:ListLogDeliveries logs:UpdateLogDelivery |
||
| UpdateGatewayInformation | Grants permission to update a gateway's metadata, which includes the gateway's name and time zone | Write | |||
| UpdateGatewaySoftwareNow | Grants permission to update the gateway virtual machine (VM) software | Write | |||
| UpdateMaintenanceStartTime | Grants permission to update a gateway's weekly maintenance start time information, including day and time of the week. The maintenance time is the time in your gateway's time zone | Write | |||
| UpdateNFSFileShare | Grants permission to update a NFS file share | Write | |||
| UpdateSMBFileShare | Grants permission to update a SMB file share | Write | |||
| UpdateSMBFileShareVisibility | Grants permission to update whether the shares on a gateway are visible in a net view or browse list | Write | |||
| UpdateSMBLocalGroups | Grants permission to update the list of Active Directory users and groups that have special permissions for SMB file shares on the gateway | Write | |||
| UpdateSMBSecurityStrategy | Grants permission to update the SMB security strategy on a file gateway | Write | |||
| UpdateSnapshotSchedule | Grants permission to update a snapshot schedule configured for a gateway volume | Write | |||
| UpdateVTLDeviceType | Grants permission to update the type of medium changer in a gateway-VTL | Write |
Resource types defined by AWS Storage Gateway
The following resource types are defined by this service and can be used in the
Resource
element of IAM permission policy statements. Each action in the
Actions table
identifies the resource types that can be specified with that action. A resource type can also define which condition keys you can include in a policy. These keys are displayed in the last column of the Resource types table. For details about the columns in the following table, see
Resource types table
.
| Resource types | ARN | Condition keys |
|---|---|---|
| device |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:gateway/$
{
GatewayId}/device/$
{
Vtldevice}
|
|
| fs-association |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:fs-association/$
{
FsaId}
|
|
| gateway |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:gateway/$
{
GatewayId}
|
|
| share |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:share/$
{
ShareId}
|
|
| tape |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:tape/$
{
TapeBarcode}
|
|
| tapepool |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:tapepool/$
{
PoolId}
|
|
| target |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:gateway/$
{
GatewayId}/target/$
{
IscsiTarget}
|
|
| volume |
arn:$
{
Partition}:storagegateway:$
{
Region}:$
{
Account}:gateway/$
{
GatewayId}/volume/$
{
VolumeId}
|
Condition keys for AWS Storage Gateway
AWS Storage Gateway defines the following condition keys that can be used in the
Condition
element of an IAM policy. You can use these keys to further refine the conditions under which the policy statement applies. For details about the columns in the following table, see
Condition keys table
.
To view the global condition keys that are available to all services, see Available global condition keys .
| Condition keys | Description | Type |
|---|---|---|
| aws:RequestTag/${TagKey} | Filters access by the allowed set of values for each of the tags | String |
| aws:ResourceTag/${TagKey} | Filters access by tag-value associated with the resource | String |
| aws:TagKeys | Filters access by the presence of mandatory tags in the request | ArrayOfString |


olsrr offers tools for detecting violation of standard regression assumptions. Here we take a look at residual diagnostics. The standard regression assumptions include the following about residuals/errors:
Graph for detecting violation of normality assumption.
model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_plot_resid_qq(model)
Test for detecting violation of normality assumption.
model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_test_normality(model)
## -----------------------------------------------
## Test Statistic pvalue
## -----------------------------------------------
## Shapiro-Wilk 0.9366 0.0600
## Kolmogorov-Smirnov 0.1152 0.7464
## Cramer-von Mises 2.8122 0.0000
## Anderson-Darling 0.5859 0.1188
## -----------------------------------------------
Correlation between observed residuals and expected residuals under normality.
model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_test_correlation(model)
## [1] 0.970066
It is a scatter plot of residuals on the y axis and fitted values on the x axis to detect non-linearity, unequal error variances, and outliers.
Characteristics of a well behaved residual vs fitted plot:
model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_plot_resid_fit(model)
Histogram of residuals for detecting violation of normality assumption.
model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
ols_plot_resid_hist(model)


WebUI. CSS Framework
Built with SASS
Custom form controls
Buttons
Info
Accent 3
Accent 4
Success
Accent 1
Accent 4
Warning
Accent 1
Light
Danger
Dark
Default
Accent 1
Accent 3
Accent 4
Dark
Grouped controls
1
2
3
1
2
3
1
2
3
£
.00
£
.00
£
.00
Checkboxes and radio buttons


Feedback Form
Please fill out this form to help us improve our site.
Please state your name:
Please enter your password:
Enter your comments here:
...
Please select your favorite action hero:
Rambo
Mad Max
Bugs Bunny
What programming languages do you know:
C
C++
CSharp
Please select your favorite music:
Heavy Metal
Black Metal
Other Metal


CLI Library
CodeIgniter’s CLI library makes creating interactive command-line scripts simple, including:
Prompting the user for more information
Writing multi-colored text the terminal
Beeping (be nice!)
Showing progress bars during long tasks
Wrapping long text lines to fit the window.
Initializing the Class
You do not need to create an instance of the CLI library, since all of it’s methods are static. Instead, you simply
need to ensure your controller can locate it via a use
statement above your class:
<?php
namespace App\Commands;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
class MyCommand extends BaseCommand
{
// ...
public function run(array $params)
{
// ...
}
}
The class is automatically initialized when the file is loaded the first time.
Getting Input from the User
Sometimes you need to ask the user for more information. They might not have provided optional command-line
arguments, or the script may have encountered an existing file and needs confirmation before overwriting. This is
handled with the prompt()
or promptByKey()
method.
Note
Since v4.3.0, you can write tests for these methods with PhpStreamWrapper
.
See Testing CLI Input.
prompt()
You can provide a question by passing it in as the first parameter:
<?php
$color = CLI::prompt('What is your favorite color?');
You can provide a default answer that will be used if the user just hits enter by passing the default in the second parameter:
<?php
$color = CLI::prompt('What is your favorite color?', 'blue');
You can restrict the acceptable answers by passing in an array of allowed answers as the second parameter:
<?php
$overwrite = CLI::prompt('File exists. Overwrite?', ['y', 'n']);
Finally, you can pass validation rules to the answer input as the third parameter:
<?php
$email = CLI::prompt('What is your email?', null, 'required|valid_email');
Validation rules can also be written in the array syntax:
<?php
$email = CLI::prompt('What is your email?', null, ['required', 'valid_email']);
promptByKey()
Predefined answers (options) for prompt sometimes need to be described or are too complex to select via their value.
promptByKey()
allows the user to select an option by its key instead of its value:
<?php
$fruit = CLI::promptByKey('These are your choices:', ['The red apple', 'The plump orange', 'The ripe banana']);
/*
* These are your choices:
* [0] The red apple
* [1] The plump orange
* [2] The ripe banana
*
* [0, 1, 2]:
*/
Named keys are also possible:
<?php
$fruit = CLI::promptByKey(['These are your choices:', 'Which would you like?'], [
'apple' => 'The red apple',
'orange' => 'The plump orange',
'banana' => 'The ripe banana',
]);
/*
* These are your choices:
* [apple] The red apple
* [orange] The plump orange
* [banana] The ripe banana
*
* Which would you like? [apple, orange, banana]:
*/
Finally, you can pass validation rules to the answer input as the third parameter, the acceptable answers are automatically restricted to the passed options.
promptByMultipleKeys()
New in version 4.3.0.
This method is the same as promptByKey()
, but it supports multiple value.
<?php
$hobbies = CLI::promptByMultipleKeys('Select your hobbies:', ['Playing game', 'Sleep', 'Badminton']);
/*
* Select your hobbies:
* [0] Playing game
* [1] Sleep
* [2] Badminton
*
* You can specify multiple values separated by commas.
* [0, 1, 2]:
*
* if your answer is '0,2', the return is the key and the value of the options :
* [
* [0] => "Playing game",
* [2] => "Badminton"
* ]
*/
Important
The method promptByMultipleKeys()
, unlike promptByKey()
, does not support named keys or validation.
Providing Feedback
write()
Several methods are provided for you to provide feedback to your users. This can be as simple as a single status update
or a complex table of information that wraps to the user’s terminal window. At the core of this is the write()
method which takes the string to output as the first parameter:
<?php
CLI::write('The rain in Spain falls mainly on the plains.');
You can change the color of the text by passing in a color name as the second parameter:
<?php
CLI::write('File created.', 'green');
This could be used to differentiate messages by status, or create ‘headers’ by using a different color. You can even set background colors by passing the color name in as the third parameter:
<?php
CLI::write('File overwritten.', 'light_red', 'dark_gray');
The following foreground colors are available:
black
dark_gray
blue
dark_blue
light_blue
green
light_green
cyan
light_cyan
red
light_red
purple
light_purple
light_yellow
yellow
light_gray
white
And a smaller number are available as background colors:
black
blue
green
cyan
red
yellow
light_gray
magenta
print()
Print functions identically to the write()
method, except that it does not force a newline either before or after.
Instead it prints it to the screen wherever the cursor is currently. This allows you to print multiple items all on
the same line, from different calls. This is especially helpful when you want to show a status, do something, then
print “Done” on the same line:
<?php
for ($i = 0; $i <= 10; $i++) {
CLI::print($i);
}
color()
While the write()
command will write a single line to the terminal, ending it with a EOL character, you can
use the color()
method to make a string fragment that can be used in the same way, except that it will not force
an EOL after printing. This allows you to create multiple outputs on the same row. Or, more commonly, you can use
it inside of a write()
method to create a string of a different color inside:
<?php
CLI::write("fileA \t" . CLI::color('/path/to/file', 'white'), 'yellow');
This example would write a single line to the window, with fileA
in yellow, followed by a tab, and then
/path/to/file
in white text.
error()
If you need to output errors, you should use the appropriately named error()
method. This writes light-red text
to STDERR, instead of STDOUT, like write()
and color()
do. This can be useful if you have scripts watching
for errors so they don’t have to sift through all of the information, only the actual error messages. You use it
exactly as you would the write()
method:
<?php
CLI::error('Cannot write to file: ' . $file);
wrap()
This command will take a string, start printing it on the current line, and wrap it to a set length on new lines. This might be useful when displaying a list of options with descriptions that you want to wrap in the current window and not go off screen:
<?php
CLI::color("task1\t", 'yellow');
CLI::wrap('Some long description goes here that might be longer than the current window.');
By default, the string will wrap at the terminal width. Windows currently doesn’t provide a way to determine the window size, so we default to 80 characters. If you want to restrict the width to something shorter that you can be pretty sure fits within the window, pass the maximum line-length as the second parameter. This will break the string at the nearest word barrier so that words are not broken.
<?php
// Wrap the text at max 20 characters wide
CLI::wrap($description, 20);
You may find that you want a column on the left of titles, files, or tasks, while you want a column of text on the right with their descriptions. By default, this will wrap back to the left edge of the window, which doesn’t allow things to line up in columns. In cases like this, you can pass in a number of spaces to pad every line after the first line, so that you will have a crisp column edge on the left:
<?php
$titles = [
'task1a',
'task1abc',
];
$descriptions = [
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
"Lorem Ipsum has been the industry's standard dummy text ever since the",
];
// Determine the maximum length of all titles
// to determine the width of the left column
$maxlen = max(array_map('strlen', $titles));
for ($i = 0; $i < count($titles); $i++) {
CLI::write(
// Display the title on the left of the row
substr(
$titles[$i] . str_repeat(' ', $maxlen + 3),
0,
$maxlen + 3
) .
// Wrap the descriptions in a right-hand column
// with its left side 3 characters wider than
// the longest item on the left.
CLI::wrap($descriptions[$i], 40, $maxlen + 3)
);
}
Would create something like this:
task1a Lorem Ipsum is simply dummy
text of the printing and
typesetting industry.
task1abc Lorem Ipsum has been the
industry's standard dummy
text ever since the
newLine()
The newLine()
method displays a blank line to the user. It does not take any parameters:
<?php
CLI::newLine();
clearScreen()
You can clear the current terminal window with the clearScreen()
method. In most versions of Windows, this will
simply insert 40 blank lines since Windows doesn’t support this feature. Windows 10 bash integration should change
this:
<?php
CLI::clearScreen();
showProgress()
If you have a long-running task that you would like to keep the user updated with the progress, you can use the
showProgress()
method which displays something like the following:
[####......] 40% Complete
This block is animated in place for a very nice effect.
To use it, pass in the current step as the first parameter, and the total number of steps as the second parameter.
The percent complete and the length of the display will be determined based on that number. When you are done,
pass false
as the first parameter and the progress bar will be removed.
<?php
$totalSteps = count($tasks);
$currStep = 1;
foreach ($tasks as $task) {
CLI::showProgress($currStep++, $totalSteps);
$task->run();
}
// Done, so erase it...
CLI::showProgress(false);
table()
<?php
$thead = ['ID', 'Title', 'Updated At', 'Active'];
$tbody = [
[7, 'A great item title', '2017-11-15 10:35:02', 1],
[8, 'Another great item title', '2017-11-16 13:46:54', 0],
];
CLI::table($tbody, $thead);
+----+--------------------------+---------------------+--------+
| ID | Title | Updated At | Active |
+----+--------------------------+---------------------+--------+
| 7 | A great item title | 2017-11-16 10:35:02 | 1 |
| 8 | Another great item title | 2017-11-16 13:46:54 | 0 |
+----+--------------------------+---------------------+--------+
wait()
Waits a certain number of seconds, optionally showing a wait message and waiting for a key press.
<?php
// wait for specified interval, with countdown displayed
CLI::wait($seconds, true);
// show continuation message and wait for input
CLI::wait(0, false);
// wait for specified interval
CLI::wait($seconds, false);


Welcome to Stan's Robot Shop
Here you will find all of Stan's friends. Have a browse around and see who is here.
This is a simple example microservices ecommerce application.
It has been built using various technologies:
- AngularJS (1.x)
- Nginx
- NodeJS
- Java
- Python
- Golang
- PHP (Apache)
- MongoDB
- Redis
- MySQL
When deployed into an environment monitored by Instana, these technology stacks will be automatically
detected and monitored, all with minimum configuration. Every request will be traced end to end.
Stan will keep an eye on all those metrics, events and traces and let you know what needs your attention.
To find out more visit the Instana site.
All the code is available on Github.


Search
Preparing search index...
The search index is not available
@iabtcf/cmpapi - API Documentation
Options
All
Public
Public/Protected
All
Inherited
Externals
Only exported
Menu
Globals
InAppTCData
Interface InAppTCData
InAppTCData response model to be returned to TCF Api Command issuer
Hierarchy
TCData
Response
InAppTCData
Implemented by
InAppTCDataBldr
Index
Properties
cmp
Id
cmp
Version
event
Status
gdpr
Applies
is
Service
Specific
out
OfBand
publisher
publisherCC
purpose
purpose
One
Treatment
special
Feature
Optins
tc
String
tcf
Policy
Version
use
Non
Standard
Stacks
vendor
Properties
cmp
Id
cmp
Id
:
number
cmp
Version
cmp
Version
:
number
event
Status
event
Status
:
string
gdpr
Applies
gdpr
Applies
:
boolean
|
BoolInt
is
Service
Specific
is
Service
Specific
:
boolean
|
BoolInt
out
OfBand
out
OfBand
:
undefined
publisher
publisher
:
object
Type declaration
consents
:
BooleanVector
|
string
custom
Purpose
:
object
consents
:
BooleanVector
|
string
legitimate
Interests
:
BooleanVector
|
string
legitimate
Interests
:
BooleanVector
|
string
restrictions
:
Restrictions
publisherCC
publisherCC
:
string
purpose
purpose
:
object
Type declaration
consents
:
BooleanVector
|
string
legitimate
Interests
:
BooleanVector
|
string
purpose
One
Treatment
purpose
One
Treatment
:
boolean
|
BoolInt
special
Feature
Optins
special
Feature
Optins
:
BooleanVector
|
string
tc
String
tc
String
:
string
tcf
Policy
Version
tcf
Policy
Version
:
number
use
Non
Standard
Stacks
use
Non
Standard
Stacks
:
boolean
|
BoolInt
vendor
vendor
:
object
Type declaration
consents
:
BooleanVector
|
string
legitimate
Interests
:
BooleanVector
|
string
Globals
In
AppTCData
cmp
Id
cmp
Version
event
Status
gdpr
Applies
is
Service
Specific
out
OfBand
publisher
publisherCC
purpose
purpose
One
Treatment
special
Feature
Optins
tc
String
tcf
Policy
Version
use
Non
Standard
Stacks
vendor
Generated using
TypeDoc
InAppTCData response model to be returned to TCF Api Command issuer


Custom Game
Timer
3Strikes
Free
Home
Play
Addition
Select
Subtraction
Select
Multiplication
Select
Division
Select


--- layout: default title: About permalink: /about/ ---
Who are we and what are we do
a2call is a collective group of developers from all kinds of background, skill level; coming together to build a voice technology company that is truly open and online!
Our members know a variety of languages and each one is a specialist in their field!
Want to learn something new? Members usually share their projects and experiences for others to learn from!
a2call is an open team made up of people from diverse backgrounds, no matter what race, gender or preferences you have, everyone is welcome!
You can check out our members or projects with following the links down below!


Major events:
☰
×
Home
Authors' conceptions
Administration
Mints
About
Fars
Sham
Jazira & Mosul
Ifriqiya
Yemen
Empire (beta)
Fars
Jazira


NYC's air quality is generally good, but often varies
Our air quality is pretty good and has been improving over time. For PM2.5 (fine particles in the air), NYC meets the national air quality standard of an annual average of 12 μg/m3.
But hour to hour, there's large variation in our air quality - even in neighborhoods with the cleanest air. That means sometimes, New Yorkers are exposed to high levels of pollutants like PM2.5 that can harm health.
These high levels are driven by daily changes in traffic volume, weather patterns that can trap emissions, and other short-term events.
Air quality varies because sources vary
In New York City, about 45% of PM2.5 comes from far-away sources, like coal-burning power plants in the Midwest. But the rest comes from local sources.
When we study air quality in every neighborhood of the city, we're able to identify the sources that are most closely associated with higher levels of air pollution.
Building density affects a neighborhood's air quality because like vehicles, buildings burn fuel and emit pollutants: their boilers burn oil and gas to produce heat and hot water. This is one reason we often see more air pollution in the winter.
Because of new heating oil regulations, PM2.5 has gone down dramatically, and SO2 levels are now indetectable. Read more at the NYCCAS annual report.
Industrial areas affect a neighborhood's air quality because of diesel exhaust from trucks idling and traveling through industrial areas, and from industrial combustion equipment.
Traffic density affects a neighborhood's air quality because engines produce PM2.5, black carbon, and NOx. While electric vehicles help reduce emissions, all vehicles also contribute to PM2.5 through tire wear and braking. Traffic volume is one reason we often see daily spikes in PM2.5 concentration in the mornings and evenings.
Truck traffic density affects a neighborhood's air quality because diesel combustion produces additional pollutants.
Common patterns
We often see air quality data take the shapes below. Take a look at the images and see if you can see similar patterns in today's data - or come back tomorrow to check.
Hourly PM2.5 measurements from 5 AQ monitors
PM2.5, in micrograms per cubic meter (μ/m3)"What about my neighborhood?"
We don't have real-time data for every neighborhood in New York City. However, we use our network of air quality monitors and a huge dataset of sources factors to model air quality based on key factors that affect air quality. To find out about air quality in your neighborhood, click the button below.


| align-content |
Specifies the alignment between the lines inside a flexible container when the items do not use all available space |
| align-items |
Specifies the alignment for items inside a flexible container |
| align-self |
Specifies the alignment for selected items inside a flexible container |
| all |
Resets all properties (except unicode-bidi and direction) |
| animation |
A shorthand property for all the animation-* properties |
| animation-delay |
Specifies a delay for the start of an animation |
| animation-direction |
Specifies whether an animation should be played forwards, backwards or in alternate cycles |
| animation-duration |
Specifies how long an animation should take to complete one cycle |
| animation-fill-mode |
Specifies a style for the element when the animation is not playing (before it starts, after it ends, or both) |
| animation-iteration-count |
Specifies the number of times an animation should be played |
| animation-name |
Specifies a name for the @keyframes animation |
| animation-play-state |
Specifies whether the animation is running or paused |
| animation-timing-function |
Specifies the speed curve of an animation |
| backface-visibility |
Defines whether or not the back face of an element should be visible when facing the user |
| background |
A shorthand property for all the background-* properties |
| background-attachment |
Sets whether a background image scrolls with the rest of the page, or is fixed |
| background-blend-mode |
Specifies the blending mode of each background layer (color/image) |
| background-clip |
Defines how far the background (color or image) should extend within an element
|
| background-color |
Specifies the background color of an element |
| background-image |
Specifies one or more background images for an element |
| background-origin |
Specifies the origin position of a background image |
| background-position |
Specifies the position of a background image |
| background-repeat |
Sets if/how a background image will be repeated |
| background-size |
Specifies the size of the background images |
| border |
A shorthand property for border-width, border-style and border-color |
| border-bottom |
A shorthand property for border-bottom-width, border-bottom-style and border-bottom-color |
| border-bottom-color |
Sets the color of the bottom border |
| border-bottom-left-radius |
Defines the radius of the border of the bottom-left corner |
| border-bottom-right-radius |
Defines the radius of the border of the bottom-right corner |
| border-bottom-style |
Sets the style of the bottom border |
| border-bottom-width |
Sets the width of the bottom border |
| border-collapse |
Sets whether table borders should collapse into a single border or be separated |
| border-color |
Sets the color of the four borders |
| border-image |
A shorthand property for all the border-image-* properties |
| border-image-outset |
Specifies the amount by which the border image area extends beyond the border box |
| border-image-repeat |
Specifies whether the border image should be repeated, rounded or stretched |
| border-image-slice |
Specifies how to slice the border image |
| border-image-source |
Specifies the path to the image to be used as a border |
| border-image-width |
Specifies the width of the border image |
| border-left |
A shorthand property for all the border-left-* properties |
| border-left-color |
Sets the color of the left border |
| border-left-style |
Sets the style of the left border |
| border-left-width |
Sets the width of the left border |
| border-radius |
A shorthand property for the four border-*-radius properties |
| border-right |
A shorthand property for all the border-right-* properties |
| border-right-color |
Sets the color of the right border |
| border-right-style |
Sets the style of the right border |
| border-right-width |
Sets the width of the right border |
| border-spacing |
Sets the distance between the borders of adjacent cells |
| border-style |
Sets the style of the four borders |
| border-top |
A shorthand property for border-top-width, border-top-style and border-top-color
|
| border-top-color |
Sets the color of the top border |
| border-top-left-radius |
Defines the radius of the border of the top-left corner |
| border-top-right-radius |
Defines the radius of the border of the top-right corner |
| border-top-style |
Sets the style of the top border |
| border-top-width |
Sets the width of the top border |
| border-width |
Sets the width of the four borders |
| bottom |
Sets the elements position, from the bottom of its parent element |
| box-decoration-break |
Sets the behavior of the background and border of an element at page-break, or, for in-line elements, at line-break. |
| box-shadow |
Attaches one or more shadows to an element |
| box-sizing |
Defines how the width and height of an element are calculated: should they include padding and borders, or not |
| break-after |
Specifies the page-, column-, or region-break behavior after the generated box |
| break-before |
Specifies the page-, column-, or region-break behavior before the generated box |
| break-inside |
Specifies the page-, column-, or region-break behavior inside the generated box |
| caption-side |
Specifies the placement of a table caption |
| caret-color |
Specifies the color of the cursor (caret) in inputs, textareas, or any element that is editable |
| @charset |
Specifies the character encoding used in the style sheet |
| clear |
Specifies on which sides of an element floating elements are not allowed to float |
| clip |
Clips an absolutely positioned element |
| color |
Sets the color of text |
| column-count |
Specifies the number of columns an element should be divided into |
| column-fill |
Specifies how to fill columns, balanced or not |
| column-gap |
Specifies the gap between the columns |
| column-rule |
A shorthand property for all the column-rule-* properties |
| column-rule-color |
Specifies the color of the rule between columns |
| column-rule-style |
Specifies the style of the rule between columns |
| column-rule-width |
Specifies the width of the rule between columns |
| column-span |
Specifies how many columns an element should span across |
| column-width |
Specifies the column width |
| columns |
A shorthand property for column-width and column-count |
| content |
Used with the :before and :after pseudo-elements, to insert generated content |
| counter-increment |
Increases or decreases the value of one or more CSS counters |
| counter-reset |
Creates or resets one or more CSS counters |
| cursor |
Specifies the mouse cursor to be displayed when pointing over an element |
| direction |
Specifies the text direction/writing direction |
| display |
Specifies how a certain HTML element should be displayed |
| empty-cells |
Specifies whether or not to display borders and background on empty cells in a table |
| filter |
Defines effects (e.g. blurring or color shifting) on an element before the element is displayed |
| flex |
A shorthand property for the flex-grow, flex-shrink, and the flex-basis properties
|
| flex-basis |
Specifies the initial length of a flexible item |
| flex-direction |
Specifies the direction of the flexible items |
| flex-flow |
A shorthand property for the flex-direction and the flex-wrap properties |
| flex-grow |
Specifies how much the item will grow relative to the rest |
| flex-shrink |
Specifies how the item will shrink relative to the rest |
| flex-wrap |
Specifies whether the flexible items should wrap or not |
| float |
Specifies whether or not a box should float |
| font |
A shorthand property for the font-style, font-variant, font-weight, font-size/line-height, and the font-family properties |
| @font-face |
A rule that allows websites to download and use fonts other than the "web-safe" fonts |
| font-family |
Specifies the font family for text |
| font-feature-settings |
Allows control over advanced typographic features in OpenType fonts |
| @font-feature-values |
Allows authors to use a common name in font-variant-alternate for feature activated differently in OpenType |
| font-kerning |
Controls the usage of the kerning information (how letters are spaced) |
| font-language-override |
Controls the usage of language-specific glyphs in a typeface |
| font-size |
Specifies the font size of text |
| font-size-adjust |
Preserves the readability of text when font fallback occurs |
| font-stretch |
Selects a normal, condensed, or expanded face from a font family |
| font-style |
Specifies the font style for text |
| font-synthesis |
Controls which missing typefaces (bold or italic) may be synthesized by the browser |
| font-variant |
Specifies whether or not a text should be displayed in a small-caps font |
| font-variant-alternates |
Controls the usage of alternate glyphs associated to alternative names defined in @font-feature-values |
| font-variant-caps |
Controls the usage of alternate glyphs for capital letters |
| font-variant-east-asian |
Controls the usage of alternate glyphs for East Asian scripts (e.g Japanese and Chinese) |
| font-variant-ligatures |
Controls which ligatures and contextual forms are used in textual content of the elements it applies to |
| font-variant-numeric |
Controls the usage of alternate glyphs for numbers, fractions, and ordinal markers |
| font-variant-position |
Controls the usage of alternate glyphs of smaller size positioned as superscript or subscript regarding the baseline of the font |
| font-weight |
Specifies the weight of a font |
| grid |
A shorthand property for the grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, and the grid-auto-flow properties |
| grid-area |
Either specifies a name for the grid item, or this property is a shorthand property for the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties |
| grid-auto-columns |
Specifies a default column size |
| grid-auto-flow |
Specifies how auto-placed items are inserted in the grid |
| grid-auto-rows |
Specifies a default row size |
| grid-column |
A shorthand property for the grid-column-start and the grid-column-end properties |
| grid-column-end |
Specifies where to end the grid item |
| grid-column-gap |
Specifies the size of the gap between columns |
| grid-column-start |
Specifies where to start the grid item |
| grid-gap |
A shorthand property for the grid-row-gap and grid-column-gap properties |
| grid-row |
A shorthand property for the grid-row-start and the grid-row-end properties |
| grid-row-end |
Specifies where to end the grid item |
| grid-row-gap |
Specifies the size of the gap between rows |
| grid-row-start |
Specifies where to start the grid item |
| grid-template |
A shorthand property for the grid-template-rows, grid-template-columns and grid-areas properties |
| grid-template-areas |
Specifies how to display columns and rows, using named grid items |
| grid-template-columns |
Specifies the size of the columns, and how many columns in a grid layout |
| grid-template-rows |
Specifies the size of the rows in a grid layout |
| hanging-punctuation |
Specifies whether a punctuation character may be placed outside the line box |
| height |
Sets the height of an element |
| hyphens |
Sets how to split words to improve the layout of paragraphs |
| image-rendering |
Gives a hint to the browser about what aspects of an image are most important to preserve when the image is scaled |
| @import |
Allows you to import a style sheet into another style sheet |
| isolation |
Defines whether an element must create a new stacking content |
| justify-content |
Specifies the alignment between the items inside a flexible container when the items do not use all available space |
| @keyframes |
Specifies the animation code |
| left |
Specifies the left position of a positioned element |
| letter-spacing |
Increases or decreases the space between characters in a text |
| line-break |
Specifies how/if to break lines |
| line-height |
Sets the line height |
| list-style |
Sets all the properties for a list in one declaration |
| list-style-image |
Specifies an image as the list-item marker |
| list-style-position |
Specifies the position of the list-item markers (bullet points) |
| list-style-type |
Specifies the type of list-item marker |
| margin |
Sets all the margin properties in one declaration |
| margin-bottom |
Sets the bottom margin of an element |
| margin-left |
Sets the left margin of an element |
| margin-right |
Sets the right margin of an element |
| margin-top |
Sets the top margin of an element |
| max-height |
Sets the maximum height of an element |
| max-width |
Sets the maximum width of an element |
| @media |
Sets the style rules for different media types/devices/sizes |
| min-height |
Sets the minimum height of an element |
| min-width |
Sets the minimum width of an element |
| mix-blend-mode |
Specifies how an element's content should blend with its direct parent background |
| object-fit |
Specifies how the contents of a replaced element should be fitted to the box established by its used height and width |
| object-position |
Specifies the alignment of the replaced element inside its box |
| opacity |
Sets the opacity level for an element |
| order |
Sets the order of the flexible item, relative to the rest |
| orphans |
Sets the minimum number of lines that must be left at the bottom of a page when a page break occurs inside an element |
| outline |
A shorthand property for the outline-width, outline-style, and the outline-color properties |
| outline-color |
Sets the color of an outline |
| outline-offset |
Offsets an outline, and draws it beyond the border edge |
| outline-style |
Sets the style of an outline |
| outline-width |
Sets the width of an outline |
| overflow
|
Specifies what happens if content overflows an element's box |
| overflow-wrap |
Specifies whether or not the browser may break lines within words in order to prevent overflow (when a string is too long to fit its containing box) |
| overflow-x |
Specifies whether or not to clip the left/right edges of the content, if it overflows the element's content area |
| overflow-y |
Specifies whether or not to clip the top/bottom edges of the content, if it overflows the element's content area |
| padding |
A shorthand property for all the padding-* properties |
| padding-bottom |
Sets the bottom padding of an element |
| padding-left |
Sets the left padding of an element |
| padding-right |
Sets the right padding of an element |
| padding-top |
Sets the top padding of an element |
| page-break-after |
Sets the page-break behavior after an element |
| page-break-before |
Sets the page-break behavior before an element |
| page-break-inside |
Sets the page-break behavior inside an element |
| perspective |
Gives a 3D-positioned element some perspective |
| perspective-origin |
Defines at which position the user is looking at the 3D-positioned element |
| pointer-events |
Defines whether or not an element reacts to pointer events |
| position |
Specifies the type of positioning method used for an element (static, relative, absolute or fixed) |
| quotes |
Sets the type of quotation marks for embedded quotations |
| resize |
Defines if (and how) an element is resizable by the user |
| right |
Specifies the right position of a positioned element |
| scroll-behavior |
Specifies whether to smoothly animate the scroll position in a scrollable box, instead of a straight jump |
| tab-size |
Specifies the width of a tab character |
| table-layout |
Defines the algorithm used to lay out table cells, rows, and columns |
| text-align |
Specifies the horizontal alignment of text |
| text-align-last |
Describes how the last line of a block or a line right before a forced line break is aligned when text-align is "justify" |
| text-combine-upright |
Specifies the combination of multiple characters into the space of a single character |
| text-decoration |
Specifies the decoration added to text |
| text-decoration-color |
Specifies the color of the text-decoration |
| text-decoration-line |
Specifies the type of line in a text-decoration |
| text-decoration-style |
Specifies the style of the line in a text decoration |
| text-indent |
Specifies the indentation of the first line in a text-block |
| text-justify |
Specifies the justification method used when text-align is "justify" |
| text-orientation |
Defines the orientation of the text in a line |
| text-overflow |
Specifies what should happen when text overflows the containing element |
| text-shadow |
Adds shadow to text |
| text-transform |
Controls the capitalization of text |
| text-underline-position |
Specifies the position of the underline which is set using the text-decoration property |
| top |
Specifies the top position of a positioned element |
| transform |
Applies a 2D or 3D transformation to an element |
| transform-origin |
Allows you to change the position on transformed elements |
| transform-style |
Specifies how nested elements are rendered in 3D space |
| transition |
A shorthand property for all the transition-* properties |
| transition-delay |
Specifies when the transition effect will start |
| transition-duration |
Specifies how many seconds or milliseconds a transition effect takes to complete |
| transition-property |
Specifies the name of the CSS property the transition effect is for |
| transition-timing-function |
Specifies the speed curve of the transition effect |
| unicode-bidi |
Used together with the direction property to set or return whether the text should be overridden to support multiple languages in the same document |
| user-select |
Specifies whether the text of an element can be selected |
| vertical-align |
Sets the vertical alignment of an element |
| visibility |
Specifies whether or not an element is visible |
| white-space |
Specifies how white-space inside an element is handled |
| widows |
Sets the minimum number of lines that must be left at the top of a page when a page break occurs inside an element |
| width |
Sets the width of an element |
| word-break |
Specifies how words should break when reaching the end of a line |
| word-spacing |
Increases or decreases the space between words in a text |
| word-wrap |
Allows long, unbreakable words to be broken and wrap to the next line |
| writing-mode |
Specifies whether lines of text are laid out horizontally or vertically |
| z-index |
Sets the stack order of a positioned element |


#include <Ray.h>
|
| std::ostream & | print (std::ostream &sink) const |
| |
◆ Ray()
◆ offset()
Offset the base by v.
- Parameters
-
| v | The vector to add to the base |
◆ print()
| std::ostream & Ray::print |
( |
std::ostream & |
sink | ) |
const |
|
private |
◆ read_base()
| const Vector3D & Ray::read_base |
( |
| ) |
const |
◆ read_direction()
| const Vector3D & Ray::read_direction |
( |
| ) |
const |
◆ read_inverse_direction()
| const Vector3D & Ray::read_inverse_direction |
( |
| ) |
const |
◆ walk()
| void Ray::walk |
( |
double |
d | ) |
|
Offset the base by direction*d.
- Parameters
-
| d | The number of directions to walk |
◆ operator<<
| std::ostream& operator<< |
( |
std::ostream & |
sink, |
|
|
const Ray & |
ray |
|
) |
| |
|
friend |
◆ direction
◆ inverse_direction
◆ point
The documentation for this class was generated from the following files:


---
order: 20
title: Adeptus Mechanicus – Titan Legion
name: War Griffons Titan Legion
forces:
- adeptus-mechanicus-titan-legion
- imperial-navy
using_the_army_list:
|
The following army list allows you to field an army based on one of the War Griffons Titan Legion. It can also be used as a stand in
army list for other Titan Legions as well.
War Griffons Titan Legion formations come in three types: battle titans, scout titans and support formations. Each battle titan you include in the army allows you to field any two scout titan formations. Each battle titan or scout titan formation allows you to field any one support formation. Although you can only take a scout titan or support formation if you first take a battle titan formation, they are treated as separate independent formations during a battle and do not have to move around together.
In addition, certain formations may be given upgrades. Which upgrades a formation may be given are listed in the upgrades
column. Upgrades are added to the formation and are not a separate formation. Each upgrade that is taken adds to the cost of the formation, as shown on the upgrade chart. **Note:** the upgrades chosen can lead to an additional surcharge (see [War Griffons Epic Tournament Special Rules](#war-griffons-epic-tournament-special-rules)).
special_rules:
- god-machines
- war-griffons-epic-tournament-special-rules
---
War Griffons Titan Legion armies have a strategy rating of 3. Battle and Scout Titan formations have an initiative rating of 1+. All other formations have an initiative rating of 2+.
Battle Titan Formations
| Formation |
Units |
Upgrades |
Cost |
| Emperor |
One Imperator or Warmonger Class Titan |
Carapace Multilasers, Legate, Sacred Icon, Veteran Princeps |
1250 points |
| Reaver |
One Reaver Class Titan |
All |
550 points |
| Warlord |
One Warlord Class Titan |
All |
675 points |
Scout Titan Formations
| (Any two scout titan formations may be fielded per each battle titan.) |
| Formation |
Units |
Upgrades |
Cost |
| Warhound |
One Warhound Class Titan |
Inferno Gun, Plasma Blastgun, Turbo-Laser Destructor, Veteran Princeps, Vulcan Mega-Bolter |
275 points |
| Warhound Pack |
Two Warhound Class Titans |
Inferno Gun, Plasma Blastgun, Turbo-Laser Destructor, Veteran Princeps, Vulcan Mega-Bolter |
500 points |
Titan Upgrades
Battle Titan Weapons
| (Mount each weapon mount in the formation with one of the following upgrades.) |
| Upgrade |
Cost |
| Apocalypse Missile Launcher |
+25 points each |
| Carapace Landing Pad |
Free |
| Close Combat Weapon |
+25 points each |
| Corvus Assault Pod |
Free |
| Gatling Blaster |
+25 points each |
| Laser Blaster |
+50 points each |
| Laser Burner |
Free |
| Melta Cannon |
+50 points each |
| Plasma Cannon |
+25 points each |
Plasma Destructor
Note: Carapace weapon mounts only.
|
+75 points each |
| Quake Cannon |
+75 points each |
Support Missile
Note: Carapace weapon mounts only.
|
+75 points each |
| Volcano Cannon |
+50 points each |
Scout Titan Weapons
| (Mount each weapon mount in the formation with one of the following upgrades.) |
| Upgrade |
Cost |
| Inferno Gun |
Free |
| Plasma Blastgun |
Free |
| Turbo-Laser Destructor |
+25 points each |
| Vulcan Mega-Bolter |
Free |
Scout and Battle Titan Upgrades
| (Add any of the following upgrades to a unit up to once per formation.) |
| Upgrade |
Cost |
| Carapace Multilasers |
+50 points |
| 0–1 Legate per army |
+50 points |
| Sacred Icon |
+50 points |
| Veteran Princeps |
+25 points |
|
Support Formations
| (Any one support formation may be fielded per each battle or scout titan formation.) |
| Formation |
Units |
Cost |
| Crusader Scout Maniple |
Four Crusader Robots |
150 points |
| Forge Knight Maniple |
Five Forge Knights |
250 points |
| 0–1 Lysander Fighter per Warmonger Class Titan |
One Lysander Fighter |
75 points |
| Marauder Squadron |
Two Marauder Bombers |
250 points |
| 0–1 Orbital Support |
One Ark Mechanicus Battleship |
200 points |
| Skitarii Demi-Century |
Eight Hypaspist units and two Secutor units |
250 points |
| Thunderbolt Squadron |
Two Thunderbolt Fighters |
150 points |


Mr.Updater is mainly a platform for offered deals,loots and tricks. It is a public website where people can get latest offered deals,loots on online shops/stores. This is mainly made for the people not to waste money as well as time, we value your precious time. We Assure you that we give you the best deals, loots and offers available at your fingertip. We also update everyday's cashbacks, unlimited tricks and some self money making tricks. Why to waste money and time?.. when you have everything under a single platform.
JOIN OUR WHATSAPP GROUP
JOINEmail: mrupdater999@gmail.com


VSL // Small-Batch Eats For Dads
* Bon Appétit recently named Franklin the best cue’ joint in the country. Here’s your chance to skip the line and douse a lil’ Espresso BBQ Sauce
today’s Very Short List:
food 6 Jun 2014
Reggie Milligan co-founded Mantry (The Modern Man’s Pantry)
Subscribe
* Olive & Sinclair’s Bourbon Nib Brittle
* Created by two college buddies over a booze-infused brunch, Stu’s Bloody Mary Mix
http://link.nyobserver.com/516ca68465217dc6e1b9a3a61m94y.bbl/TvnrKi0WTdwTHwxwC3ecf
delightful e-mail that shares
cultural gems from a
different curator every day.
If you have any problems reading this e-mail, click here
http://link.nyobserver.com/516ca68465217dc6e1b9a3a61m94y.bbl/UHyHCJsf7NZSKXrPC07cd
Subscribe
Forward
My Account
Unsubscribe
culture 4 Jun 2014
Louise Ljungberg on the powerful, the fascinating, and the heartbroken.
culture 2 Jun 2014
Isabel Sheinman looks at some innovative non-profit campaigns.
food 30 May 2014
Chef Cristina Castañeda on a healthy balance of mind, body, and Mexican food.
Editorial Policy
Privacy Policy
Contact Us
Press
Terms + Conditions
very fine print: ©2014
Observer VSL LLC.
321 West 44th Street, 6th Floor
New York, NY 10036 USA
All rights reserved.
Questions?<PHONE_NUMBER>.
This message was intended for<EMAIL_ADDRESS>If you believe this has been sent to you in error, please safely unsubscribe


Provides functions used to build R packages. Locates compilers
needed to build R packages on various platforms and ensures the PATH is
configured appropriately so R can use them.
| Version: |
1.0.2 |
| Depends: |
R (≥ 3.1) |
| Imports: |
callr (≥ 2.0.0), cli, crayon, desc, prettyunits, R6, rprojroot, withr (≥ 2.1.2) |
| Suggests: |
Rcpp, testthat, covr |
| Published: |
2018-10-16 |
| Author: |
Hadley Wickham [aut],
Jim Hester [aut, cre],
RStudio [cph] |
| Maintainer: |
Jim Hester <james.hester at rstudio.com> |
| BugReports: |
https://github.com/r-lib/pkgbuild/issues |
| License: |
GPL-3 |
| URL: |
https://github.com/r-lib/pkgbuild |
| NeedsCompilation: |
no |
| Materials: |
README NEWS |
| CRAN checks: |
pkgbuild results |


Simple design using HTML5
Simple design using HTML5
Hi! My name is Gradi Kayamba.
I am a Front-, and Back-End Web Developer. I'm very passionate and dedicated to my work.
With 4 years experience as a Web developer, I have acquired the skills and knowledge necessary to make your project a success.
I enjoy every step of the design process, from discussion and collaboration to concept and execution, but I find the most satisfaction in seeing the finished product do everything for you that it was created to do.
Life Time Learning is my keyword.
The world is constantly changing and it is a must for me to regularly update my skills and knowledge.
Simple design using HTML5
From script to animation
From blank to colors


China presents any observer with an array of bizarre and seemingly irreconcilable contradictions. Over the years we have constructed a framework that aids in understanding China’s paradox.
October 2012
China presents any observer with an array of bizarre and seemingly irreconcilable contradictions. Over the years we have constructed a framework that aids in understanding China’s paradox.
October 2012


Pinhole Elimination is a read-write DFM action intended to remove
small copper residues (islands) and cover small pinholes (tiny copperless gaps
surrounded on all sides by copper) in the layer. Such islands may be easily
disconnected from the laminate, causing shorts in the circuitry. Pinholes, on
the other hand, may cause electrical breaks, decreased connectivity, or
undesirable electrical effects.
Pinhole Elimination locates such undesirable features by first
contourizing the layer features and then looking for islands, and holes in
islands, which are smaller than a predefined parameter. If there is enough
surrounding space, islands will be covered by negative features and holes will
be covered by positive features. In cases where the surrounding space is too
limited to insert a patch, the hole or island will be listed in the Uncovered category.
All features listed in the Pinhole Elimination category are
tagged with the .patch attribute.
Another problem that Pinhole Elimination helps solve: some
surface-fill algorithms produce sets of parallel lines, which are placed
parallel to each other. As result of rounding errors in different software and
hardware components, such lines sometimes create long slivers or holes. Pinhole
Elimination enlarges all such lines slightly (by 0.001 mil).
Pinhole Elimination operates on any layer but is mainly designed
for power and ground, mixed, and signal layers.
*
Layers with more than 320,000 nets cannot be processed
in global mode
Enables you to define how to fill pinholes: Lines and/or
Surfaces.
Reports the total features detected for each category in each
layer.
No result attributes are produced.


So far, we've made a function that tells us the type of a given character:
(def digits #{\1 \2 \3 \4 \5 \6 \7 \8 \9 \0}) (def char-names {\space :space \. :period \/ :forward-slash \" :double-quote}) (defn char-type [ch] (cond (contains? digits ch) :digit (contains? char-names ch) (get char-names ch) true :other))
Then, we looped over an array of characters and grouped them according to their type:
(def chars (vec "42 0.5 1/2 foo-bar")) (loop [result [] index 0 last-type nil group nil] (let [ch (get chars index) new-type (char-type ch) new-index (+ index 1)] (if ch (if (= last-type new-type) (recur result new-index last-type (conj group ch)) (let [new-result (if group (conj result group) result)] (recur new-result new-index new-type [ch]))) (conj result group))))
We now want to combine these grouped characters into strings. One way to do that is with the str
function:
(str \h \e \l \l \o)
So now we can change our loop to store the groups as strings rather than in vectors by simply changing how the group is passed to recur
:
(loop [result [] index 0 last-type nil group nil] (let [ch (get chars index) new-type (char-type ch) new-index (+ index 1)] (if ch (if (= last-type new-type) (recur result new-index last-type (str group ch)) (let [new-result (if group (conj result group) result)] (recur new-result new-index new-type (str ch)))) (conj result group))))
While this is a good start, it's not quite what we want. A reader needs to treat 1.5
as a discrete number, so instead of ["0" "." "5"]
we really just want "0.5"
. To do this, let's make a more sophisticated function for deciding if the types are the same:
(defn same-type? [left-type right-type] (or (= left-type right-type) (= [left-type right-type] [:digit :period])))
Then use it where we are currently are doing (= last-type new-type)
:
(loop [result [] index 0 last-type nil group nil] (let [ch (get chars index) new-type (char-type ch) new-index (+ index 1)] (if ch (if (same-type? last-type new-type) (recur result new-index last-type (str group ch)) (let [new-result (if group (conj result group) result)] (recur new-result new-index new-type (str ch)))) (conj result group))))
Now our 0.5
is merged together! Let's finally put this loop in a function so we can easily call it:
(defn partition-chars [chars] (loop [result [] index 0 last-type nil group nil] (let [ch (get chars index) new-type (char-type ch) new-index (+ index 1)] (if ch (if (same-type? last-type new-type) (recur result new-index last-type (str group ch)) (let [new-result (if group (conj result group) result)] (recur new-result new-index new-type (str ch)))) (conj result group)))))
Now we can call it like this:
(partition-chars chars)
Notice that the function argument is called chars
. It is perfectly fine for a var and a function argument to have the same name. Inside the function, the evaluator will resolve chars
as the argument. Outside the function, chars
will resolve to the var as usual. This is called shadowing.
Now we can easily start merging other things. Let's make fractions merge together:
(defn same-type? [left-type right-type] (or (= left-type right-type) (= [left-type right-type] [:digit :period]) (= [left-type right-type] [:digit :forward-slash])))
And now 1/2
is a single string:
(partition-chars chars)
There's a simpler way to write this. We can put all "merge pairs" in a set:
(def merge-pairs #{[:digit :period] [:digit :forward-slash]})
And then make same-type?
check if the current pair is in it:
(defn same-type? [left-type right-type] (or (= left-type right-type) (contains? merge-pairs [left-type right-type])))
It should still work the same way:
Previous: LoopsNext: Regular Expressions(partition-chars chars)


Thunberg Joins Climate Activists at LA Rally
by NATHAN SOLISLOS ANGELES (CN) – Climate activist Greta Thunberg joined hundreds of climate activists – both young and old – in downtown Los Angeles on Friday to call attention to global warming and to empower people to hold elected leaders accountable.
Organizers said California’s oil drilling industry is one of the biggest emitters of greenhouse gases and its unsafe safety standards cause residents near drill sites to suffer health problems.
The Fridays for Future movement gained worldwide recognition since Thunberg went on strike outside Swedish Parliament in 2018.
Since then, the 16-year-old has embarked on a transatlantic sailing trip from the United Kingdom to New York to raise awareness on greenhouse gas emissions. She went on to address the United Nations in September during the Climate Action Summit and she was shortlisted for the Nobel Peace Prize.
Thunberg said she recently visited the small town of Paradise in Northern California, which was devastated by a wildfire a year ago.
“I met with survivors who showed me around the devastation. Street after street with no houses left. I heard heartbreaking stories,” said Thunberg. “Today, in California we can see the wildfires happening just around the corner. Wildfires that are being intensified by the climate crisis. But it’s not just here.”
She said climate change is causing a dangerous feedback loop that imperils the lives of future generations – and it will be up to the youth to hold their leaders accountable.
The event was organized by Youth Climate Strike, a movement inspired by Thunberg.
During her speech in Los Angeles, Thunberg asked why climate scientists are being ignored which has put people lives at risk.
“Right now, we are living in the beginning of a climate and ecological breakdown. We cannot continue to look away from this crisis anymore,” said Thunberg.
This slideshow requires JavaScript.
After the speech, 77-year-old Joe Roberts said he was not offended by Thunberg saying older generations failed the youth.
“It’s a good point. Not enough was done. I know I can’t do much now. But I can support them,” said Roberts.
Kori “Koko” Malia, 21, of Redondo Beach is a youth group leader with Climate Reality Project and understands the importance of reaching out to young people and allowing them to become involved with climate activism.
“So much is relayed to middle schoolers and the way they’re learning at that age makes a big difference,” said Malia, who was joined by her mother, Lisa Takashima.
Malia says she believes she developed an autoimmune disease from coastal refineries near where she lives, a stark reality many communities face. Takashima says her daughter used to run cross-country until a few years ago.
“I’m glad my mom is so supportive of me doing this. That’s the best gift she can give me. To allow me to fight for my future,” said Malia.
Several hundred marchers went to one of Gov. Gavin Newsom’s offices in downtown Los Angeles to demand he order phasing out the fossil fuel industry in California. No Newsom representatives met the crowd.
Los Angeles is one a few cities that have promised to push forward economic and environmental policies, much like the Green New Deal proposed by congressional Democrats. In September, Climate Strike activists rallied outside City Hall, where LA Mayor Eric Garcetti said the city would strive to become 100% renewable by 2030.
Copyright © 2019 courthousenews.com


(.) (.–.) (–) pain (–.) study breast cancer intervention patients NMT treatment women taping week therapy used changes differences trial AIs Cancer Oncol symptoms {border-style group aromatase fatigue groups musculoskeletal px;} quality significant After #ffffff;} application functional strength clinical functioning observed Mean life pilot (−.–.) Clin Index VAS analysis effects variables − . Functional data p = .), randomized results (.–) BCS EORTC Soc control grip number pressure Arrival (%) Breast CRP Med University arthralgia baseline cervical participants scale Aromatase Changes Control Experimental Kinesio PPT Table applied cases controlled effect experimental inhibitors joint pain, reducing subjective tamoxifen (− .–.) Backache Index, Outcomes Pain QoL associated cms. early health improvement participant postmenopausal p = .) survivors use using (−–) Eur POMS Quality Ther compared different disorders exercise impact index intervention, muscle pain. physical px; scales sensation statistically strip {font-family (Table BAI Disability Life MBS Málaga, Phys QLQ-C Res Spine adjuvant font-size hand healthy hormone improve increase intra-group lower mean. neuromuscular placed related second status studies study, tape technique threshold treated tunnel value values (Range) -time ANOVA BADIX BMC C-reactive Neuromuscular Profile Taping Time ULFI Upper Visual analyzing double; endocrine important inflammatory insomnia interventions loss mean new n = ) objective outcomes overall performed position possible p = ) questionnaire questionnaires received reduce sample strips survivors: syndrome taking therapeutic variable version years yoga Basal (T) (T), ./JCO... ./s--- ATAC Abbreviations: Analogue Arroyo-Morales Cuesta-Vargas Department Fig. Health Limb Mood Questionnaire Research Wide achieve areas base body border-color border-width carpal change cut did improved improves induced information inhibitor-associated inhibitor-induced interesting knee low mass meta-analysis neutral painful patient problems protein reduction resistance solid; symptoms, training variables. variations visual weight {font-style {font-weight (,%) (ANOVA) (CI ./--- Basal CTS Cantarero-Villanueva Care Carpal Effect European Fernández-Lao Hospital Morning Organization Patient-Reported Pressure SFI Sham Spanish Sports Stiffness Total Treatment VNM [], achieved acupuncture analogue available better bold cancer-related cancer: central collab: common concluded contrast courier; development difference drugs effectiveness efficacy em; end estrogen evaluate evaluation grid.. group, higher improving initial levels lumbar means measure measures mechanism morning occur outcome pain: plasma postoperative practice present previous program proteins pt;} p = ), randomised rates recent reported review scores sensitivity shoulder showed slight spine status/QoL study. subjects support taken therapy, time underwent variance various weeks Cognitive Grade


| Scanner - Command line invocation | -p /Users/shani/git/semantic-mediator-protege-plugin -s disabled -b -o csar.report.smc.protege src |
| Scanner - CSAR version | 3.1.1 rev<PHONE_NUMBER>-8738aef abbreviated |
| Scanner - Invoked on | September 4, 2017 5:24 PM |
| Scanner - User name | shani |
| Scanner - Total files | 3 |
| Scanner - Scanned files | 3 |
| Analyzer - CSAR version | 3.1.1 rev<PHONE_NUMBER>-8738aef abbreviated |
| Analyzer - User name | shani |
| Analyzer - Scanned files | 3 |
| Analyzer - Included files | 3 |
| Analyzer - Legal files | 0 |
| Analyzer - Excluded files | 0 |
| Analyzer - Binary files | 0 |
| Analyzer - Last saved | |


--- layout: default title: MISERICORDAE PROJECT whitepaper: passive onni: passive blog: passive get: passive exchange: passive description: A decentralized ‘transformer’ and ‘restorer’ blockchain. ---
Main primary objectives toward addressing:
Misericordae Blockchain is a decentralized ‘transformer’ and ‘restorer’ aimed at implementing solutions to peculiar challenges facing cryptocurrency ecosystem. Read more about Misericordae Blockchain Project...
Onni is a core-shell hybridized gold-pegged price-superstable and price-hemivolatile cryptocurrency of Misericordae Blockchain with hybrid PoW/PoS, nonlinear mining difficulty and multi-algorithmic based. Onnicoin was designed to meet the routine needs of ordinary users who desire stability and protection from extraordinary market forces, and also to satisfy the strong interests of currency traders who enjoy price fluctuations as a tradecraft routine. Get ONNICOIN for your routines!


{% if friend %}
First Name:
Last Name:
Occupation:
Known Since:
Save
{% else %}
There is no friend with id of {{friend.id}}
{% endif %}


The preceding chapter discussed basic data types that serve as building blocks or atoms of large Slogan programs. This chapter is about composite data types, which are molecules created by combining the basic data types in various ways. Some of the data types we discuss here are pairs, lists, arrays, hash tables, sets and records. Pairs, lists and arrays are also known as aggregate types because they are concatenations of other values.1
Suppose you are writing a program that deals with GPS coordinates. A GPS coordinate consists of two real numbers – one for latitude and the other for longitude. You can always use two separate variables for these, but your program will lack the ability to express the concept of location as a concrete entity. Without this ability, functions in your program will have to accept and "interpret" two distinct numbers as representing a single location.
Let us tackle the problem of giving the GPS coordinate a concrete representation. We need a mechanism to glue together two real numbers
into a single value. Slogan's pair data type is ideal for this purpose. A pair can be
constructed either by calling the pair
function or by using the colon (:
)
operator2.
Here are the coordinates of two cities of the world, encoded as
decimal degrees:
let new_york_coords = pair(40.7166638, -74.0)
let bangalore_coords = 12.97160:77.59456
new_york_coords
// 40.7166638:-74.0
bangalore_coords
// 12.9716:77.59456
The values in a pair can be accessed in two ways. The first method is to use the head
and
tail
functions.
head(bangalore_coords)
// 12.9716
tail(bangalore_coords)
// 77.59456
If you want to bind both members in a pair to new variables, it is more convenient to use the data destructuring mechanism built-into
the let
statement. The variable part of a let
can be
a "pattern". If the internal structure of the value on the right-hand side of the assignment matches this pattern,
values inside the structure will be bound to variables in the pattern.
let ny_lat:ny_long = new_york_coords
ny_lat
// 40.7166638
ny_long
// -74.0
If you want to bind only certain elements in the structure, just replace the variable name with an underscore (_
) in the pattern:
let _:bng_long = bangalore_coords
bng_long
// 77.59456
Now that we have a suitable representation for GPS coordinates, it is a good idea to hide the details of this representation under suitable functions. This will enable the rest of the code to deal with location or coordinates as an abstract idea. Basically we need three functions – a constructor to build coordinates out of two real numbers and two selectors for accessing the individual parts of the location. If we ever decide to use a different internal representation, only these three functions need to change. This is because the rest of the code create and access coordinates through these functions and does not make any assumptions about how they are really represented in memory. This way we add a thin layer of data abstraction to our program.
function make_coords(lat, long) lat:long
function latitude(coord) head(coord)
function longitude(coord) tail(coord)
As the constructors and selectors are not doing nothing much on their own, the following definitions are also possible, in which
they become just aliases for pair
, head
and tail
:
let make_coords = pair
let latitude = head
let longitude = tail
Let us try using the new abstractions:
let new_york_coords = make_coords(40.7166638, -74.0)
let bangalore_coords = make_coords(12.97160, 77.59456)
latitude(new_york_coords)
// 40.7166638
longitude(bangalore_coords)
// 77.59456
Any new functions that we write need not be bothered about the fact that we represent coordinates with pairs. As an example, we will write a function that prints the DMS value of a coordinate object.
function show_dms(coord)
{ show_dms_component(latitude(coord))
show(" ")
show_dms_component(longitude(coord))
newline() }
function show_dms_component(dd_component)
show(floor(dd_component), "d ",
floor(mod(dd_component * 60, 60)), "m ",
mod(abs(dd_component) * 3600, 60), "s ")
// Usage:
show_dms(bangalore_coords)
//> 12.0d 58.0m 17.760000000002037s 77.0d 35.0m 40.41600000002654s
show_dms(new_york_coords)
//> 40.0d 42.0m 59.98967999999877s -74.0d 0.0m 0.0s
The values glued together by a pair need not be primitives. They can be other pairs, for instance. This enables us to build hierarchical data structures like the one shown below:
let tree = (1:(2:3:(4:5)))
head(tree)
// 1
head(tail(tree))
// 2
tail(tail(tree))
// 3:4:5
The basic sequence obtained by chaining together pairs are known as a list. A proper list will be terminated by a value that
represents the empty sequence. In Slogan this value is represented by []
. There are various ways you could build a proper list.
Some of these methods are illustrated here:
// pairs terminated by an empty list ([]), is a proper list.
1:2:3:4:5:[]
// [1, 2, 3, 4, 5]
// a list literal can also be constructed by enclosing comma-separated values in []:
[\a, \e, \i, \o, \u]
// [\a, \e, \i, \o, \u]
// another way to build a proper list is to call the `list` function:
list(1, 2, "hello", 3)
// [1, 2, hello, 3]
A list of pairs can be used as a table to lookup information. The lookup function can treat the head of each pair as the key
to find the associated data.
let price_list = ['orange:80, 'apple:120, 'grapes:72]
assq('apple, price_list)
// apple:120
assq('mango, price_list);
// false
function calculate_price(fruit, kg)
{ let entry = assq(fruit, price_list)
when (entry) tail(entry) * kg }
calculate_price('apple, 2)
// 240
calculate_price('grapes, 5)
// 360
calculate_price('mango, 5)
// false
If the lookup-keys are of a complex type like string, list or large integers, assq
won't work. We need a function that
inspects the structure of the key for equality. The function assoc
is defined for this purpose.
Assoc
uses the is_equal
predicate, which is mapped to
the ==
operator, to do the equality check.
let person = ["name": "nemo", "age": 1]
assoc("name", person)
// name:nemo
assoc("age", person)
// age:1
assq("age", person)
// false
The next program demonstrates some useful functions that can be applied on lists:
let xs = [10, 3, 45, 8, 9]
length(xs)
// 5
length(xs) == count(xs)
// true
at(xs, 2)
// 45
xs[2]
// 45
xs[1:3]
// [3, 45]
xs[:3]
// [10, 3, 45]
reverse(xs)
// [9, 8, 45, 3, 10]
sort(xs)
// [3, 8, 9, 10, 45]
// comparisons
[1, 2, 3] == [1, 2, 3]
// true
[1, 2, 3] <> [4, 5, 6]
// true
[1, 2, 3] < [4, 5, 6]
// true
[1, 2, 3] > [4, 5, 6]
// false
[1, 2, 3] >= [1, 2, 3]
// true
// membership checks
memq(3, xs)
// [3, 45, 8, 9]
memq(10, xs)
// [10, 3, 45, 8, 9]
memq(1, xs)
// false
let ys = ["a", "list", "of", "strings", ["and", "lists"]]
// memq won't work because it uses `is_eq`
memq("of", ys)
// false
// use `member` instead
member("of", ys)
// [of, strings, [and, lists]]
member(["and", "lists"], ys)
// [[and, lists]]
member(["and", "list"], ys)
// false
function is_vowel(c)
memq(c, [\a, \e, \i, \o, \u])
is_vowel(\a)
// [\a, \e, \i, \o, \u]
is_vowel(\o)
// [\o, \u]
is_vowel(\k)
// false
A list comprehension is a notational convenience for constructing lists from other lists. It has the following general syntax:
[out_expr | var_expr <- input_list where filter_expr, ...]
Out_expr
constructs each element in the output list. Var_expr
assign values to
variables used in out_expr
. Each value is "extracted" from an input list. The where_clause
is
optional and is used to filter values extracted from the input list.
Some examples of using list comprehensions are shown below:
[x * x | x <- [1, 2, 3, 4, 5]]
// [1, 4, 9, 16, 25]
[i : j | i <- range(1, 5), j <- range(i, 5) where is_even(i)]
// [2:2, 2:3, 2:4, 2:5, 4:4, 4:5]
function triads(n)
{ let elems = range(1, n);
[[x, y, z] | x <- elems,
y <- elems,
z <- elems where x * x + y * y == z * z] }
triads(15)
// [[3, 4, 5], [4, 3, 5], [5, 12, 13], [6, 8, 10],
[8, 6, 10], [9, 12, 15], [12, 5, 13], [12, 9, 15]]
function concat(xss) [x | xs <- xss, x <- xs]
concat([[1, 2, 3], [4, 5, 6]])
// [1, 2, 3, 4, 5, 6]
Arrays are fixed-length sequences that provide constant-time, position-based lookup for elements. If fast lookups are required you should always prefer an array over a list because a list can only provide sequential access to its members. Just like for lists, there are multiple ways to create and initialize arrays:
#[1, 2, 3]
// #[1, 2, 3]
array("hello", "world")
// #[hello, world]
let xs = make_array(5)
xs
// #[false, false, false, false, false]
array_set(xs, 0, 120)
array_set(xs, 2, "hi")
xs
// #[120, false, hi, false, false]
xs[0]
// 120
let ys = #[1, 2, 3, 4, 5]
ys[2:4]
// #[3, 4]
Slogan provide arrays for storing and accessing specific numeric types. For example, the byte-array is optimized for bytes. There are
also arrays for 16bit/32bit/64bit signed/unsigned integers and 32bit/64bit floating-point numbers. The type of an array literal is specified
by an identifier after the #
sign. For example #u8
means an array of unsigned bytes and #s32
means
an array of signed 32bit integers.
#u8[1, 34, 250][1]
// 34
// precision of elements may vary based on architecture:
#f32[1.0, 34.114, 250.12][1]
// 34.11399841308594
Another useful type-specific array are bit_arrays. They are designed to efficiently store and retrieve bit-encoded information.
let flags = #b[1, 0, 1, 1]
flags[0]
// true
flags[1]
// false
bit_array_clear(flags, 2)
flags
// #b[1, 0, 0, 1]
Exercise 5.1. Read about the 16 bit color encoding scheme,
where the red and blue components are encoded using 5 bits and the green component is encoded in 6 bits. Implement a function,
make_color
that takes the red, green and blue components as arguments and return the encoded color value as a bit-array.
Also write selectors for decoding the color object into individual red, green and blue values.
A bloom filter is a data structure that can quickly test if an element is a member of a set.  An element is added to the bloom filter by first converting it into a bunch of integers called hashes and then using those as indices to be turned-on in the bit-array. Membership check also happens similarly - if all the bits at the hashes of the element are on, it is a member of the set. Bloom filters are space efficient because elements are reduced to a few bits and stored. They are ideal when fast lookups against a huge set is required and a false positive result is not catastrophic. An example application is in the domain of crawling and indexing web pages. A crawler has to retrieve and index millions or even billion of pages. When it encounters a new URL, it has to quickly figure out if that URL was already crawled or not. Bloom filter is an ideal data structure here because it is space efficient, fast and rarely re-crawling a page need not be a big deal.
Let us go straight into the implementation of the bloom filter. Note that we make use of the hash functions built into Slogan. A production quality bloom filter will require better hashing techniques.
function make_bloom_filter(size)
make_bit_array(size)
/* Return two hashes for the string `entry`.
The first is generated using the built-in `string_hash`
function. The second hash is generated by converting
`entry` into a list of integers and then hashing that list.
*/
function hash_entry(entry, size)
{ let h1 = string_hash(entry)
// we haven't talked about `map` yet, but we will soon!
let h2 = equal_hash(map(char_to_integer, string_to_list(entry)))
remainder(h1, size):remainder(h2, size) }
/* Add an entry to the bloom filter.
The bits at the positions identified by the hashes
are turned on.
*/
function bloom_filter_set(b, entry)
{ let h1:h2 = hash_entry(entry, bit_array_length(b))
bit_array_set(b, h1)
bit_array_set(b, h2) }
/* Return true if `entry` is a member of the bloom filter.
Both bits identified by the hashes must be on.
*/
function bloom_filter_test(b, entry)
{ let h1:h2 = hash_entry(entry, bit_array_length(b))
b[h1] && b[h2] }
Here is our tiny bloom filter in action:
let b = make_bloom_filter(1000)
bloom_filter_set(b, "hello")
bloom_filter_set(b, "helLO")
bloom_filter_set(b, "hello world")
bloom_filter_test(b, "hello")
// true
bloom_filter_test(b, "helLO")
// true
bloom_filter_test(b, "hello world")
// true
bloom_filter_test(b, "hello, world")
// false
bloom_filter_test(b, "HelLO")
// false
The hash table is one of the most ingenious and versatile of all data structures. It is an unordered collection of key/value pairs in which all the keys are distinct, and the value associated with a given key can be retrieved, updated, or removed using a constant number of key comparisons on the average, no matter how large the hash table.
The simplest way to create a hash table is to write down it as pairs enclosed in #{}
. The head of a pair is treated as key
and the tail becomes the associated value.
let ages = #{"alice":10, "bob":8, "eve":12}
ages["alice"]
// 10
ages["eve"] = ages["eve"] + 2
ages["eve"]
// 14
ages["olivia"]
// false
// return a default value for a missing key
hashtable_at(ages, "olivia", 7)
// 7
hashtable_keys(ages)
// #[alice, eve, bob]
hashtable_values(ages)
// #[10, 14, 8]
A set stores an unordered sequence of objects without duplicates. It is an implementation of the mathematical concept
of finite sets.
Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for
membership in a set. A set literal is written by enclosing the objects in #()
.
let s1 = #(1, 2, 3, 4)
let s2 = #(3, 4, 5, 6)
is_set_member(s1, 2)
// true
is_set_member(s1, 5)
// false
set_difference(s1, s2)
// #(1, 2)
set_difference(s2, s1)
// #(5, 6)
set_intersection(s1, s2)
// #(3, 4)
set_union(s1, s2)
// #(1, 2, 3, 4, 5, 6)
is_subset(#(1, 2), #(1, 2, 3, 4))
// true
is_superset(#(1, 2), #(1, 2, 3, 4))
// false
is_superset(#(1, 2, 3, 4), #(1, 2))
// true
Records are a means for defining new, distinct types. The record
statement is used to introduce a new
custom type. Its general syntax is shown below:
record <name> (<member01> where <pre-condition>, <member02> ...)
For a new record type, Slogan automatically generates a constructor and selector/modifier functions for accessing and updating its members.
The following program shows how a simple record can be defined and used.
record employee(name, salary, dept)
let e1 = employee(name = "alice", salary = 3400, dept = "ENG")
let e2 = employee(name = "bob", salary = 4500, dept = "FIN")
e1
// #<employee #4 name: "alice" salary: 3400 dept: "ENG">
e2
// #<employee #5 name: "bob" salary: 4500 dept: "FIN">
employee_name(e1)
// alice
employee_dept(e2)
// FIN
employee_set_salary(e1, 3600)
e1
// #<employee #4 name: "alice" salary: 3600 dept: "ENG">
One problem with the auto-generated constructor is that it won't do any data integrity checks. For instance, you are allowed to create an employee with an invalid salary:
employee(name = "nemo", salary = "#@@@#@@$", dept = "ENG")
#<employee #6 name: "nemo" salary: "#@@@#@@$" dept: "ENG">
The optional where
clause allows us to specify data validation rules for record values. Let us
redefine the employee
record with some condition checks.
record employee(name where is_string(name),
salary where is_integer(salary)
&& salary > 1500
&& salary < 10000,
dept where is_string(dept))
employee(name = "nemo", salary = "#@@@#@@$", dept = "ENG")
//> error: precondition_failed, #@@@#@@$
employee(name = "nemo", salary = 230, dept = "ENG")
//> error: precondition_failed, 230
employee(name = "nemo", salary = 2300, dept = "ENG")
// #<employee #7 name: "nemo" salary: 2300 dept: "ENG">
Slogan has the ability to take apart data structures and do pattern matching on them. A pattern match expression has the following general form:
match (value)
pattern_1 -> result_1
| pattern_2 -> result_2
| ...
If value
does not match any of the listed patterns, a no_match_found
error is raised.
Let us begin our exploration of pattern matching with the help of a few simple examples. Later we will see how this facility can lead to the clean and concise specification of a non-trivial algorithm.
Our first example re-implements a function from Slogan core
- the length
function that return the number of elements in a list.
function length(xs)
match(xs)
[] -> 0
| h:t -> 1 + length(t)
Our definition of length
does a pattern destructuring on its argument. If the pattern matches an empty list,
0
is returned. If the pattern matches a head and a tail pair, the length is 1
added to the length of tail.
We can write this function more compactly, by eliminating the explicit declaration of match
.
We also do not need to bind the h
variable because we don't use it. This can be replaced by the _
wildcard character.
function length(xs)
| [] -> 0
| _:t -> 1 + length(t)
Pattern matching can be done on any data type with a literal representation - numbers, strings, lists, arrays, hash tables, sets and so on. A few more examples follows:
function factorial(n)
| 0 -> 1
| _ -> n * factorial(n-1)
factorial(10)
// 3628800
factorial(3)
//6
// Evaluate arithmetic expressions in the
// format #{operation: [expr1, expr2]}, where `operation`
// is one of the four symbols - 'add, 'sub, 'mul and 'div.
// An expression can also be a numeric literal.
function calculate(expr)
| #{'add: [e1, e2]} -> calculate(e1) + calculate(e2)
| #{'sub: [e1, e2]} -> calculate(e1) - calculate(e2)
| #{'mul: [e1, e2]} -> calculate(e1) * calculate(e2)
| #{'div: [e1, e2]} -> calculate(e1) / calculate(e2)
| e where is_number(e) -> e
calculate(#{'add: [#{'mul: [10, 20]}, 500]})
// 700
calculate(#{'sub: [100, 20]})
// 80
calculate(#{'sub: [100, "ok"]})
//> error: no_match_found
The calculate
function makes use of the where
guard in the last pattern to make sure that
the value that gets bound to the variable is a number.
In addition to the built-in data structures, user defined records can also be destructured:3
record circle(radius)
record rectangle(width, length)
function area(shape)
| circle(radius) -> 3.14159 * (radius * radius)
| rectangle(width, length) -> width * length
area(circle(radius = 10.34))
//<PHONE_NUMBER>0399995
area(rectangle(width=20, length=52.78))
// 1055.6
A record pattern match can refer members by position. This is achieved by prefixing the member name by the @
character.
(This means record members are not allowed to start with the @
character). Let us rewrite the area
function
by destructuring the record members by position:
function area(shape)
| circle(@r) -> 3.14159 * (@r * @r)
| rectangle(@w, @l) -> @w * @l
If a function with an implicit match takes more than one parameter, all the arguments should be packaged into a list and passed to the pattern matcher:
function f(a, b)
| [1, b] -> b * 10
| [2, b] -> b * 100
f(1, 2)
// 20
f(2, 2)
// 200
Slogan support or-patterns
, which is a feature that allows us to collapse multiple clauses with identical right-hand sides
into a single clause:
function f(xs)
| [a, b]
| #[a, b]
| #(a, b) -> a * b
f([10, 20])
// 200
f(#[10, 20])
// 200
f(#(10, 20))
// 200
Repetition of the same pattern can be avoided by using the special pattern variable %
, which always refer to the previous
pattern checked.
match ([1, 2, 3])
[_, b, _] where b >= 10 -> 'hi
| % where b >= 1 -> 'hello
// hello
Now that we have covered the basics, let us write some code that exploits the true expressive power of pattern matching! We are going to implement a data structure that is often flagged as "advanced" in text books. This is the red-black tree - one of the most popular of all balanced binary trees.
In a red-black tree every node is colored either red or black and it satisfies the following two balance invariants:
These invariants guarantee that the longest possible path in the tree is not longer than the shortest possible path times two. (The longest path has alternating red and black nodes and the shortest path has only black nodes.)
These invariants are enforced while inserting a new node, using a balance
function. This function re-configures
all possible black-red-red paths into a red-black-black path. The black-red-red paths can occur in four configurations,
depending on whether the red node is a left or right child. The rewrite required is the same in all cases. Pattern matching makes it possible
to write the balance
function in a compact, declarative style:
function balance(color, t, z, d)
| ['b, ['r,['r,a,x,b],y,c], z, d]
| ['b, ['r,a,x,['r,b,y,c]], z, d]
| ['b, a, x, ['r,['r,b,y,c],z,d]]
| ['b, a, x, ['r,b,y,['r,c,z,d]]]
-> ['r,['b,a,x,b],y,['b,c,z,d]]
| _ -> [color, t, z, d]
The complete code for the red-black tree is available for download. For a detailed description of a red-black tree structure similar to the one presented here, please see the book "Purely functional data structures" by Chris Okasaki.
1By that definition, a string is also an aggregate data type because it is essentially an array of characters. We treated it as a basic data type because of its importance in performing many useful tasks, like searching for patterns in textual data.
2Pairs can be made out of any expressions. For e.g, the expression 1 + 2:100
will create the pair 3:100
. Keep in mind that function call expressions tends to bind tightly to the right. So if you want to glue
the two expressions 1 + inc(1)
and 100
into a pair, the first expression
must be enclosed in parenthesis, as in, (1 + inc(1)):100
. This will result in the pair 3:100
as expected.
3Pattern based destructuring can be performed on user-defined composite types as well. Slogan allows you to define your own composites that behave like lists and hash tables. This will be the subject of a later chapter.


From Node Package Manager:
npm install node-simple-router
From source:
git clone https://github.com/sandy98/node-simple-router
cd to your installation directory and runnpm test
then point your browser to http://localhost:8000 and review the info
and above all, try the examples.
You can roll your own, or use the sample server that NSR provides by means of the mk-server utility:
mk-server js
will provide a barebones server (server.js) with some example routes ready to run.
In order for this to work, you must have installed NSR global, like so:
sudo npm install -g node-simple-router
, or have the .bin directory of NSR in your path by whatever means you see fit.
Either case, the basic steps are the same:
var http = require('http');
var Router = require('node-simple-router');
var router = Router(); // may also be router = new Router();
router.get("/hello", function(request, response) {response.end("Hello, World!"};});
var server = http.createServer(router);
server.listen(1234);