text:
---
title: Components
---

A component is a collection of Kubernetes manifests including all resources needed for an application, such as a `Deployment`, a `Service` or a `Secret`.

## Folder Structure

A component should be placed in `components/<name>.js` or `components/<name>/index.js`.

```shell
.
└── components
    ├── foo
    │   └── index.js
    └── nginx.js
```

When you run [`kosko generate`](cli/generate.md), Kosko will find all files or folders in `components` folder that matching the pattern set in [`components`](configuration.md#components) configuration (it is `*` by default, which means everything in components folder). You can add component names or patterns to the command to specify which components to generate.

```shell
# Use `components` in `kosko.toml`.
kosko generate

# Specify which components to generate
kosko generate nginx dev_*
```

## Basic

Let's start with a basic component. In the following example, we will create a new file `components/busybox.js` that exports a `Pod`.

```ts ts2js
import { Pod } from "kubernetes-models/v1/Pod";

const pod = new Pod({
  metadata: { name: "busybox" },
  spec: {
    containers: [{ name: "busybox", image: "busybox" }]
  }
});

export default pod;
```

Then you can run [`kosko generate`](cli/generate.md) to print YAML.

```shell
kosko generate
# apiVersion: v1
# kind: Pod
# metadata:
#   name: busybox
# spec:
#   containers:
#     - name: busybox
#       image: busybox
```

At the first line, we import `Pod` class from [kubernetes-models] package. This is a separated package which is generated automatically from [Kubernetes OpenAPI Specification](https://github.com/kubernetes/kubernetes/tree/master/api/openapi-spec). It provides type definitions and validation. You can import corresponding resources as below.

```ts
// Class
import { Kind } from "kubernetes-models/<apiVersion>/<kind>";

// Interface
import { IKind } from "kubernetes-models/<apiVersion>/<kind>";
```

Kind can be omitted from the import path if you want to import multiple resources at a time. Please note that this might have impact on the module loading speed.

```ts
import { Pod, Service } from "kubernetes-models/v1";
```

[kubernetes-models] also supports custom resource definitions (CRDs). You can see [here](https://github.com/tommy351/kubernetes-models-ts#3rd-party-models) for a full list of supported 3rd-party models.

```ts
import { Certificate } from<EMAIL_ADDRESS>```

If the CRD package is not available yet, or you want to skip validation on certain manifests, Kosko also supports plain objects.

```ts
const pod = {
  apiVersion: "v1",
  kind: "Pod"
};
```

## Export More Manifests

In the following example, we will create a file `components/nginx.js` that exports a `Deployment` and `Service`.

```ts ts2js
import { Deployment } from "kubernetes-models/apps/v1/Deployment";
import { Service } from "kubernetes-models/v1/Service";

const labels = { app: "nginx" };

const deployment = new Deployment({
  metadata: { name: "nginx" },
  spec: {
    selector: {
      matchLabels: labels
    },
    template: {
      metadata: { labels },
      spec: {
        containers: [{ name: "nginx", image: "nginx" }]
      }
    }
  }
});

const service = new Service({
  metadata: { name: "nginx" },
  spec: {
    selector: labels,
    ports: [{ port: 80 }]
  }
});

export default [deployment, service];
```

At the last line, we replace the export value with an array. So when you run [`kosko generate`](cli/generate.md), it will print YAML as below.

```shell
kosko generate
# ---
# apiVersion: apps/v1
# kind: Deployment
# (omitted)
# ---
# apiVersion: v1
# kind: Service
# (omitted)
```

### Function

You can also export a function that returns an array of manifests.

```ts
export default function () {
  return [new Deployment(), new Service()];
}
```

### Async Function

```ts
export default async function () {
  return [new Deployment(), new Service()];
}
```

### Iterable

Besides array, objects which implements [the iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol), such as `Set`, `Map` or generator functions, are also supported.

```ts
// Set
export default new Set([new Deployment(), new Service()]);

// Generator function
function* gen() {
  yield new Deployment();
  yield new Service();
}

export default gen();
```

### Async Iterable

```ts
// Async generator function
async function* gen() {
  yield new Deployment();
  yield new Service();
}

export default gen();
```

## Nested Manifests

:::info
Available since v1.0.0.
:::

All of the patterns we just mentioned above can be combined together. It is very useful for reusing manifests across components.

For example, we can create a function that returns a database as a resource, and use it later in components.

```ts ts2js
import { Deployment } from "kubernetes-models/apps/v1/Deployment";
import { Service } from "kubernetes-models/v1/Service";

function createDatabase(name: string) {
  const metadata = { name: `${name}-db` };
  return [new Deployment({ metadata }), new Service({ metadata })];
}

export default [
  createDatabase("my-app"),
  new Deployment({ metadata: { name: "my-app" } }),
  new Service({ metadata: { name: "my-app" } })
];
```

All manifests in arrays and functions will be flattened. Below is YAML output.

```yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-db
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-db
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
```

[kubernetes-models]: https://github.com/tommy351/kubernetes-models-ts

gha_language: TypeScript


text:
# SwiftAppirater

[![CI Status](http://img.shields.io/travis/Zhou Hao/SwiftAppirater.svg?style=flat)](https://travis-ci.org/Zhou Hao/SwiftAppirater)
[![Version](https://img.shields.io/cocoapods/v/SwiftAppirater.svg?style=flat)](http://cocoapods.org/pods/SwiftAppirater)
[![License](https://img.shields.io/cocoapods/l/SwiftAppirater.svg?style=flat)](http://cocoapods.org/pods/SwiftAppirater)
[![Platform](https://img.shields.io/cocoapods/p/SwiftAppirater.svg?style=flat)](http://cocoapods.org/pods/SwiftAppirater)

A Swift version of [Appirater](https://github.com/arashpayan/appirater).

## Example

To run the example project, clone the repo, and run `pod install` from the Example directory first.

## Usage

## Installation

SwiftAppirater is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

```ruby
pod "SwiftAppirater"
```

## TODO

- Need fully test.
- Unit test.

## Author

Zhou Hao<EMAIL_ADDRESS>
## License

SwiftAppirater is available under the MIT license. See the LICENSE file for more info.

license: MIT

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
# remedy

Remedy is yet another translator from markdown to
[reveal.js](http://lab.hakim.se/reveal-js/#/). It is very similar to other
solutions to the same problem, but it allows for a bit more control over the
resulting html document. Specifically, you can pipe in additional header code
and thus include custom css and javascript. Furthermore, you can have
individual slides be marked by certain keywords.

Note that remedy requires python3.

## Installation

Should just be a simple

    pip install remedy

Alternatively, you can run the `setup.py`.

## Simple example

Imagine the following markdown script

    # My first remedy

    ---

    ## Remedy is no solution for everything

    - You might want to use reveal directly
    - there are other markdown to reveal.js converters

    ---html,subslide

    <div class='special-class'>
        Something is happening in here that's to complicated to express in markdown.
        Maybe something that requires elaborate styling or javascript?
    </div>

    ---subslide

    ## Another markdown slide

    We all know how to write markdown, right?

    ---

    ## Final slide

    Good bye!

stored in `slides.md`. You can then use

    python -m remedy slides.md

To create an html file called `presentation.html` that contains a slide show
for your presentation.

Maybe, we also have an additional bit of header code in a separate file
`header_mod.html` that styles your `"special-class"`:

    <style>
    .special-class {
        font-size: 24pt !important;
    }
    </style>

This can be included by simply calling

    python -m remedy --header=header_mod.html slides.md

Try `python -m remedy -h` for more options.

## Contributing

I believe that `remedy` is a pretty nice tool if you do so too, but you miss
that one really neat feature. Code it yourself and send me a pull request. If
you find a bug, ideally fix it yourself and send me a pull request.

Note that there are tests. They should pass after you apply your changes. Also,
I'm trying to stick to pep8 with respect to code formatting. You should do so
as well.

## Tests

Remedy has two end to end tests that check the examples in this readme:
![test results](https://travis-ci.org/igordertigor/remedy.svg?branch=master)

repository: igordertigor/remedy

repo_name: igordertigor/remedy


text:
# Changelog

## 0.3.2+1
- fix a strong mode issue in the generated Dart library

## 0.3.2
- expose the `PausePostRequest` event

## 0.3.1
- fix a parsing issue with ExtensionData

## 0.2.4
- expose the service protocol timeline API
- add the new `None` event type

## 0.2.3
- include the name of the calling method in RPC errors

## 0.2.2
- fixed several strong mode analysis issues

## 0.2.1
- upgrade to service protocol version `3.3`

## 0.2.0
- upgrade to service protocol version `3.2`

## 0.1.2
- fixed a bug with the `ServiceExtensionAdded` event

## 0.1.1
- expose the new 'Extension' event information

## 0.1.0
- rev to 0.1.0; declare first stable API version

## 0.0.13
- improve the toString() message for RPCError

## 0.0.12
- bug fix for parsing MapAssociations

## 0.0.11
- bug fix to the service extension API

## 0.0.10
- expose a service extension API

## 0.0.9
- update to the latest spec to capture the `Event.inspectee` field

## 0.0.8
- allow listening to arbitrary event types
- use Strings for the enum types (to allow for unknown enum values)

## 0.0.7
- make the diagnostic logging synchronous
- remove a workaround for a VM bug (fixed in 1.13.0-dev.7.3)
- several strong mode fixes

## 0.0.6
- added `exceptionPauseMode` to the Isolate class
- added `hashCode` and `operator==` methods to classes supporting object identity
- work around a VM bug with the `type` field of `BoundVariable` and `BoundField`

## 0.0.5
- added more dartdocs
- moved back to using Dart enums
- changed from optional positional params to optional named params

## 0.0.4
- enum redux

## 0.0.3
- update to use a custom enum class
- upgrade to the latest service protocol spec

## 0.0.2
- added the `setExceptionPauseMode` method
- fixed an issue with enum parsing

## 0.0.1
- first publish
- upgraded the library to the 3.0 version of the service protocol
- upgraded the library to the 2.0 version of the service protocol
- copied basic Dart API generator from Atom Dart Plugin
  https://github.com/dart-atom/dartlang/tree/master/tool
- refactored Dart code to generate Java client as well as Dart client


text:
# Welcome to hook!

hook is a RESTful, extendable Backend as a Service that provides instant backend
to develop sites and apps faster, with dead-simple integration for iOS, Android,
JavaScript and more.

It follows the same principles from [nobackend](http://nobackend.org/), [hoodie.js](https://github.com/hoodiehq/hoodie.js) and [Parse](http://parse.com)

**Requirements**: PHP 5.4+, or [PHP 5.3](More/Deployment/#deploying-on-php-53).

## Front-end Integration Libraries

Reduce the gap between backend and frontend development:

- [JavaScript](https://github.com/doubleleft/hook-javascript) ([docs](http://doubleleft.github.io/hook-javascript))
- [C# / Unity3D](https://github.com/doubleleft/hook-csharp)
- [Corona SDK](https://github.com/doubleleft/hook-corona-sdk)
- [iOS / OSX](https://github.com/doubleleft/hook-swift)
- [Java / Android](https://github.com/doubleleft/hook-android)
- [C++](https://github.com/doubleleft/hook-cpp)
- [PHP](https://github.com/doubleleft/hook-php) ([docs](http://doubleleft.github.io/hook-php))
- [Ruby](https://github.com/doubleleft/hook-ruby) ([docs](http://doubleleft.github.io/hook-ruby/))
- [Flash / ActionScript 3.0](https://github.com/doubleleft/hook-as3)

repository: doubleleft/hook-userguide

repo_name: doubleleft/hook-userguide


text:
# AccountsV1CredentialAws

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Sid** | Pointer to **string** | The unique string that we created to identify the AWS resource. |
**AccountSid** | Pointer to **string** | The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the AWS resource. |
**FriendlyName** | Pointer to **string** | The string that you assigned to describe the resource. |
**DateCreated** | Pointer to [**time.Time**](time.Time.md) | The date and time in GMT when the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format. |
**DateUpdated** | Pointer to [**time.Time**](time.Time.md) | The date and time in GMT when the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format. |
**Url** | Pointer to **string** | The URI for this resource, relative to `https://accounts.twilio.com` |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

repository: twilio/twilio-go

branch_name: refs/heads/main

gha_language: Go

gha_license_id: MIT

repo_name: twilio/twilio-go


text:
# Project Title

One Paragraph of project description goes here

## Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

### Prerequisites

What things you need to install the software and how to install them

```
Give examples
```

### Installing

A step by step series of examples that tell you how to get a development env running

Say what the step will be

```
Give the example
```

And repeat

```
until finished
```

End with an example of getting some data out of the system or using it for a little demo

## Running the tests

Explain how to run the automated tests for this system

### Break down into end to end tests

Explain what these tests test and why

```
Give an example
```

### And coding style tests

Explain what these tests test and why

```
Give an example
```

## Versioning

We use [Github](http://github.org/) for versioning.

## Authors

* **Anthony ADELAIDE**
* **Yassine AKRAFI**

See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

## Acknowledgments

* Hat tip to anyone whose code was used
* Inspiration
* etc

repository: ArK-Ade/QualiteLog

repo_name: ArK-Ade/QualiteLog


text:
# Local Zoo

#### Angular JS Independent Project, 06/09/2017

#### By Brian Fan

## Description

Local Zoo is a web application to track animals for zoo. Zoo staff can add and update the existing animal data. Also, he or she would be able to sort the animal by animal's age group.

## Planning

1. Configuration/dependencies
  * Angular CLI version 1.1.0
  * Bootstrap v4.0.0-alpha.6

2. Specs
  * Spec 1: Generate 3 components to display animal detail, add new animal, and edit animal info.
  * Spec 2: Hardcode animals data and display on template in animal detail component.
  * Spec 3: Add new form and functionality to collect user input to add new animal.
  * Spec 4: Edit existing animal data.
  * Spec 5: Filter animal data by age group.

3. Potential future functionalities
  * Save animal data to database
  * See animal detail at single page
  * Let user to delete animal data
  * Display animal by youngest to oldest
  * Import animal data through API.

4. UX/UI
  * Install and use Bootstrap 4

## Prerequisites

You will need the following things properly installed on your computer.
* [Git](https://git-scm.com/)
* [Node.js](https://nodejs.org/) (with NPM)
* [Angular CLI](https://cli.angular.io/)

## Installation

* `git clone https://github.com/txbluebee/local-zoo`
* `cd local-zoo`
* `npm install`

## Running / Development

* `ng serve`
* Visit your app at [http://localhost:4200](http://localhost:4200).

## Technologies Used

_HTML_

_SCSS_

_Bootstrap_

_TypeScript_

_Angular.js_

### License

Copyright (c) 2017 Brian Fan
The website is licensed under the MIT license.

repository: txbluebee/local-zoo

repo_name: txbluebee/local-zoo


text:
# Pool Monitoring & Control - ESP32 Application

Requires at least ESP IDF v3.0rc1.

Raspberry Pi side of the project: [DavidAntliff/poolmon](https://github.com/DavidAntliff/poolmon)

[system block diagram, software architecture diagram and ESP32 schematic](https://easyeda.com/ef784f36/Test_Project-2fcb46b5097649a4b018bc6c12a2d6d0)

Veroboard [design](https://www.draw.io/?lightbox=1&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Veroboard.xml#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FDavidAntliff%2Fpoolmon%2Fmaster%2Fsupport%2Fboard%2FVeroboard.xml)

## Notes

### One Wire Bus

The DS18B20 needs extra current for EEPROM writes and Temperature measurements.

https://www.maximintegrated.com/en/app-notes/index.mvp/id/4255

Vpup is the pullup voltage.

Vpupmin is the minimum pull up voltage and is usually 2.8V (not sure how this can be calculated from datasheet).

For a given Vpup and Rpup, the difference between Vpup and Vpupmin determines the current available for special functions:

    Iavail = (Vpup - Vpip_min) / Rpup

For the DS18B20 at 3.3V:

    Vpup = 3.3V
    Rpup = 4.7kΩ
    Vpupmin = 2.8V
    => Iavail = 0.106mA

This is probably too low for a single device.

TODO: calculate a better Rpup resistor value.

## MQTT

Subscribe to all messages:

```
$ mosquitto_sub -h rpi -v -t \#
```

Send a message (e.g. reset ESP32):

```
$ mosquitto_pub -h rpi -t poolmon/esp32/reset -m 1
```

Update OTA (use the .bin file):

Locally:
```
$ python -m http.server --directory build/
```

```
$ mosquitto_pub -h <IP_ADDRESS> -t poolmon/ota/url -m "http://<IP_ADDRESS>:8000/esp32-poolmon.bin"
$ mosquitto_pub -h rpi -t poolmon/esp32/reset -m 1
```

NOTE: Things to check before doing OTA!

* The WiFi credentials in the new .bin match the current ones,
* The partition table is set to Factory + 2 x OTA (not the default!)
* The FLASH size is set to 4 MB


text:
---
title: React Native push notification using Batch and Fastlane
date: '2017-03-15'
summary: ''
tags:
  - React Native
  - React
  - Batch
  - Push notifications
  - Google
  - Apple
---

Following on my previous post on setting up
[Continuous Deployment for React Native](/archives/2017/02/01/continuous-integration-for-react-native-with-testfairy-testflight-deploy/),
this post outlines how to get push notifications working reliably for both
Android and iOS using [Batch](https://batch.com) as the intermediary that sits
between your server and Google's and Apple's push servers.

For the app I'm working on there were a number of requirements:

* Ability to push a message to devices in batches of 1000's at a time.
* Ability to handle a push notification differently depending on whether the
app is in the foreground or background
* Ability to know if/when app was started due to the user clicking on a push
notification
* Ability to know if user has disabled push notifications for the app via their
device settings, and if so, to be able to take them to their settings page
* On iOS, the ability to choose when we ask the user for push notification
permissions instead of automatically at app startup.

_Why use Batch and not just make direct calls to Apple and Google's
servers?_

Batch and other push notification services like it abstract away the differences
in dealing with Apple's and Google's services. Batch in particular provides a
transactional API which allows you to [push a message to upto 10000 devices](https://batch.com/doc/api/transactional.html)
at a time, all through a simple REST API.

Another advantage is that it provides an online interface through which you can
easily test push notifications without having to write any code yourself.
Finally, if you're just using the transactional API without the need to push
JSON data (i.e. silent notifications) it's [free to use](https://batch.com/pricing).

## The push notifications process

**iOS**

In order to receive a push notification in your app, the following must happen:

1. Request push notifications permission (the user will be shown
  a native dialog asking for permission)
2. If permission is granted then APNS (Apple Push Notification Service) will
issue a _token_ which is unique to your app and the user's device. If you
restart your app the token will be generated as soon as it's requested, since
the user has already previously granted permission.
3. The token must be sent along with a notification message to Batch, which
will then call through to APNS to send a push notification to the device

**Android**

The procedure is the same as for iOS (see above) except that the user does not
get prompted with a dialog asking for permission - the permission is granted by
default.

The token is generated by FCM (Firebase Cloud Messaging), Google's equivalent to
APNS. It is made use of in the same way (i.e. sending it to Batch).

### What if the user declines permission?

If the user declines push notification permission, either via the prompted dialog
or manually in their app settings then a dialog will not get shown again. Thus
you must first instruct the user to re-enable push notifications manually before
asking for a registration token.

## Android setup

You first need to setup FCM (Firebase Cloud Messaging) for your Android app:

1. Sign up at [https://console.firebase.google.com/](https://console.firebase.google.com/)
1. Create a new Android app (with the right package name for your app)
1. Download the `google-services.json` file and place it in `<project folder>/android/app`
1. Note down the cloud messaging _server key_ and _sender ID_:

![screenshot](fcm-settings.png)

_Note: You can use either the legacy or non-legacy key, both are fine._

We will enter these details into Batch later on (see below) so that it will be
able to push to our Android app.

## iOS Setup

_Note: I will assume you are using [Match](https://github.com/fastlane/fastlane/tree/master/match)
for managing your certificates and provisioning profiles._

Go into the Apple Developer portal and create new _Development_ and _Production_
push certificates for your app:

![screenshot](apn-push.png)

Now you just need to re-generate your provisioning profiles from scratch:

```shell
$ bundle exec fastlane match --force development
$ bundle exec fastlane match --force adhoc
$ bundle exec fastlane match --force appstore
```

The _Development_ push certificate is used with the development provisioning
profile, and the _Production_ with Ad-hoc and Appstore profiles.

If you build your app in _Release_ mode then it will must use either the Ad-hoc
or Appstore profile. In _Debug_ mode it must use the development profile.
Since iTunes/TestFlight recommends using the Appstore profile here is how your
profile settings should look in XCode:

![screenshot](xcode-profiles.png)

## Batch dashboard setup

You need to create **2 apps** in your Batch account, one for each platform.

For the Android app you need to enter your FCM settings you obtained earlier:

![screenshot](batch-android-settings.png)

_Note: Default priority is set to high to ensure rapid message delivery._

For iOS app you first need to export your _Production_ push certificate as a `.p12`
file ([see instructions](https://batch.com/doc/ios/prerequisites.html#_generating-the-p12-file))
and then upload it into Batch:

![screenshot](batch-ios-settings.png)

## App native integration

The next piece of the puzzle is setting up the platform-native part of the app
to enable it to receive push notifications.

### iOS

If you integrate the Batch SDK in the default recommended way you end up with a
situation where the user is asked for push notifications permission as soon as
the app starts.

To avoid this it's better to opt for [manual integration](https://batch.com/doc/ios/advanced/manual-integration.html) and then
use React Native's [built-in push API](http://facebook.github.io/react-native/releases/0.42/docs/pushnotificationios.html#pushnotificationios) to ask for permissions.

Once you've added the Batch SDK to your project, modify your `AppDelegate` as such:

```
/* AppDelegate.h */

#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) NSData *devicePushToken; // for storing the token given to us by APNS
@end
```

```
/* AppDelegate.m */

#import "AppDelegate.h"

@import Batch;
#import <React/RCTPushNotificationManager.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings]<EMAIL_ADDRESS>fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"myMobileApp"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  // Start Batch.
  [BatchPush disableAutomaticIntegration];
  [Batch startWithAPIKey:@"58459349083048038"];

  return YES;
}

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
  [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];

  self.devicePushToken = deviceToken;
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  [RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification
{
  [RCTPushNotificationManager didReceiveRemoteNotification:notification];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
  [RCTPushNotificationManager didReceiveLocalNotification:notification];
}

@end
```

Note the use of the Batch API key. This is obtained from your Batch dashboard
for your iOS app:

![screenshot](batch-api-key.png)

_Note: If you're only using Batch for its transactional push API (as this post
  is showing) then you only every need to use the LIVE api key, and can ignore
  the DEV one._

When the app starts up, one of the following two happen:

* If the user hasn't previously enabled push notifications then nothing happens.
* If the user HAS previously enabled push notifications then the obtained token
is stored in the `devicePushToken` member of `AppDelegate` for use later on (see below).

When doing manual integration, the APNS-provided push token must be passed to
Batch manually. Let's create a `Notifications` module which you can call through
to from Javascript:

```
/* Notifications.h */

#ifndef Notifications_h
#define Notifications_h
#import <React/RCTBridgeModule.h>
@interface Notifications : NSObject<RCTBridgeModule>
@end
#endif
```

```
/* Notifications.m */

#import <Foundation/Foundation.h>
#import "AppDelegate.h"
#import "Notifications.h"
@import Batch;
@implementation Notifications

// Expose this module to the React Native bridge
RCT_EXPORT_MODULE(Notifications)

RCT_EXPORT_METHOD(setPushToken:(NSString *)token) {
  AppDelegate* app = (AppDelegate*)[[UIApplication sharedApplication] delegate];

  NSLog(@"RNBatch: setPushToken: passed-in = %@, stored = %@", token, app.devicePushToken);

  [BatchPush handleDeviceToken:app.devicePushToken];
}

@end
```

Finally, enable push notifications in the app's capability list:

![screenshot](xcode-push-1.png)
![screenshot](xcode-push-2.png)

### Android

Android integration needs a bit more work since there is not yet a React Native
built-in push notifications API for Android. Most importantly, you want to know
within Javascript when the user receives a notification.

Once you've added the Batch SDK to your project, modify `AndroidManifest.xml`:

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
  ...

  <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
  <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>

  <application ...>
    ...

    <!-- Handle recieved pushes -->
    <service android:name="com.mycompany.myapp.notifications.PushService" />
    <receiver android:name="com.mycompany.myapp.notifications.PushReceiver" android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="${applicationId}" />
        </intent-filter>
    </receiver>
    <!-- Push token registration listeners -->
    <service android:name="com.mycompany.myapp.notifications.InstanceIdService" android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
    <service android:name="com.batch.android.BatchPushInstanceIDService" android:exported="true">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID"/>
        </intent-filter>
    </service>
    <!-- Handle notification messages which get clicked/processed -->
    <service android:name="com.mycompany.myapp.notifications.MessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

  </application>
</manifest>
```

Let's write these one by one.

First we need a component which listens for new push tokens assigned by FCM:

```java
package com.mycompany.myapp.notifcations;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class InstanceIdService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        // Broadcast refreshed token to all Activity instances
        Intent i = new Intent("RefreshToken");
        Bundle bundle = new Bundle();
        bundle.putString("token", 'RefreshToken');
        i.putExtras(bundle);
        sendBroadcast(i);
    }
}
```

We need a `MessagingService` which will handle received push messages:

```java
package com.mycompany.myapp.notifications;

import android.content.Intent;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Intent i = new Intent("Message");
        i.putExtra("data", remoteMessage);
        sendOrderedBroadcast(i, null);
    }
}
```

Handle the push notification once the app gets woken up:

```java
package com.mycompany.myapp.notifications;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

public class PushReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ComponentName comp = new ComponentName(context.getPackageName(), PushService.class.getName());
        startWakefulService(context, intent.setComponent(comp));
        setResultCode(Activity.RESULT_OK);
    }
}
```

Handle the _Message_ intents:

```java
package com.mycompany.myapp.notifications;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

import com.batch.android.Batch;

public class PushService extends IntentService
{
    @Override
    protected void onHandleIntent(Intent intent)
    {
        try
        {
            if( Batch.Push.shouldDisplayPush(this, intent) )
            {
                // show notification icon and display only if app is NOT in foreground
                if (!State.getInstance().isInForeground()) {
                    Batch.Push.displayNotification(this, intent);
                }
            }
        }
        finally
        {
            PushReceiver.completeWakefulIntent(intent);
        }
    }
}
```

The `State` object used above is just a singleton used to track whether the
app is in the foreground or not:

```java
package com.mycompany.myapp.notifications;

public class State {
    private static State ourInstance = new State();

    public static State getInstance() {
        return ourInstance;
    }

    private boolean inForeground = false;

    public boolean isInForeground() {
        return this.inForeground;
    }

    public void setIsInForeground(boolean val) {
        this.inForeground = val;
    }
}
```

Finally, the big one. The `Notifications` module which will send the token and
any incoming notification up into Javascript layer, and expose methods to be
called from therein (most of this code is derived from
  [react-native-fcm](https://github.com/evollu/react-native-fcm)):

```java
package com.mycompany.myapp.notifications;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.RemoteMessage;

import android.os.Bundle;

import android.content.Context;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class NotificationsModule extends ReactContextBaseJavaModule implements LifecycleEventListener, ActivityEventListener {
    private Intent initIntent;

    public NotificationsModule(ReactApplicationContext reactContext) {
        super(reactContext);
        getReactApplicationContext().addLifecycleEventListener(this);
        getReactApplicationContext().addActivityEventListener(this);
        registerTokenRefreshHandler();
        registerMessageHandler();
    }

    @Override
    public Map<String, Object> getConstants() {
        Map<String, Object> constants = new HashMap<>();
        return constants;
    }

    @Override
    public String getName() {
        return "Notifications";
    }

    @ReactMethod
    public void getToken(Promise promise) {
        promise.resolve(FirebaseInstanceId.getInstance().getToken());
    }

    private void sendEvent(String eventName, Object params) {
        if (getReactApplicationContext().hasActiveCatalystInstance()) {
            getReactApplicationContext()
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit(eventName, params);
        }
    }

    private void sendNotificationToApp(Object params) {
        sendEvent("notification", params);
    }

    private void registerTokenRefreshHandler() {
        IntentFilter intentFilter = new IntentFilter("RefreshToken");
        getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (getReactApplicationContext().hasActiveCatalystInstance()) {
                    String token = intent.getStringExtra("token");
                    sendEvent("pushToken", token);
                    abortBroadcast();
                }
            }
        }, intentFilter);
    }

    private void registerMessageHandler() {
        IntentFilter intentFilter = new IntentFilter("Message");

        getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (getReactApplicationContext().hasActiveCatalystInstance()) {
                    RemoteMessage message = intent.getParcelableExtra("data");
                    WritableMap params = Arguments.createMap();
                    if(message.getData() != null){
                        Map data = message.getData();
                        Set<String> keysIterator = data.keySet();
                        for(String key: keysIterator){
                            params.putString(key, (String) data.get(key));
                        }
                        sendNotificationToApp(params);
                        abortBroadcast();
                    }
                }
            }
        }, intentFilter);
    }

    private WritableMap parseIntent(Intent intent){
        WritableMap params;
        Bundle extras = intent.getExtras();
        if (extras != null) {
            try {
                params = Arguments.fromBundle(extras);
            } catch (Exception e){
                Log.e(TAG, e.getMessage());
                params = Arguments.createMap();
            }
        } else {
            params = Arguments.createMap();
        }
        WritableMap fcm = Arguments.createMap();
        fcm.putString("action", intent.getAction());
        params.putMap("fcm", fcm);
        params.putInt("opened_from_tray", 1);
        return params;
    }

    @Override
    public void onHostResume() {
        State.getInstance().setIsInForeground(true);

        if (initIntent == null){
            //the first intent is initial intent that opens the app
            Intent newIntent = getCurrentActivity().getIntent();
            sendEvent("initialNotification", parseIntent(newIntent));
            initIntent = newIntent;
        }
    }

    @Override
    public void onHostPause() {
        State.getInstance().setIsInForeground(false);
    }

    @Override
    public void onHostDestroy() {
        State.getInstance().setIsInForeground(false);
    }

    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
    }

    @Override
    public void onNewIntent(Intent intent){
        sendNotificationToApp(parseIntent(intent));
    }
}
```

And as with any React Native native module for Android there has to be an
accompanying `ReactPackage`:

```java
package com.mycompany.myapp.notifications;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class NotificationsPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new NotificationsModule(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList();
    }
}
```

To complete Batch integration, the `MainActivity` will look like this:

```java
package com.mycompany.myapp;

import android.content.Intent;

import com.batch.android.Batch;
import com.facebook.react.ReactActivity;

public class MainActivity extends ReactActivity {
    @Override
    protected String getMainComponentName() {
        return "myMobileApp";
    }

    @Override
    protected void onStart()
    {
        super.onStart();
        Batch.onStart(this);
    }

    @Override
    protected void onStop()
    {
        Batch.onStop(this);
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        Batch.onDestroy(this);
        super.onDestroy();
    }

    @Override
    public void onNewIntent(Intent intent)
    {
        Batch.onNewIntent(this, intent);
        super.onNewIntent(intent);
    }
}
````

And the `MainApplication`:

```java
package com.mycompany.myapp;

import android.app.Application;
import android.content.Context;

import com.batch.android.Batch;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage;
import com.mycompany.myapp.notifications.NotificationsPackage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected List<ReactPackage> getPackages() {
      return new ArrayList<>(Arrays.asList(
          new MainReactPackage(),
          new ReactNativePermissionsPackage(),
          new NotificationsPackage()
      ));
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();

    Batch.Push.setGCMSenderId('983247928738492');
    Batch.Push.setManualDisplay(true);
    Batch.setConfig(new com.batch.android.Config("58459349083048038"));

    SoLoader.init(this, /* native exopackage */ false);
  }
}
```

As you can see above, you need both the FCM/GCM _Sender ID_ you obtained from
FCM, and your Batch API key from within the Batch dashboard. Note that the API
key should be the one for the Android app, not the iOS app.

## Javascript layer

Finally, let's see how to hook things up in the Javascript layer.

Let's build a unified interface doing push notifications. First, define the
`PushBase` class:

```js
/* PushBase.ios */

import Q from 'bluebird'

export default class PushBase {
  checkPermission () {
    return this._checkPermission()
  }

  askForPermission () {
    return this._requestPermission()
  }

  getToken () {
    return this.token
  }

  initService () {
    return Q.try(() => {
      if (!this.initialized) {
        this.initialized = true

        return this._initService()
      }
    })
  }

  clearAppIconBadgeNumber () {
    this._clearBadge()
  }

  _onError = (err) => {
    console.warn(err)
  }

  _onRegisterToken = (token) => {
    this.token = token

    this._sendTokenToNativeLayer()

    /* TODO: push token to server */
  }

  _onNotification = (notification) => {
    console.log('Raw notification:', notification)

    const parsed = this._parseNotification(notification)

    if (parsed) {
      /* TODO: handle push notification */
    }
  }

  _parseNotification = (n) => n

  _clearBadge () {}

  _sendTokenToNativeLayer = (token) => {}
}
```

This base class exposes three methods:

* `initService()` - initialise push notifications service and obtain a token from
APNS/FCM
* `checkPermission()` - check to see if push notifications is enabled for the app
* `askForPermission()` - ask the user for push notifications permission (if not already enabled)

Each method will call through to methods implemented in subclasses.

**Android**

```js
/* PushAndroid.js */

import Q from 'bluebird'
import { NativeModules, DeviceEventEmitter } from 'react-native'
import PushBase from './PushBase'

const NativeNotifications = NativeModules.Notifications

class PushAndroid extends PushBase {
  constructor () {
    super()

    DeviceEventEmitter.addListener('notification', this._onNotification)
    DeviceEventEmitter.addListener('pushToken', this._onRegisterToken)
  }

  _checkPermission () {
    // in Android notifications are enabled by default
    return Q.resolve(true)
  }

  _requestPermission () {
    // in Android notifications are enabled by default
    return Q.resolve(true)
  }

  _initService () {
    return NativeNotifications.getToken()
    .then(this._onRegisterToken)
    .then(() => {
      if (this._initialNotification) {
        const n = this._initialNotification
        this._initialNotification = null
        n.background = true
        this._onNotification(n)
      }
    })
  }

  _parseNotification = (n) => {
    const ret = n.batchPushPayload || (n.title ? n : null)

    if (n && ret) {
      ret.background = !!n.background
    }

    return ret
  }
}

const push = new PushAndroid()
export default push

DeviceEventEmitter.addListener('initialNotification', (data) => {
  push._initialNotification = data
})
```

The `PushAndroid` class communicates with the native `Notifications` module we
created earlier. It asks for a token during initialisation. It also listens for the
`initialNotification` event, to capture the cases where the app was started due
to the user clicking on a notification.

Note that the notification object which gets passed to `_onNotification()`
will just be a JSON object, and will have the `background` key set to `true` if
the notification was received whilst the app was in the background or not running
 at all.

 This lets you apply different logic depending on how the notification
 was received. For example, if a notification is received when your app is in
 the foreground you may wish to show a popup to the user. Whereas in other
 cases you may wish to automatically navigate the user to the relevant page
 within your app according to the notification's meaning.

**iOS**

```js
/* PushIos.js */

import Q from 'bluebird'
import { PushNotificationIOS, NativeModules } from 'react-native'
import PushBase from './PushBase'

class PushIos extends PushBase {
  constructor () {
    super()

    PushNotificationIOS.addEventListener('register', this._onRegisterToken)
    PushNotificationIOS.addEventListener('registrationError', this._onError)
    PushNotificationIOS.addEventListener('notification', this._onNotification)
  }

  _checkPermission () {
    return PushNotificationIOS.checkPermissions((state)
    .then((state) => ( this._isEnabled(state) ? true : false ))
  }

  _requestPermission () {
    return PushNotificationIOS.requestPermissions()
    .then((state) => ( this._isEnabled(state) ? true : false ))
  }

  _initService () {
    return this._requestPermission()
    .then(() => {
      return PushNotificationIOS.getInitialNotification().then((notification) => {
        if (notification) {
          notification.background = true
          this._onNotification(notification)
        }
      })
    })
  }

  _parseNotification = (n) => {
    const ret = n._data

    if (n && ret) {
      ret.background = !!n.background
    }

    return ret
  }

  _clearBadge () {
    PushNotificationIOS.setApplicationIconBadgeNumber(0)
  }

  _sendTokenToNativeLayer = (token) => {
    NativeModules.Notifications.setPushToken(this.token)
  }

  _isEnabled (state) {
    return _.get(state, 'alert') || _.get(state, 'badge') || _.get(state, 'sound')
  }
}

export default new PushIos()
```

Same as for `PushAndroid`, `PushIos` also sets the `background` key to `true` if
a notification was received whilst the app was not in the foreground.

Notice that the when checking or asking for permission, the code parses the
resulting notification permission state to verify that atleast one type of
notification mechanism is enabled for the app (sound, badge and/or alert).

Also note that it calls through to the the native `Notifications` module once a
token is available, to ensure that the Batch iOS native layer gets initialised.
It doesn't strictly need to pass the token through (since we already obtain and
  save it in the native layer), this is just for convenience.

## Permission detection

So far all the original requirements have been met, except one:

* ~~Ability to push a message to devices in batches of 1000's at a time.~~
* ~~Ability to handle a push notification differently depending on whether the
app is in the foreground or background~~
* ~~Ability to know if/when app was started due to the user clicking on a push
notification~~
* Ability to know if user has disabled push notifications for the app via their
device settings, and if so, to be able to take them to their settings page
* ~~On iOS, the ability to choose when we ask the user for push notification
permissions instead of automatically at app startup.~~

However this is now trivial to achieve given the methods for checking and
asking for permission. To take a user to the device settings page associated
with your app you can do:

```js
import { Linking } from 'react-native'
Linking.openURL('app-settings:').catch(console.warn)
```

If you do this then you'll also want to recheck permissions once the user returns
to your app. This can be accomplished by listening in for app state changes
using the built-in [AppState](http://facebook.github.io/react-native/releases/0.42/docs/appstate.html#appstate) API.

## Triggering push notifications from your server

In the `PushBase` class above you'll notice the `_onRegisterToken()` method:

```js
_onRegisterToken = (token) => {
  this.token = token

  this._sendTokenToNativeLayer()

  /* TODO: push token to server */
}
```

In the final part of this method you would send the push token to your server.
Once the server has the token, triggering a push notification to be sent to
the device is just a matter of using [the Batch API](https://batch.com/doc/api/transactional.html).

Note the `sandbox` parameter:

![screenshot](batch-sandbox.png)

For iOS, it must be set to `true` if pushing to a `Debug` build of your app
(since this type of  build uses a `Development` provisioning profile). For
`Release` builds and any build of the Android app you should have it set to `false`.

gha_language: JavaScript


text:
# XRDevicePose

The **`XRDevicePose`** of the WebXR Device API describes the position and orientation of an XRDevice relative to the XRCoordinateSystem it was queried with. It also describes the view and projection matrices that should be used by the application to render a frame of an AR/VR scene.

## Properties

poseModelMatrix

Returns a matrix that defines the position and orientation of a viewer's head or device.

## Methods

getViewMatrix()

Takes an XRView object and returns a matrix describing the view transform to be used when rendering the passed XRView. The matrices represent the inverse of the model matrix of the associated viewpoint.

## Examples

TBD

```
function onDrawFrame(timestamp, xrFrame) {
  // Do we have an active session?
  if (xrSession) {
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    gl.bindFramebuffer(xrSession.baseLayer.framebuffer);

    for (let view of xrFrame.views) {
      let viewport = xrSession.baseLayer.getViewport(view);
      gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
      drawScene(view, pose);
    }

    // Request the next animation callback
    xrSession.requestAnimationFrame(onDrawFrame);
  } else {
    // No session available, so render a default mono view.
    gl.viewport(0, 0, glCanvas.width, glCanvas.height);
    drawScene();

    // Request the next window callback
    window.requestAnimationFrame(onDrawFrame);
  }
}

function drawScene(view, pose) {
  let viewMatrix = null;
  let projectionMatrix = null;
  if (view) {
    viewMatrix = pose.getViewMatrix(view);
    projectionMatrix = view.projectionMatrix;
  } else {
    viewMatrix = defaultViewMatrix;
    projectionMatrix = defaultProjectionMatrix;
  }
}
```

## Specifications

[XRDevicePose Interface](https://immersive-web.github.io/webxr/spec/latest/#xrdevicepose-interface)

## Browser Compatibility

See [Browser Compatibility](compatibility).

repository: brianpeiris/webxr-reference

repo_name: brianpeiris/webxr-reference


text:
# Nature Connect

Nature Connect is a web application take on the classic connect four game!

## Motivation

This project was built for a 2-day hackathon and grew out of our desire to expand our javascript skills while making a simple game with a clear Nature theme.

## Usage

To add more depth to our connect 4 game we programmed a simple AI to enable single player play. Single player mode is the default, and prospective players only need to select their token choices before clicking the start button!

## Project

View this project live [HERE](parkerrebensdorf.com/natureConnect/)

## Features

- [x] Single And Multiplayer Modes
- [x] Single Player Ai
- [x] Design made for Desktop and Mobile use

## Technologies Used

- [JavaScript](https://www.javascript.com/)
- [HTML5](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5)
- [CSS3](https://www.w3.org/Style/CSS/Overview.en.html)
- [jQuery](https://jquery.com/)

## Contributors

[PDRX91](https://github.com/PDRX91) |
[Briantmorr](https://github.com/Briantmorr) |
[bylizhang](https://github.com/bylizhang)

## License
This project is licensed under the MIT License © [Parker Rebensdorf](parkerrebensdorf.com)


text:
---
hrs_structure:
  division: '5'
  volume: '14'
  title: '37'
  chapter: '708'
  section: 708-837.5
type: hrs_section
tags:
  - Crime
  - Criminal Proceeding
menu:
  hrs:
    identifier: HRS_0708-0837_0005
    parent: HRS0708
    name: 708-837.5 Failure to return leased or rented personal
weight: 22250
title: Failure to return leased or rented personal
full_title: 708-837.5 Failure to return leased or rented personal
---
**[§708-837.5] Failure to return leased or rented personal property; penalty.** [(1)] A person commits the offense of failure to return leased or rented personal property other than a rental motor vehicle, when he knowingly or intentionally does not return the leased or rented personal property to the person, or his agent, from whom the personal property was leased or rented within fourteen days after the return date stated in the lease or rental contract, unless the person leasing or renting the personal property gives notice that he will not be able to return the leased or rented personal property by the date stated and with the permission of the owner of the property or his agent extends the date by which the personal property will be returned.

[(2)] Failure to return leased or rented personal property is a petty misdemeanor. [L 1980, c 171, §6]

Cross References

As to civil remedies, see §§603-29, 604-6.2, and 633-8.

COMMENTARY ON §708-837.5

Act 171, Session Laws 1980, enacted this section as part of a package of penal sanctions and civil remedies intended "to provide an effective means for businesses, which have rented personal property to others, to obtain speedy and rightful return of their property while respecting the rights of persons who have leased the property." Conference Committee Report No. 37-80 (57-80).

repository: SamMade/BlueAndKrabby

repo_name: SamMade/BlueAndKrabby


text:
---
title: Abbreviations
permalink: /who-we-are/abbreviations/
---
## Site Abbreviations

As there are multiple abbreviations used throughout the website, this page serves as a glossary of what each of the abbreviations represents!

#### 1. [A*STAR - Agency for Science, Technology and Research](https://www.a-star.edu.sg/) #### {#astar}
#### 2. ACIP - Advanced Construction & Innovation Planning Department #### {#acip}
#### 3. [BCA - Building and Construction Authority](https://www1.bca.gov.sg/) #### {#bca}
#### 4. BE - Built Environment #### {#be}
#### 5. [CHART - Centre for Healthcare Assistive and Robotics Technologies](https://www.cgh.com.sg/chart) #### {#chart}
#### 6. [EDB - Economic Development Board](https://www.edb.gov.sg/) #### {#edb}
#### 7. ES - Environmental Services #### {#es}
#### 8. [ESG - Enterprise Singapore](https://www.enterprisesg.gov.sg/) #### {#esg}
#### 9. ETD - Environment Technology Department #### {#etd}
#### 10. [MOH - Ministry of Health](https://www.moh.gov.sg/) #### {#moh}
#### 11. [NEA - National Environment Agency](https://www.nea.gov.sg/) #### {#nea}
#### 12. [NRF - National Research Foundation](https://www.nrf.gov.sg/) #### {#nrf}
#### 13. [NRP - National Robotics Programme](https://www.nrp.gov.sg) #### {#nrp}
#### 14. [RECT -Robotics Enabling Capability Technology](/research/#rect) #### {#rect}
#### 15. [RDS - Robotics Domain Specific](/research/#rds) #### {#rds}
#### 16. RMF - Robotics Middleware Framework #### {#rmf}
#### 17. [ROS - Robot Operating System](http://wiki.ros.org/) #### {#ros}
#### 18. [ROS-I - ROS Industrial](https://rosindustrial.org/) #### {#rosi}
#### 19. SSPO - Smart Systems Programme Office #### {#sspo}
#### 20. S&TPPO - Science & Technology Policy & Plans Office #### {#stppo}

repository: Isabelchia/astar-nrp

repo_name: Isabelchia/astar-nrp


text:
# SBT / Circumflex Docco plugin

This is an overly simple sbt plugin for [circumflex docco] style documentation generation.

Here's an example on this very plugin: [gh-pages][gh-pages]

Include the plugin in your `project/plugins/build.sbt`

    libraryDependencies <+= (sbtVersion) ( sv =>
      "com.github.philcali" %% "sbt-cx-docco" % ("sbt" + sv + "_0.0.5")
    )

Your project definition may vary. The plugin allows pretty granular control over what
files to document, and where to place the documentation. An example project definition below:

    doccoBasePath := file("src/main/scala")

    // I'm using this to filter files that contain this regex
    // This defaults to anything that ends with .scala of course
    doccoFilenameRegex := """.*\.[scala|sbt]""".r

Here's a list of all the circumflex settings during the batch docco process
(I copied from the plugin's source):

    // Configurable Settings
    doccoBasePath := file("."),
    doccoOutputPath <<= (target) { _ / "docco" },
    doccoPageTemplate := file(".") / "docco-batch-page.html.ftl",
    doccoIndexTemplate := file(".") / "docco-index.html.ftl",
    doccoFilenameRegex := """.*\.scala$""".r,
    doccoTitle <<= name.identity,
    doccoStripScaladoc := true,
    doccoSkipEmpty := true

Run the `docco` task to generate docco documentation.

## Hacking

 * See <https://github.com/inca/circumflex> for modifying the Docco source.

 * Hack, hack, hack

 * Run `mvn clean install -pl circumflex-docco -am`

 * Add the following line to `build.sbt`

    resolvers += "Local Maven Repository" at "file://"+Path.userHome+"/.m2/repository"

*then...*

 * Run `sbt docco`

*or...*

 * Run `sbt publish-local`

 * In your own project add `changing()` to the end of the dependency in your `plugins.sbt`

[gh-pages]: http://philcali.github.com/sbt-cx-docco/
[circumflex docco]: http://circumflex.ru/projects/docco/index.html

repository: vjpr/sbt-cx-docco

repo_name: vjpr/sbt-cx-docco


text:
[![Build][ot-gh-action-build-svg]][ot-gh-action-build]

[ot-gh-action-build]: https://github.com/openthread/ot-qorvo/actions?query=workflow%3ABuild+branch%3Amain+event%3Apush
[ot-gh-action-build-svg]: https://github.com/openthread/ot-qorvo/workflows/Build/badge.svg?branch=main&event=push

---

# OpenThread on Qorvo Example

This repo contains example platform drivers for [Qorvo GP712][gp712], [Qorvo QPG6095][qpg6095], [Qorvo QPG6100][qpg6100], and [Qorvo QPG7015M][qpg7015m].

[gp712]: https://www.qorvo.com/products/p/GP712
[qpg6095]: https://www.qorvo.com/products/p/QPG6095
[qpg6100]: https://www.qorvo.com/products/p/QPG6100
[qpg7015m]: https://www.qorvo.com/products/p/QPG7015M

To learn more about building and running the examples please check the [documentation](https://github.com/Qorvo/qpg-openthread/blob/master/README.md)

# Contributing

We would love for you to contribute to OpenThread and help make it even better than it is today! See our [Contributing Guidelines](https://github.com/openthread/openthread/blob/main/CONTRIBUTING.md) for more information.

Contributors are required to abide by our [Code of Conduct](https://github.com/openthread/openthread/blob/main/CODE_OF_CONDUCT.md) and [Coding Conventions and Style Guide](https://github.com/openthread/openthread/blob/main/STYLE_GUIDE.md).

# License

OpenThread is released under the [BSD 3-Clause license](https://github.com/openthread/ot-qorvo/blob/main/LICENSE). See the [`LICENSE`](https://github.com/openthread/ot-qorvo/blob/main/LICENSE) file for more information.

Please only use the OpenThread name and marks when accurately referencing this software distribution. Do not use the marks in a way that suggests you are endorsed by or otherwise affiliated with Nest, Google, or The Thread Group.

# Need help?

There are numerous avenues for OpenThread support:

- Bugs and feature requests — [submit to the Issue Tracker](https://github.com/openthread/openthread/issues)
- Stack Overflow — [post questions using the `openthread` tag](http://stackoverflow.com/questions/tagged/openthread)
- Google Groups — [discussion and announcements at openthread-users](https://groups.google.com/forum/#!forum/openthread-users)

The openthread-users Google Group is the recommended place for users to discuss OpenThread and interact directly with the OpenThread team.

repository: dvdm-qorvo/ot-qorvo

repo_name: dvdm-qorvo/ot-qorvo


text:
# thypad
A simple note taking app built with socket.io & express.
For the sake of simplicity, there is no data persistence.

Demo: https://thypad.herokuapp.com/

#Features
Multiple users can join by entering a username on the log in screen.
Users can type & contibute to the note in thypad.
A list of currently online users is displayed.
By clicking on text in the note, users can see who created that part of the note & whether that person is currently online.

repository: idesi/thypad

repo_name: idesi/thypad


text:
# Setting Socket Options

<!-- TOC -->

- [1. TCP_NODELAY](#1-tcp_nodelay)
- [2. SO_LINGER](#2-so_linger)
- [3. SO_TIMEOUT](#3-so_timeout)
- [4. SO_RCVBUF and SO_SNDBUF](#4-so_rcvbuf-and-so_sndbuf)
- [5. SO_KEEPALIVE](#5-so_keepalive)
- [6. OOBINLINE](#6-oobinline)
- [7. SO_REUSEADDR](#7-so_reuseaddr)
- [8. IP_TOS Class of Service](#8-ip_tos-class-of-service)

<!-- /TOC -->

Socket options specify **how the native sockets** on which the Java Socket class relies **send and receive data**. Java supports nine options for client-side sockets:

- TCP_NODELAY
- SO_BINDADDR
- SO_TIMEOUT
- SO_LINGER
- SO_SNDBUF
- SO_RCVBUF
- SO_KEEPALIVE
- OOBINLINE
- IP_TOS

The funny-looking names for these options are taken from the named constants in the C header files used in Berkeley Unix where sockets were invented. Thus, they follow classic Unix C naming conventions rather than the more legible Java naming conventions. For instance, `SO_SNDBUF` really means “Socket Option Send Buffer Size.”

## 1. TCP_NODELAY

```java
public void setTcpNoDelay(boolean on) throws SocketException
public boolean getTcpNoDelay() throws SocketException
```

Setting `TCP_NODELAY` to `true` ensures that packets are sent as quickly as possible regardless of their size. Normally, small (one-byte) packets are combined into larger packets before being sent. Before sending another packet, the local host waits to receive acknowledgment of the previous packet from the remote system. This is known as **Nagle’s algorithm**. The problem with Nagle’s algorithm is that if the remote system doesn’t send acknowledgments back to the local system fast enough, applications that depend on the steady transfer of small parcels of information may slow down. This issue is especially problematic for GUI programs such as games or network computer applications where the server needs to track client-side mouse movement in real time. On a really slow network, even simple typing can be too slow because of the constant buffering. Setting `TCP_NODELAY` to `true` defeats this buffering scheme, so that all packets are sent as soon as they’re ready.

`setTcpNoDelay(true)` turns off buffering for the socket. `setTcpNoDelay(false)` turns it back on. `getTcpNoDelay()` returns `true` if buffering is off and `false` if buffering is on. For example, the following fragment turns off buffering (that is, it turns on `TCP_NODELAY`) for the socket s if it isn’t already off:

```java
if (!s.getTcpNoDelay()) s.setTcpNoDelay(true);
```

These two methods are each declared to throw a `SocketException`, which will happen if the underlying socket implementation doesn’t support the `TCP_NODELAY` option.

## 2. SO_LINGER

```java
public void setSoLinger(boolean on, int seconds) throws SocketException
public int getSoLinger() throws SocketException
```

The `SO_LINGER` option specifies what to do with datagrams that have not yet been sent when a socket is closed. **By default**, the `close()` method returns immediately; but the system still tries to send any remaining data. If the linger time is set to `zero`, any unsent packets are thrown away when the socket is closed. If `SO_LINGER` is turned on and the linger time is any positive value, the `close()` method blocks while waiting the specified number of seconds for the data to be sent and the acknowledgments to be received. When that number of seconds has passed, the socket is closed and any remaining data is not sent, acknowledgment or no.

These two methods each throw a `SocketException` if the underlying socket implementation does not support the `SO_LINGER` option. The `setSoLinger()` method can also throw an `IllegalArgumentException` if you try to set the linger time to a **negative value**. However, the `getSoLinger()` method may return `-1` to indicate that this option is disabled, and as much time as is needed is taken to deliver the remaining data; for example, to set the linger timeout for the Sockets to four minutes, if it’s not already set to some other value:

```java
if (s.getTcpSoLinger() == -1) s.setSoLinger(true, 240);
```

The maximum linger time is `65,535` seconds, and may be smaller on some platforms. Times larger than that will be reduced to the maximum linger time. Frankly, `65,535` seconds (more than 18 hours) is much longer than you actually want to wait. Generally, the platform default value is more appropriate.

## 3. SO_TIMEOUT

```java
public void setSoTimeout(int milliseconds) throws SocketException
public int getSoTimeout() throws SocketException
```

Normally when you try to read data from a socket, the `read()` call blocks as long as necessary to get enough bytes. By setting `SO_TIMEOUT`, you ensure that the call will not block for more than a fixed number of **milliseconds**. When the timeout expires, an `InterruptedIOException` is thrown, and you should be prepared to catch it. However, the socket is still connected. Although this `read()` call failed, you can try to read from the socket again. The next call may succeed.

Timeouts are given in **milliseconds**. **Zero** is interpreted as **an infinite timeout**; it is the default value. For example, to set the timeout value of the `Socket` objects to 3 minutes if it isn’t already set, specify `180,000` milliseconds:

```java
if (s.getSoTimeout() == 0) s.setSoTimeout(180000);
```

These two methods each throw a `SocketException` if the underlying socket implementation does not support the `SO_TIMEOUT` option. The `setSoTimeout()` method also throws an `IllegalArgumentException` if the specified timeout value is **negative**.

## 4. SO_RCVBUF and SO_SNDBUF

**TCP uses buffers to improve network performance**. Larger buffers tend to improve performance for reasonably fast (say, 10Mbps and up) connections whereas slower, dialup connections do better with smaller buffers. Generally, transfers of large, continuous blocks of data, which are common in file transfer protocols such as FTP and HTTP, benefit from large buffers, whereas the smaller transfers of interactive sessions, such as Telnet and many games, do not. Relatively old operating systems designed in the age of small files and slow networks, such as BSD 4.2, use two-kilobyte buffers. Windows XP used 17,520 byte buffers. These days, 128 kilobytes is a common default.

**Maximum achievable bandwidth** equals **buffer size** divided by **latency**. For example, on Windows XP suppose the latency between two hosts is half a second (500 ms). Then the bandwidth is 17520 bytes / 0.5 seconds = 35040 bytes / second = 273.75 kilobits / second. That’s the maximum speed of any socket, regardless of how fast the network is. That’s plenty fast for a dial-up connection, and not bad for ISDN, but not really adequate for a DSL line or FIOS.

**You can increase speed by decreasing latency**. However, latency is a function of the network hardware and other factors outside the control of your application. **On the other hand, you do control the buffer size**. For example, if you increase the buffer size from 17,520 bytes to 128 kilobytes, the maximum bandwidth increases to 2 megabits per second. Double the buffer size again to 256 kilobytes, and the maximum bandwidth doubles to 4 megabits per second. Of course, the network itself has limits on maximum bandwidth. **Set the buffer too high and your program will try to send and receive data faster than the network can handle, leading to congestion, dropped packets, and slower performance**. Thus, when you want maximum bandwidth, you need to match the buffer size to the latency of the connection so it’s a little less than the bandwidth of the network.

The `SO_RCVBUF` option controls the suggested send buffer size used for network input. The `SO_SNDBUF` option controls the suggested send buffer size used for network output:

```java
public void setReceiveBufferSize(int size)
    throws SocketException, IllegalArgumentException
public int getReceiveBufferSize() throws SocketException
public void setSendBufferSize(int size)
    throws SocketException, IllegalArgumentException
public int getSendBufferSize() throws SocketException
```

Although it looks like you should be able to set the send and receive buffers independently, the buffer is usually set to the smaller of these two. For instance, if you set the send buffer to `64K` and the receive buffer to `128K`, you’ll have `64K` as both the send and receive buffer size. Java will report that the receive buffer is `128K`, but the underlying TCP stack will really be using `64K`.

The `setReceiveBufferSize()`/`setSendBufferSize()` methods suggest a number of bytes to use for buffering output on this socket. **However, the underlying implementation is free to ignore or adjust this suggestion**. In particular, Unix and Linux systems often specify a maximum buffer size, typically 64K or 256K, and do not allow any socket to have a larger one. If you attempt to set a larger value, Java will just pin it to the maximum possible buffer size. On Linux, it’s not unheard of for the underlying implementation to double the requested size. For example, if you ask for a 64K buffer, you may get a 128K buffer instead.

These methods throw an `IllegalArgumentException` if the argument is less than or equal to **zero**. Although they’re also declared to throw `SocketException`, they probably won’t in practice, because a `SocketException` is thrown for the same reason as `IllegalArgumentException` and the check for the `IllegalArgumentException` is made first.

In general, if you find your application is not able to fully utilize the available bandwidth (e.g., you have a 25 Mbps Internet connection, but your data is transferring at a piddling 1.5 Mbps) try increasing the buffer sizes. **By contrast, if you’re dropping packets and experiencing congestion, try decreasing the buffer size**. However, most of the time, unless you’re really taxing the network in one direction or the other, the defaults are fine. In particular, modern operating systems use TCP window scaling (not controllable from Java) to dynamically adjust buffer sizes to fit the network. As with almost any performance tuning advice, the rule of thumb is not to do it until you’ve measured a problem. And even then you may well get more speed by increasing the maximum allowed buffer size at the operating system level than by adjusting the buffer sizes of individual sockets.

## 5. SO_KEEPALIVE

If `SO_KEEPALIVE` is turned on, the client occasionally sends a data packet over an idle connection (most commonly once every two hours), just to make sure the server hasn’t crashed. If the server fails to respond to this packet, the client keeps trying for a little more than 11 minutes until it receives a response. If it doesn’t receive a response within 12 minutes, the client closes the socket. Without `SO_KEEPALIVE`, an inactive client could live more or less forever without noticing that the server had crashed. These methods turn `SO_KEEPALIVE` on and off and determine its current state:

```java
public void setKeepAlive(boolean on) throws SocketException
public boolean getKeepAlive() throws SocketException
```

The default for `SO_KEEPALIVE` is `false`. This code fragment turns `SO_KEEPALIVE` off, if it’s turned on:

```java
if (s.getKeepAlive()) s.setKeepAlive(false);
```

## 6. OOBINLINE

TCP includes a feature that sends a single byte of “urgent” data out of band. This data is sent immediately. Furthermore, the receiver is notified when the urgent data is received and may elect to process the urgent data before it processes any other data that has already been received. Java supports both sending and receiving such urgent data. The sending method is named, obviously enough, `sendUrgentData()`:

```java
public void sendUrgentData(int data) throws IOException
```

This method sends the **lowest-order byte** of its argument almost immediately. If necessary, any currently cached data is flushed first.

How the receiving end responds to urgent data is a little confused, and varies from one platform and API to the next. Some systems receive the urgent data separately from the regular data. However, the more common, more modern approach is to place the urgent data in the regular received data queue in its proper order, tell the application that urgent data is available, and let it hunt through the queue to find it.

By default, Java ignores urgent data received from a socket. However, if you want to receive urgent data inline with regular data, you need to set the `OOBINLINE` option to `true` using these methods:

```java
public void setOOBInline(boolean on) throws SocketException
public boolean getOOBInline() throws SocketException
```

The default for `OOBINLINE` is `false`. This code fragment turns `OOBINLINE` on, if it’s turned off:

```java
if (!s.getOOBInline()) s.setOOBInline(true);
```

Once `OOBINLINE` is turned on, any urgent data that arrives will be placed on the socket’s input stream to be read in the usual way. Java does not distinguish it from nonurgent data. That makes it less than ideally useful, but if you have a particular byte (e.g., a `Ctrl-C`) that has special meaning to your program and never shows up in the regular data stream, then this would enable you to send it more quickly.

## 7. SO_REUSEADDR

When a socket is closed, it may not immediately release the local port, especially if a connection was open when the socket was closed. It can sometimes wait for a small amount of time to make sure it receives any lingering packets that were addressed to the port that were still crossing the network when the socket was closed. The system won’t do anything with any of the late packets it receives. It just wants to make sure they don’t accidentally get fed into a new process that has bound to the same port.

This isn’t a big problem on a random port, but it can be an issue if the socket has bound to a well-known port because it prevents any other socket from using that port in the meantime. If the `SO_REUSEADDR` is turned on (it’s turned off by default), another socket is allowed to bind to the port even while data may be outstanding for the previous socket.

In Java this option is controlled by these two methods:

```java
public void setReuseAddress(boolean on) throws SocketException
public boolean getReuseAddress() throws SocketException
```

For this to work, `setReuseAddress()` must be called before the new socket binds to the port. This means the socket must be created in an unconnected state using the noargs constructor; then `setReuseAddress(true)` is called, and the socket is connected using the `connect()` method. Both the socket that was previously connected and the new socket reusing the old address must set `SO_REUSEADDR` to `true` for it to take effect.

## 8. IP_TOS Class of Service

**Different types of Internet service have different performance needs**. For instance, video chat needs relatively high bandwidth and low latency for good performance, whereas email can be passed over low-bandwidth connections and even held up for several hours without major harm. VOIP needs less bandwidth than video but minimum jitter. It might be wise to price the different classes of service differentially so that people won’t ask for the highest class of service automatically. After all, if sending an overnight letter cost the same as sending a package via media mail, we’d all just use FedEx overnight, which would quickly become congested and overwhelmed. The Internet is no different.

The class of service is stored in an eight-bit field called `IP_TOS` in the IP header. Java lets you inspect and set the value a socket places in this field using these two methods:

```java
public int getTrafficClass() throws SocketException
public void setTrafficClass(int trafficClass) throws SocketException
```

The traffic class is given as an `int` between `0` and `255`. Because this value is copied to an eight-bit field in the TCP header, only the low order byte of this int is used; and values outside this range cause `IllegalArgumentException`s.