text:
# JBASoftwareChallenge
A repo to hold the code for the JBA software challenge

The provided data had inconsistencies, with how the data was written, so I manually normalized it
Grid values changed: (28, 222), (49, 221), (49, 222), (50, 221), (107, 280)
Data given lacked spacing between months, I extrapolated, based on the style and format of the file where the spaces between months would go, and placed them in manually
In a real situation, I would ask the creator of the data to send me the correct data for these grid values. I modified the data in order to move forward with the project knowing that it would be easy to retrospectively change the data later on in the project

On my computer, the solution takes 1.303 seconds.
It generates a comma separated file which can easily be converted to a spreadsheet, or used elsewhere

repository: mattioso/JBASoftwareChallenge

repo_name: mattioso/JBASoftwareChallenge


text:
# Fpass

Flutter Gpass application.

[gpass](https://github.com/yakuter/gpass) is an open source password manager API written with Go by [Yakuter](https://github.com/yakuter).

 ## TO-DO

 - [x] List all logins
   - [ ] List settings
   - [x] Add divider
   - [x] Slide for delete
   - [x] Drag for refresh
   - [ ] Sharable login
   - [x] Monospace password
 - [x] Create new login
   - [ ] Avoid null data
 - [x] Setting page
 - [ ] Add pin/biometric security
 - [ ] Localize
 - [ ] Dynamic light/dark mode

license: MIT

repository: aeosmanoglu/fpass

branch_name: refs/heads/master

extension: md

gha_language: Dart

gha_license_id: MIT

license_type: permissive

repo_name: aeosmanoglu/fpass


text:
# CyberArk Ansible Demo

Demonstrating secure delivery of secrets to Ansible Playbooks from [CyberArk Enterprise Password Vault](https://cyberark.com) via CyberArk's Application Identity Manager (AIM) and by [CyberArk Conjur](https://conjur.org).

repository: infamousjoeg/cyberark-ansible-demo

repo_name: infamousjoeg/cyberark-ansible-demo


text:
---
author: jeffatwood
comments: true
date: 2008-09-24 16:18:30+00:00
layout: post
redirect_from: /2008/09/podcast-23
hero: /images/category/podcasts.jpg
slug: podcast-23
title: 'Podcast #23'
wordpress_id: 103
tags:
- company
- podcasts
---

This is the twenty-third episode of the StackOverflow podcast, wherein Joel and I discuss the following:

  * The Stack Overflow team will be in New York City from the 24th to the 28th. It's partly business, and partly a reward to our team for their hard work on the site. What are some cool geeky things for us to do in NYC?

  * We wonder: do newscasters wear pants?

  * Joel describes his upcoming Inc. magazine article enumerating the seven development mistakes we made in building Stack Overflow. I think by seven he meant zero.

  * Most of the reviews of [Cuil](http://www.google.com/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fwww.cuil.com%2F&ei=_4DZSJr5LomasQPA3_DsDA&usg=AFQjCNEAaWsxycaSfzZK4sUO3um-Nx-U2g&sig2=taSQOqonltpv1GIixMSR3A) and [Knol](http://knol.google.com/k#) are negative because "I tried it for what it was intended to be used, and it didn't work."

  * The power of short informal code reviews in bridging the skill gap between beginning and expert software developers. Good developers think of this as self-preservation, because today's beginner code is tomorrow's code you'll have to maintain.

  * There have been a lot of requests for a packaged, customized version of Stack Overflow, but we have some reservations about the difficulty of delivering a packaged solution, and whether the current design will scale down to smaller private communities at all.

  * Should trusted users be allowed to close questions? Or should the community simply vote them down? I argue we need both of these methods; Joel feels we only need voting.

  * It's ok to have some "fun" programming questions every now and then. It can't be a community if you don't stop every so often to have some (at least partially on topic) fun.

We also answered the following listener questions:

  1. "How do you handle newbie questions?"

  2. **Richard**: "How do you cultivate programmer mentoring at a small company?"

If you'd like to submit a question to be answered in our next episode, record an audio file (90 seconds or less) and mail it to [podcast@stackoverflow.com](mailto:podcast@stackoverflow.com). You can [record a question](http://blog.stackoverflow.com/index.php/2008/05/recording-podcast-questions-using-your-telephone/) using nothing but a telephone and a web browser. We also have a dedicated phone number you can call to leave audio questions at **646-826-3879**.

The [transcript wiki](https://stackoverflow.fogbugz.com/default.asp?W25450) for this episode is available for public editing.

[display_podcast]

extension: markdown


text:
## Introduction

The STH location operator is a WireCloud operator that allows you to retrieve location values for context broker entities and combine them with historic values of other attributes.

## Settings

- **STH server URL**: URL of the STH server to use for retrieving entity
  information
- **NGSI tenant/service**: Tenant/service to use when connecting to the context
  broker. Must be a string of alphanumeric characters (lowercase) and the `_`
  symbol. Maximum length is 50 characters. If empty, the default tenant will be
  used
- **NGSI scope**: Scope/path to use when connecting to the context broker. Must
  be a string of alphanumeric characters (lowercase) and the `_` symbol
  separated by `/` slashes. Maximum length is 50 characters. If empty, the
  default service path will be used: `/`
- **Attribute**: Attribute of the entity to query about. Should be a attribute with coordinates of type geo:point.

## Wiring

### Input Endpoints

- **Input Data**: JSON object with the input data with the following attributes: an array of values, an array of timestamps of the values, the entity and the attribute.

### Output Endpoints

- **Output Data**: JSON object with the output data with the following attributes: an array of values, an array of timestamps for the values, an array of coordinates for the values, the entity and entity id.

## References

* [Orion Context Broker][orion]
* [Short Time History (Comet)][sth]

[orion]: http://catalogue.fiware.org/enablers/publishsubscribe-context-broker-orion-context-broker "Orion Context Broker info"
[sth]: https://github.com/telefonicaid/fiware-sth-comet


text:
# csrex

A simple implementation of regular expressions in C#.

Regular expressions are first compiled into an array of instructions.
The resulting regex object can then attempt to match a given string without needing to perform any memory allocations.
Instead of a string the `match()` method also accepts the new `ReadOnlySpan<char>` type.

repository: markusolt/csrex

repo_name: markusolt/csrex


text:
[![](https://jitpack.io/v/BaselHorany/RecentActivitiesMenu.svg)](https://jitpack.io/#BaselHorany/RecentActivitiesMenu)

# RecentActivitiesMenu
A menu that display recent visited activity on their paused stated, which also can be clicked to naviagte to it directly. Similar to recent apps menu but this is for in-app activities
This Lib not only nice addtition to make more unique design that may like users\client, but also used to navigate easier and faster between activities, for instance usually in android a main activity -> conversations list activity -> single chat activity, once user go back to main he can not go directly to single chat without revisiting list activity. but with this lib it is possible without losing extras

## Setup
1- Add jitpack.io repositories to you project `build.gradle`
```groovy
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
```
2- Add it as a dependency to your app `build.gradle`
```groovy
dependencies {
  compile 'com.github.BaselHorany:RecentActivitiesMenu:1.0.0'
}
```

## Usage
This Lib extends android support library DrawerLayout so you are free to deal with the menu as usual

```xml
<com.basel.RecentActivitiesMenu.ActivitiesMenuDrawer xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:openDrawer="left">

    <!--include your main layout -->
    <include
        layout="@layout/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:background="@drawable/nav_bg"
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemIconTint="@color/colorSecondary"
        app:itemTextColor="@color/colorPrimary"
<EMAIL_ADDRESS>        app:menu="@menu/navigation_menu"/>
    <!--app:headerLayout="@layout/nav_header"-->

</com.basel.RecentActivitiesMenu.ActivitiesMenuDrawer>
```

```java

/*Extend application class from this Lib. clone it and edite for multidexing*/
    public class AppController extends AMApplication {

    }

/*options*/
    DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
    drawerLayout.setRecentBelowHeader(false);//show recent menu below drawer header if any.

```
# To-do
 1-Relay on stronger identifier of activities to avoid duplication.
   Currently it uses hashCode, working on a way to idintify activity by its component name + intent extras, or the easiest way in worst cases is to manually call the lib to identify each activity.

## This lib uses AndroidX

## Author
Basel Horany
[http://baselhorany.com](http://baselhorany.com)

repository: BaselHorany/RecentActivitiesMenu

repo_name: BaselHorany/RecentActivitiesMenu


text:
# Mega Generator

This mod requires [technic](https://content.minetest.net/packages/RealBadAngel/technic/) ([github](https://github.com/minetest-mods/technic)).

## What this mod provides

The major function of this mod is so developers or server owners who want to test, develop or provide public machines without the annoyance of needing to build a massive nuclear reactor and all that just to provide/test/develop with technic's machines. Instead they can just install technic and mega_generator and enjoy some fun building cool technic devices.

## Settings

Of course you want to know what can be set and what they mean?

Check out `init.lua` in the `mega_setting` table is comments and settings for default. (Again, all customizable)

## Contributions

* [powerbanks](https://content.minetest.net/packages/OgelGames/powerbanks/) (MK1 overlay icon is used) ([github](https://github.com/OgelGames/powerbanks))
* [technic](https://content.minetest.net/packages/RealBadAngel/technic/) (Carbon plate icon is used, along with modified generator code) ([github](https://github.com/minetest-mods/technic))


text:
[![Build Status](https://nodei.co/npm/neuter.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/neuter)

# node-neuter [![Build Status](https://travis-ci.org/squarewolf/node-neuter.png?branch=master)](https://travis-ci.org/squarewolf/node-neuter) [![Dependencies](https://david-dm.org/squarewolf/node-neuter.png)](https://david-dm.org/squarewolf/node-neuter) [![Code Climate](https://codeclimate.com/github/squarewolf/node-neuter.png)](https://codeclimate.com/github/squarewolf/node-neuter)

> Unifies javascript source files in the order you require

## Getting started

The stable version of the node-neuter library can be installed from the
[npm package](https://www.npmjs.org/package/neuter):

```shell
npm install neuter
```

Alternatively the latest version can be installed from git:

```shell
npm install https://github.com/squarewolf/node-neuter/archive/master.tar.gz
```

Then simply require node-neuter in your project

```javascript
var neuter = require('neuter');
```

## About

### Origins

Node-neuter is based on  and
aims to extract the core functionality into a pure node library.

The main goal for node-neuter is to implement a pure node version of the
[grunt-neuter](https://github.com/trek/grunt-neuter) core,
paving the road for implementations for both [grunt](http://gruntjs.com/) and
[gulp](http://gulpjs.com/), as described in
[grunt-neuter issue #47](https://github.com/trek/grunt-neuter/issues/47).

Although based on [grunt-neuter](https://github.com/trek/grunt-neuter),
node-neuter is a rewrite using [esprima](http://esprima.org/) in stead of
regular expressions. As a result of this, node-neuter detects when `require` is
overwritten with a local reference and will then ignore require statements as
long as the local reference is in scope.

In contrast to [grunt-neuter](https://github.com/trek/grunt-neuter), node-neuter
returns a [SourceNode](https://github.com/mozilla/source-map#sourcenode) object,
allowing for custom handling of the parsed code and/or map generation. Because
node-neuter doesn't actually generate the source and map itself, the
[includesourcemap](https://github.com/trek/grunt-neuter#includesourcemap)
option and corresponding features have been dropped.

### Features

  1. Merges files into the main file on each call of ```require(file)```

  2. Ignores calls to locally defined require methods

  3. Support for glob pathnames

  4. Guards against double inclusion

  5. Support for file blacklisting (files will be included raw)

  6. Support for pre-include templating

  7. Support for include basepath

  8. Unifies into a universal
     [SourceNode](https://github.com/mozilla/source-map#sourcenode) object

  9. Support for the [vynil](https://github.com/wearefractal/vinyl) virtual fyle
     format

  10. Passes all [grunt-neuter](https://github.com/trek/grunt-neuter) unit
      tests, excluding those requiring the
      [includesourcemap](https://github.com/trek/grunt-neuter#includesourcemap)
      feature

#### TODO's

  * make full use of Buffers
  * write testcases for `parse(File, callback)` interface
  * write documentation for `parse(File, callback)` interface
  * ...

## Contributing

Before reporting an issue, please check if the issue isn't reported already. If it isn't, please open an issue taking into account the [bug reporting guidelines](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines).

Optionally, if you're up for the challenge of fixing the issue, fork the repo. Commit the patch to your local branch (**not** the master branch) and send in a pull request. We *love* pull requests!

### Special thanks go to

* [bschuedzig](https://github.com/bschuedzig) for reporting the very first bug *and* pull request

## Neuter

### Usage

```javascript
var Neuter = require('neuter');

var myNeuter = new Neuter();
myNeuter.parse('myfile.js', function(err, sourceNode) {
	if (err) {
		// ... handle error
		return;
	}

	// ... use the unified sourceNode object to generate source or a map
});
```

#### constructor(options)

##### options.basePath

Specifying a base path allows you to omit said portion of the filepath from your
require statements. For example: when using `basePath: "lib/js/"` in your task
options, `require("lib/js/file.js");` can instead be written as
`require("file.js");`. Note that the trailing slash *must* be included.

Type: `String`
Default: `''`

##### options.filepathTransform

Specifying a filepath transform allows you to control the path to the file that
actually gets concatenated. For example, when using `filepathTransform:
function(filepath){ return 'lib/js/' + filepath; }` in your task options,
`require("lib/js/file.js");` can instead be written as `require("file.js");`
(This achieves the same result as specifying `basePath: "lib/js/"`). When used
in conjunction with the `basePath` option, the base path will be prepended to
the `filepath` argument and a second argument will be provided that is the
directory of the file **without** the `basePath`.

Type: `function`
Default: `function(filepath){ return filepath; }`

##### options.template

Type: `String`
Default: `(function() {\n\n{%= src %}\n\n})();`

##### options.separator

Neutered files will be joined on this string. If you're post-processing
concatenated JavaScript files with a minifier, you may need to use a semicolon
`';'` as the separator although the semicolon at the end of the template should
suffice.

Type: `String`
Default: `\n\n`

##### options.skipFiles

A list of files being required that should not be checked for further require
statements. Useful for libraries that support other module building methods and
leave their requires around in a way that isn't meaningful to neutering.

Type: `Array`
Default: `[]`

##### options.process

Process source files before concatenating, either as
[templates](http://lodash.com/docs#template) or with a custom function. The
delimiters default to neuter's own special type (`{% %}`), which helps avoid
errors when requiring libraries like [Underscore](http://underscorejs.org/) or
[Lo-Dash](http://lodash.com/).

* `false` - No processing will occur.
* `true` - Process source files using [grunt.template.process][] without any
  data.
* `options` object - Process source files using [grunt.template.process][],
using the specified options.
* `function(src, filepath)` - Process source files using the given function,
  called once for each file. The returned value will
  be used as source code.

Type: `Boolean` `Object` `Function`
Default: `false`

## Examples

### Generating neutered source

```javascript
var Neuter = require('neuter');

var myNeuter = new Neuter();
myNeuter.parse('myfile.js', function(err, sourceNode) {
	if (err) {
		// ... handle error
		return;
	}

	var codeMap = sourceNode.toStringWithSourceMap({
		file: 'neutered.js',
	});

	var neuteredSource = codeMap.code;
	console.log(neuteredSource);
});
```

### Generating source map

```javascript
var Neuter = require('neuter');
var path = require('path');
var SourceMapConsumer = require('source-map').SourceMapConsumer;
var SourceMapGenerator = require('source-map').SourceMapGenerator;

var myNeuter = new Neuter();
myNeuter.parse('myfile.js', function(err, sourceNode) {
	if (err) {
		// ... handle error
		return;
	}

	var codeMap = sourceNode.toStringWithSourceMap({
		file: 'neutered.js',
	});

	var consumer = new SourceMapConsumer(codeMap.map.toJSON());
	var generator = SourceMapGenerator.fromSourceMap(consumer);
	var newSourceMap = generator.toJSON();
	newSourceMap.file = path.basename(newSourceMap.file);

	var sourceMap = JSON.stringify(newSourceMap, null, '  ');

	console.log(sourceMap);
});
```

repository: squarewolf/node-neuter

gha_language: JavaScript

repo_name: squarewolf/node-neuter


text:
# Roguelike 2D Kit for Unreal Engine 4

	Marketplace |
	Demo |
  	Website

Available in the [Unreal Engine Marketplace](https://www.unrealengine.com/marketplace/roguelike-2d-kit)

The Roguelike 2D Kit is an easy to use template for creating top down roguelike type of games in 2D!

The template is created using Blueprints and allows easy customization.

Project will be maintained, so feel free to get in touch to suggest changes, features or anything else.

## Features include:

- Different types of enemies, pickups and weapons
- Simply create rooms using tile maps and tile sets (drag and drop)
- Easy to create and modify enemies and powerups using data tables
- Systems for health, player statistics, score and save/load functionality
- And much more

For a list of features, documentation and more please see the [website](https://gracesgames.com/Roguelike2DKit/)

![FeaturedImage](https://github.com/GracesGames/Roguelike2DKit/blob/master/Images/FeaturedImage.png)


text:
# homeassistant duofern component

This uses [pyduofern](https://github.com/gluap/pyduofern) to provide (incomplete!) duofern support.
The underlying library started off as an "only those roller shutters I own and can test" port of the
(more complete but perl-based) FHEM duofern module. As of now only some roller shutters, switch actors
and smoke detectors have been observed working in Homeassistant.

Implementing new device types requires access to a device, therefore the original implementation
supported only roller shutters and was only tested with those accessible to me via friends
and family.

Later others contributed support for other roller shutters and smoke detectors not yet supported by the
component, but the feature set is still far from complete. Note that especially weather station support
is lacking.

With a bit of python background and enough time at hand you should be able to add support for new
device types yourself, and I am happy to merge commit requests to that end.

repository: rakaandro/pyduofern-hacs

gha_language: Python

repo_name: rakaandro/pyduofern-hacs


text:
# tc-context - TwinCAT ADS Javascript Library

- *written by Dmitrij Trifanov, at<EMAIL_ADDRESS>
![version](https://img.shields.io/badge/version-1.0.0-orange)
[![TwinCAT](https://img.shields.io/badge/TwinCAT-v4024.7-blue)](https://infosys.beckhoff.com/english.php?content=../content/1033/tcadscommon/html/tcadscommon_intro.htm&id=)
[![npm version](https://img.shields.io/badge/npm-v1.7.1-blue)](https://www.npmjs.org/package/ads-client)
[![License](https://img.shields.io/badge/license-MIT-green)](https://choosealicense.com/licenses/mit/)

Unofficial Node.JS Library for TwinCAT ADS Communication, designed to simplify connection to a Beckhoff PLC, and automatically generating a Symbol Map [ADS Protocol](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_ads_intro/116157835.html&id=124964102706356243) from Beckhoff for ease of read/write and subscribe data operations.
The `tc-context` library achieves this by fetching all the type data and initial symbol data at the moment connection and caching the memory locations of each individual symbol, as well as their parent symbol relationship. This grants the possibility to write partial structures directly into TwinCAT `Function_Blocks` and `Structures`, subscribing to complex objects, and clearing multiple Namespaces, all with single-line instructions at minimal run-time cost.

This library is made possible, thanks to the [ads-client](https://github.com/jisotalo/ads-client) library by Jussi Isotalo<EMAIL_ADDRESS>If you are in search for a smaller library, focusing on ADS communication, make sure to check the[ads-client](https://github.com/jisotalo/ads-client) library.

# [List of Features](#table-of-contents)

- Generation of a full Symbol Map, from a Beckhoff PLC
- Reading/writing/clearing/subscribing to non-structured and non-array types
- Reading/writing/clearing/subscribing to structured types
- Writing only to explicit members of structured types
- Reading/writing/clearing/subscribing to array types
- Reading/Writing/clearing/subscribing to sub-arrays dimension size\[*n-1*\] from an initial array of dimension size\[*n*\]
- Invoking Methods from the Beckhoff PLC Side
- Beckhoff PLC Code Change detection and Symbol Map re-generation
- Input value validation for all types, including sub-ranged integers

For detailed information, see the official [documentation](https://dmitrijtrifanov.github.io/TcContext/).

# Table of contents

- [List of Features](#list-of-features)
- [Quick Look](#quick-look)
- [Installation](#installation)
- [Connection Setup](#connection-setup)
- [Creating TcContext Instance](#creating-tccontext-instance)
    - [TcContext Components](#tccontext-components)
- [TcSymbols](#tcsymbols)
    - [Read, Write and Clear TcSymbol Operations](#read-write-and-clear-tcsymbol-operations)
    - [Subscribing to TcSymbol Changes](#subscribing-to-tcsymbol-changes)
        - [Explicit Sampling Rate](#explicit-sampling-rate)
    - [Structured TcSymbols](#structured-tcsymbols)
        - [Method call on Structured TcSymbols](#method-call-on-structured-tcsymbol)
        - [Unions and TcSymbols](#unions-and-tcsymbols)
    - [Array TcSymbols](#array-tcsymbols)
        - [Multidimensional Array](#multidimensional-array)
    - [TcSymbol Types](#tcsymbol-types)
        - [TcBooleanSymbol](#tcbooleansymbol)
        - [TcNumericSymbol](#tcnumericsymbol)
        - [TcStringSymbol](#tcstringsymbol)
        - [TcEnumSymbol](#tcenumsymbol)
        - [TcStructureSymbol](#tcstructuresymbol)
        - [TcArraySymbol](#tcarraysymbol)
    - [Invalidated TcSymbol](#invalidated-tcsymbol)
    - [TcSymbol Attributes](#tcsymbol-attributes)
        - [TcSymbol Default Attribute](#tcsymbol-default-attribute)
        - [TcSymbol ReadOnly Attribute](#tcsymbol-readonly-attribute)
        - [TcSymbol Ignore Attribute](#tcsymbol-ignore-attribute)
        - [TcSymbol Event Alias Attribute](#tcsymbol-event-alias-attribute)
- [TcEvents](#tcevents)
    - [TcEvent List](#tcevent-list)
    - [TcEvent Hierarchy](#tcevent-hierarchy)
- [Understanding TcContext Lifecycle](#understanding-tccontext-lifecycle)
- [TcExceptions](#tcexceptions)
- [Documentation](#documentation)
- [Acknowledgments](#acknowledgments)
- [License](#license)

# [Quick Look](#table-of-contents)

Below is a quick example of creating a `TcContext` for a Beckhoff PLC located at localhost, and performing read/write/clear operations. For more complex operations, and behavior definitions, see individual chapters on the subject matter.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL := TRUE;
    numericValue : INT := 10;
    structuredValue : Foo;
    arrayValue : ARRAY [0..9] OF STRING := ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j']

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    realValue : REAL;
    stringValue : STRING := 'hello world';

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context');

TcContext.create().then(async context => {

    //Reading the program's 'MAIN' Namespace
    let result = await context.$.MAIN.$get
    /**
     *  result : {
     *      booleanValue : true,
     *      numericValue : 10,
     *      structuredValue : {
     *          realValue : 0,
     *          stringValue : 'hello world'
     *      },
     *      arrayValue : ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j']
     *  }
     */

    //Clearing all members of a Structured Value
    await context.$.MAIN.structuredValue.$clear()
    result = await context.$.MAIN.structuredValue.$get;
    /**
     *  result : { realValue : 0, stringValue : '' }
     */

    //Setting a Numeric value
    await context.$.MAIN.numericValue.$set(5);
    result = await context.$.MAIN.numericValue.$get;
    /**
     *  result : 5
     */

    //Setting an Array
    await context.$.MAIN.arrayValue.$set(['1', '2', '3']);
    result = await context.$.MAIN.arrayValue.$get;
    /**
     *  result : ['1', '2', '3', 'd', 'e', 'f', 'g', 'h', 'j']
     */

    //Setting a program's Namespace values
    const set = {
         booleanValue : false,
         structuredValue : {
             realValue : 15,
             stringValue : 'i am alive'
         }

    }
    await context.$.MAIN.$set(set)
    result  = await context.$.MAIN.arrayValue.$get;
    /**
     *  result : {
     *      booleanValue : false,
     *      numericValue : 5,
     *      structuredValue : {
     *          realValue : 15,
     *          stringValue : 'i am alive'
     *      },
     *      arrayValue : ['1', '2', '3', 'd', 'e', 'f', 'g', 'h', 'j']
     *  }
     */

    //Clearing Namespace
    await context.$.MAIN.$clear();
    result = await context.$.MAIN.arrayValue.$get;
    /**
     *  result : {
     *      booleanValue : false,
     *      numericValue : 0,
     *      structuredValue : {
     *          realValue : 0,
     *          stringValue : ''
     *      },
     *      arrayValue : ['', '', '', '', '', '', '', '', '']
     *  }
     */

    //Disconnecting Context and killing bindings
    await context.kill()

})
```

# [Installation](#table-of-contents)

Run the following command to install package in your project:

```bash
npm install tc-context
```

Include the module in js:
```js
const { TcContext } = require('tc-context')
```

# [Connection Setup](#table-of-contents)

The `tc-context` library uses the [ads-client](https://github.com/jisotalo/ads-client) library for connecting and communicating with a Beckhoff PLC over the ADS Protocol. Because of that, the connection setup configuration is equal to the [connection setup](https://github.com/jisotalo/ads-client#connection-setups-and-possibilities) of the [ads-client](https://github.com/jisotalo/ads-client), since the supplied settings are routed directly to the `ads-client`.

See [ads-client](https://github.com/jisotalo/ads-client) for detailed information on different types of possible connections.

# [Creating TcContext Instance](#table-of-contents)

```js
const { TcContext } = require('tc-context')

//Connecting to a Localhost Beckhoff PLC
TcContext.create().then(async context => {

    //Result contains the currently active context
    //Perform operation with the created context....

    //When done, kill the context
    await context.kill();

})
```

In order to create a new `TcContext` Object, a call to the `TcContext.create()` functions must be made. By default, if no arguments are passed to the `TcContext.create()` function, it is assumed to that the connection that will be made is to the localhost located PLC. Explicit settings can be provided as the first argument to the `TcContext.create()` function.

***NOTE:*** The `TcContext` object must be explicitly killed at the end of its use, through the `TcContext.kill()` method call. This will clean up all subscription handles, termination the connection, and clear the generated map, thus ensuring no memory leaks.

```js
const { TcContext } = require('tc-context')

const settings = {
  targetAmsNetId: '<IP_ADDRESS>.1.1',
  targetAdsPort: 851
  //And more....
}

//Connecting to a Localhost Beckhoff PLC
TcContext.create(settings).then(async context => {

    //Result contains the currently active context for <IP_ADDRESS>.1.1:851
    //Perform operation with the created context....

    //When done, kill the context
    await context.kill();

})
```

The settings are routed to the [ads-client](https://github.com/jisotalo/ads-client) `Client.connect()` method directly, without any modification. Hence, for more detailed and up-to-date information, on different connection patters, see the official documentation of [ads-client](https://github.com/jisotalo/ads-client).

## [TcContext Components](#table-of-contents)

The `TcContext` Object is composed of 3 Components :

* `TcSymbolRegistry` - Storage for all the Symbol Maps created based based on the data gathered by `TcCom`', passed through the `TcTypeRegistry`. This property can be accessed by the `TcContext.symbols` property, and the registered symbol maps can be accessed by the `TcContext.symbols.namespaces` property. The `TcSymbolNamespace` represents the Programs and any Global Variable Lists present in the PLC.
***Note:*** Because access to the symbol namespaces is a common operation, a shortcut is implemented in the form of `TcContext.$`, which corresponds to `TcContext.symbols.namespaces`
* `TcTypeRegistry` - Storage for all the processed types, which are gathered by `TcCom` Component. This component can be accessed through `TcContext.types` property, and the registered types can be queried by `TcContext.types.has(<type name>)`.
***Note:*** Type names are case sensitive.
* `TcCom` - Component responsible for communication and data passing between `TcContext` and the PLC. This component can be accessed through `TcContext.COM` property.

# [TcSymbols](#table-of-contents)

Upon a successful `TcContext` creation, a full `TcSymbol` map is created, mirroring what is currently loaded in the Beckhoff PLC. The create `TcSymbolNamespaces` can be accessed either through `TcContext.symbols.namespaces` or `TcContext.$` properties.
In order to avoid naming conflicts with symbols declared in the PLC, all public methods provided by the `TcSymbol` Object begin with ``$` symbol.

***IMPORTANT:*** Type safety is important and there is **no implicit type conversion**. This is to ensure, that whatever is written is well defined by both ends of the system. In case of type mismatch, an exception `TcBindingInvalidTypeException` is raised and no operation is performed.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    numericValue : INT;
    rangeValue : BYTE(50..100);
    stringValue : STRING(50);
    enumValue : MyEnum;
    arrayValue : ARRAY[0..4] OF Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    {attribute 'Default' := '22.3'}
    realValue : REAL;
    {attribute 'ReadOnly'}
    stringValue : STRING;

END_VAR
```
*MyEnum(ENUM)*
```
TYPE MyEnum :
(
	member1 := 0,
	member2 := 1,
	member3 := 2
);
END_TYPE
```

The example above would produce a `TcContext` of the following type:

* `TcContext.$.MAIN` - the MAIN Program
    * `.booleanValue` - symbol of type `TcBooleanSymbol : TcSymbol`
    * `.numericValue` - symbol of type `TcNumericSymbol : TcSymbol`
    * `.rangeValue` - symbol of type `TcNumericSymbol : TcSymbol` with explicit value borders at `[50-100]`, and a write of a value outside these borders raises the `TcBindingOutOfRangeException` exception
    * `.stringValue` - symbol of type `TcStringSymbol : TcSymbol`, with a max length of `[50]` characters, and any attempt to write a string of `[50+]` length raises the `TcBindingOutOfRangeException` exception
    * `.enumValue` - symbol of type `TcEnumSymbol : TcSymbol`, which only accepts input strings from `['MyEnum.member1', 'MyEnum.member2', 'MyEnum.member3']` list, and any write of value outside that list raises the `TcBindingOutOfRangeException` exception
    * `.arrayValue` - symbol of type `TcArraySymbol : TcSymbol`, which represents an array of size `[5]` of type `Foo` type `Function_Block`
        * `[0-4]` - symbols of type `TcStructureSymbol : TcSymbol`
            * `.realValue` - symbol of type `TcNumericSymbol : TcSymbol`, with an explicit default value of `22.3`, which will be set, when ``TcSymbol.$clear()` is called
            * `.stringValue` - symbol of type `TcStringSymbol : TcSymbol`, which is set to `ReadOnly`, thus any call to `TcSymbol.$clear()` or `TcSymbol.$set()` results in an exception `TcBindingReadOnlyException`, as well as a call to `.stringValue` parent `TcSymbol.$clear()` method will ignore this symbol

```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Exception TcBindingOutOfRangeException
    await context.$.MAIN.rangeValue.$set(10)

    //MAIN.enumValue is set to 1
    await context.$.MAIN.enumValue.$set('MyEnum.member2')

    //Exception TcBindingReadOnlyException
    await context.$.MAIN.arrayValue[0].stringValue.$set('hello world')

    //For [0-4] all the .realValue members are set to 22.3
    //while .stringValue member is left untouched
    await context.$.MAIN.arrayValue.$clear()

    //Explicit TcContext kill call
    await context.kill();

})
```

The `tc-context` library currently supports all of the TwinCAT Data Types, **with the exception of**:

* Pointers
* References
* Interfaces
* Arrays of the above mentioned types

***NOTE:*** The `TcContext` Object filters out unsupported members, when generating Symbol Maps. If the end result of a `Structure`, `Funtion_Block` or `Array`, is a Symbol with no Children, no mapping will be created for that Object as well.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    filteredFB : Foo;
    filteredArr : ARRAY[0..9] OF REFERENCE TO Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    ptr: POINTER TO INT;
    ref : REFERENCE TO BYTE;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //booleanValue is defined
    const booleanValue = context.$.MAIN.booleanValue

    //filteredFB is undefined
    const filteredFB = context.$.MAIN.filteredFB

    //filteredArr is undefined
    const filteredArr = context.$.MAIN.filteredArr

    //Explicit TcContext kill call
    await context.kill();

})
```

## [Read, Write and Clear TcSymbol Operations](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    numericValue : INT;
    stringValue : STRING(50);
    enumValue : MyEnum;

END_VAR
```
*MyEnum(ENUM)*
```
TYPE MyEnum :
(
	member1 := 0,
	member2 := 1,
	member3 := 2
);
END_TYPE
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Returns the current value of MAIN.booleanValue
    const booleanValue = await context.$.MAIN.booleanValue.$get

    //Sets the value of MAIN.booleanValue
    await context.$.MAIN.booleanValue.$set(true);

    //Sets the value of MAIN.enumValue to MyEnum.member2 (1) and then read it back
    const enumValue = await context.$.MAIN.enumValue.$set('MyEnum.member2')
        .then(() => context.$.MAIN.enumValue.$get )

    if (enumValue === 'MyEnum.member2') {
        //Clears the MAIN.enumValue to MyEnum.member1 (0)
        await context.$.MAIN.enumValue.$clear()
    }

    //Explicit TcContext kill call
    await context.kill();

})
```

The `TcSymbol` Object supports the following data operations:

* `$set(val)` - method for writing a value to the Binding of the `TcSymbol` Object.
    - when `Promise` is fulfilled, it returns the value, which was successfully written to the `TcSymbol`.
    - when `Promise` is rejected, returns a `TcException` Type Object, with information regarding the error

* `$get` - property for reading the value of the `TcSymbol` Object Binding.
    - when `Promise` is fulfilled, it returns the value, which was successfully read from the `TcSymbol`.
    - when `Promise` is rejected, returns a `TcException` Type Object, with information regarding the error

* `$clear()` - method for clearing the Binding of the `TcSymbol` based on either its default value, or the explicitly specified `Default` Attribute value
    - when `Promise` is fulfilled, clearing has successfully completed
    - when `Promise` is rejected, returns a `TcException` Type Object, with information regarding the error

## [Subscribing to TcSymbol Changes](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    numericValue : INT;
    stringValue : STRING(50);
    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    booleanValue : BOOL;
    arrayValue : ARRAY[0..9] OF INT;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Activate on-change detection
    await context.$.MAIN.numericValue.$subscribe()
    await context.$.MAIN.foo.$subscribe()

    //Attach event handlers
    context.$.MAIN.numericValue.$on('changed', (e) => {
        console.log(`Boolean Value has changed to ${e.data}`);
    })

    context.$.MAIN.foo.$on('changed', (e) => {
        console.log(`{
            booleanValue : ${e.data.booleanValue},
            arrayValue : ${e.data.arrayValue.toString()}
        }`)
    })

    //When no longer change detection is needed, disable it
    await context.$.MAIN.foo.$unsubscribe();

    //Subscribe to an array.
    await context.$.MAIN.foo.arrayValue.$subscribe();
    context.$.MAIN.foo.arrayValue.$on('changed', (e) => {
        console.log(e.data.toString())
    })

    //Explicit TcContext kill call will also
    //automatically unsubscribe all active change subscriptions
    await context.kill();

})
```

`TcSymbol` Objects are capable of subscribing to a data `changed` event of type `TcSymbolChangeEvent`. When subscribed, if the PLC symbol changes its value, any handlers, which were attached, will be invoked. To subscribe `TcSymbol.$subscribe()` must be called, and to disable change detection `TcSymbol.$unsubscribe()` is called. Handlers are added to the `TcSymbol` by way of calling `TcSymbol.$on(...)` and `TcSymbol.$once(...)` and are removed through `TcSymbol.$off(...)`. When unsubscribing, event handlers are **not removed**, they are simply ignored.

When subscribing to `Structures`,`Function_Blocks` and `Arrays`, any change that happens to the data of that symbol, will also result in the `changed` event. This includes change in symbol that are not supported.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    booleanValue : BOOL := FALSE;
    ptr : POINTER TO STRING;
    bar : Bar

END_VAR
```
*Bar(FB)*
```
FUNCTION_BLOCK Bar
VAR

    numericValue : INT := 5;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Activate on-change detection
    await context.$.MAIN.foo.$subscribe()

    //Attach event handlers
    context.$.MAIN.foo.$on('changed', (e) => {
        console.log(e.data);
    }

    //Hypothetical scenario of indefinite run-time

    //When hypothetical scenario is finished
    await context.kill();

})
```

In the example above, a `TcSymbol.$subscribe()` is activated on `MAIN.foo`, which would mean, any change happening in `MAIN.foo` will invoke the `changed` event. When `MAIN.foo.booleanValue` changes from *FALSE* to *TRUE*, the `TcEvent.data` will contain an output:

```js
{
    booleanValue : true,
    bar : {
        numericValue : 5
    }
}
```

Following the previous scenario, if `MAIN.foo.bar.numericValue` has a change from *5* to *10*, this will also produce the `changed` event, with the following output:

```js
{
    booleanValue : true,
    bar : {
        numericValue : 10
    }
}
```

Lastly, even though `MAIN.foo.ptr` is not supported, and a binding to it is not created, it is still part of the data layout of `MAIN.foo` Symbol. It is because of this a change to the pointer value (*not what its pointing to*), will also produce a `changed` event, with the following output (The 2 previous examples have happened) :

```js
{
    booleanValue : true,
    bar : {
        numericValue : 10
    }
}
```

### [Explicit Sampling Rate](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    numericValue : INT;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Subscribe with a sampling rate of 1s
    await context.$.MAIN.numericValue.$subscribe(1000)

    //Attach event handlers
    context.$.MAIN.numericValue.$on('changed', (e) => {
        console.log(e.data);
    }

    //When hypothetical scenario is finished
    await context.kill();

})
```

For Symbols, the value of which changes rapidly, and detection of the change each time would either be too costly or unneeded, it is possible to explicitly set the sampling rate in milliseconds, as the argument for `TcSymbol.$subscribe()`. This will keep any changes of the Symbol from emitting `changed` event between the sampling period.

## [Structured TcSymbols](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    booleanValue : BOOL;
    numericValue : INT;
    stringValue : STRING;
    bar : Bar

END_VAR
```
*Bar(FB)*
```
FUNCTION_BLOCK Bar
VAR

    numericValue : INT;
    booleanValue : BOOL;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    await context.$.MAIN.foo.$set({ booleanValue : true, numericValue : 10});
    let result = await context.$.MAIN.foo.$get;
    /**
     * result : {
     *      booleanValue : true
     *      numericValue : 10
     *      stringValue : ''
     *      bar : {
     *          numericValue : 0
     *          booleanValue : false
     *      }
     * }
     */

    await context.$.MAIN.foo.$set({
        stringValue : 'hello world'
        bar : {
            numericValue : 15,
            booleanValue : true
        }
    })
    result = await context.$.MAIN.foo.$get;
    /**
     * result : {
     *      booleanValue : true
     *      numericValue : 10
     *      stringValue : 'hello world'
     *      bar : {
     *          numericValue : 15
     *          booleanValue : true
     *      }
     * }
     */

    //Writing to a non existent child, will result in an exception
    await context.$.MAIN.foo.$set({ nonExistent : 56.6 })
        .catch(err => console.log(err));
    /**
     * TcBindingOutOfRangeException : ....
     */

    context.$.MAIN.foo.bar.$each(symbol => {
        console.log(symbol.$binding.path)
    })
    /**
     * Output :
     *  MAIN.foo.bar.numericValue
     *  MAIN.foo.bar.booleanValue
     */

    await context.$.MAIN.foo.$clear();
    result = await context.$.MAIN.foo.$get;
    /**
     * result : {
     *      booleanValue : false
     *      numericValue : 0
     *      stringValue : ''
     *      bar : {
     *          numericValue : 0
     *          booleanValue : false
     *      }
     * }
     */

    await context.kill();

})
```

`TcSymbol` Objects are capable of operating on `Structures` and `Function_Blocks`. For `TcContext` both `Structures` and `Function_Blocks` are treated equally as structures of data. It is possible to write only explicit parts of a `TcSymbol` symbol, bound to a `Structure` or `Function_Block`

Calling `TcSymbol.$clear()` will clear all the members of the `Structure` or `Function_Block`, with the only exception of **ignoring any child marked with** ***{attribute 'ReadOnly'}***.
By calling `TcSymbol.$get` property, a full data-map of all nested-children is returned, with the exception of symbol marked with ***{attribute 'Ignore'}***

When writing to a child, which is not part of `TcSymbol`, the operation will result in an exception of type `TcBindingOutOfRangeException`.

### [Method call on Structured TcSymbols](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    booleanValue : BOOL;

END_VAR

{attribute 'TcRpcEnable'}
METHOD basicTask : INT
VAR_INPUT
    lhs : INT,
    rhs : INT
END_VAR

basicTask := lhs + rhs;

{attribute 'TcRpcEnable'}
METHOD complexTask : BOOL
VAR_INPUT
    lhs : INT;
    rhs : INT;
END_VAR
VAR_OUTPUT
	sum : INT;
	diff : INT;
END_VAR

complexTask := TRUE;
sum := lhs + rhs;
diff := lhs - rhs;
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    const basicTask = await context.$.MAIN.foo.basicTask({ lhs : 10, rhs : 15 });
    /**
     * basicTask : {
     *      result : 25
     * }
     */

    const complexTask = await context.$.MAIN.foo.complexTask({ lhs : 15, rhs : 10 });
    /**
     * basicTask : {
     *      result : 25
     *      outputs : {
     *          sum : 25,
     *          diff : 5
     *      }
     * }
     */

    await context.kill();

})
```

It is possible to invoke RPC Methods, marked with `{attribute 'TcRpcEnable'}`, on the PLC Side through the `TcContext`. Upon completion, a Javascript Object is returned with a field `result`, which contains the return value of the method call.
If the method has `VAR_OUTPUT` variables, the return of the method call will also contain `outputs` field, which store the values.

***NOTE:*** As of now, no type checking is performed when passing values to the method call, it is a direct route to the [ads-client](https://github.com/jisotalo/ads-client). See official documentation for the limitations of Rpc Method calls. This is important when dealing with `enumerators`. When writing and reading `enumerators` directly, their type is included, however when passing them to a Rpc Method, the type name of the enum must be omitted.

If the method call fails, exceptions of type `TcComIsInvalidException` or `TcComMethodCallException` are raised.

### [Unions and TcSymbols](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    myUnion : MyUnion;

END_VAR
```
*MyUnion(UNION)*
```
TYPE DUT :
UNION

    a : LREAL;
    b : LINT;
    c : WORD;

END_UNION
END_TYPE
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    let result = await context.$.MAIN.myUnion.$get
    /**
     * result : {
     *      a : 0,
     *      b : 0,
     *      c : 0
     *  }
     */

    await context.$.MAIN.myUnion.c.$set(10)
    let result = await context.$.MAIN.myUnion.$get
    /**
     * result : {
     *      a : 4.94065645841247E-323,
     *      b : 10,
     *      c : 10
     *  }
     */

    await context.kill();

})
```

`UNIONs` are considered Structured symbols in the `tc-context` library, and are accessed and manipulated the same way as Structured `TcSymbols`.

## [Array TcSymbols](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    arr : ARRAY[0..4] OF BOOLEAN;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    await context.$.MAIN.arr.$set([true, true, true]);
    let result = await context.$.MAIN.arr.$get;
    /**
     * result : [true, true, true, false, false]
     */

    await context.$.MAIN.arr.$clear();
    result = await context.$.MAIN.arr.$get;
    /**
     * result : [false, false, false, false, false]
     */

    await context.$.MAIN.arr[3].$set(true);
    result = await context.$.MAIN.arr[3].$get;
    /**
     * result : true
     */

    result = await context.$.MAIN.arr.$get;
    /**
     * result : [false, false, true, false, false]
     */

    context.$.MAIN.arr.$each(symbol => {
        console.log(symbol.$binding.name)
    })
    /**
     * Output :
     *  arr[0]
     *  arr[1]
     *  arr[2]
     *  arr[3]
     *  arr[4]
     */

    await context.kill();

})
```

The `TcContext`is capable of generating a `TcSymbol` for TwinCAT array types, allowing for reading, writing, clearing and subscribing operations on the array as a whole, as well as accessing individual members through the subscript operator.
***NOTE:*** The indexes of `TcSymbol` array are synchronized with the TwinCAT array indexes. This means the starting index of a `TcSymbol` of an `array` is that of the starting symbol of the TwinCAT `array`.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    arr1 : ARRAY[0..4] OF INT;
    arr2 : ARRAY[1..5] OF INT;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    console.log({
        startIndex : context.$.MAIN.arr1.$startIndex,
        length : context.$.MAIN.arr1.$length
    })
    /**
     * Output : { startIndex : 0, length : 5 }
     */

    console.log({
        startIndex : context.$.MAIN.arr2.$startIndex,
        length : context.$.MAIN.arr2.$length
    })
    /**
     * Output : { startIndex : 1, length : 5 }
     */

    context.$.MAIN.arr1.$each((symbol, index) => {
        console.log({ index, name : symbol : symbol.$binding.key})
    })
    /**
     * Output :
     *  { index : 0, symbol : arr1[0]}
     *  { index : 1, symbol : arr1[1]}
     *  { index : 2, symbol : arr1[2]}
     *  { index : 3, symbol : arr1[3]}
     *  { index : 4, symbol : arr1[4]}
     */

    context.$.MAIN.arr2.$each((symbol, index) => {
        console.log({ index, name : symbol : symbol.$binding.key})
    })
    /**
     * Output :
     *  { index : 1, symbol : arr1[1]}
     *  { index : 2, symbol : arr1[2]}
     *  { index : 3, symbol : arr1[3]}
     *  { index : 4, symbol : arr1[4]}
     *  { index : 5, symbol : arr1[5]}
     */

    //elem is undefined
    const elem = context.$.MAIN.arr2[0];

    await context.kill();

})
```

### [Multidimensional Array](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    arr1 : ARRAY[0..2, 0..2] OF INT;
    arr2 : ARRAY[0..2] OF ARRAY[0..2] OF INT;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    let result = await context.$.MAIN.arr1.$get;
    /**
     * result : [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
     */

    result = await context.$.MAIN.arr1[1].$get;
    /**
     * result : [0, 0, 0]
     */

    await context.$.MAIN.arr2[2].$set([1, 2, 3])
    result = await context.$.MAIN.arr2.$get;
    /**
     * result : [[0, 0, 0], [0, 0, 0], [1, 2, 3]]
     */

    await context.$.MAIN.arr1[1][1].$set(10);
    result = await context.$.MAIN.arr1[1].$get;
    /**
     * result : [0, 10, 0]
     */

    result = await context.$.MAIN.arr2.$clear()
        .then(() => context.$.MAIN.arr2.$get)
    /**
     * result : [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
     */

    result = await context.$.MAIN.arr1[1].$clear()
        .then(() => context.$.MAIN.arr1.$get)
    /**
     * result : [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
     */

    await context.kill();

})
```

TwinCAT allows for 2 different ways of declaring Multidimensional Arrays :
* `ARRAY[dimension1, dimension2, ...., dimensionN] OF <type>`
* `ARRAY[dimension1] OF ARRAY[dimension2] OF ..... ARRAY[dimensionN] of <type>`

Regardless of the case, the `TcContext` treats both of these multidimensional arrays as multidimensional Javascript Arrays, and will process them accordingly. This allows for `TcSymbol.$get`, `TcSymbol.$set()`, `TcSymbol.$clear()` and `TcSymbol.$subscribe()` operations on any of the dimension levels.

## [TcSymbol Types](#table-of-contents)

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    numericValue : INT[10..50];
    stringValue : STRING(10);
    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    arrayValue : ARRAY[0..4] OF int;
    enumValue : MyEnum;

END_VAR
```
*MyEnum(ENUM)*
```
TYPE MyEnum :
(
	member1 := 0,
	member2 := 1,
	member3 := 2
);
END_TYPE
```
*index.js*
```js
const { TcContext, TcSymbols } = require('tc-context')

TcContext.create().then(async context => {

    if (context.$.MAIN.numericValue instanceof TcSymbols.TcNumericSymbol) {
        console.log({
            min : context.$.MAIN.numericValue.$lowerBorder
            max : context.$.MAIN.numericValue.$upperBorder
        })
    }
    /**
     * Output :
     * { min : 10, max : 50 }
     */

    if (context.$.MAIN.stringValue instanceof TcSymbols.TcStringSymbol) {
        console.log({ length : context.$.MAIN.stringValue.$length })
    }
    /**
     * Output :
     * { length : 10 }
     */

    if (context.$.MAIN.foo instanceof TcSymbols.TcStructureSymbol) {
        context.$.MAIN.foo.$each(symbol => {
            if (symbol instanceof TcSymbols.TcArraySymbol) {
                console.log({ length : symbol.$length })

            } else if (symbol instanceof TcSymbols.TcEnumSymbol) {
                console.log({ fields : symbol.$fields })
            }
        })
    }
    /**
     * Output :
     * { length : 5 }
     * { fields : ['MyEnum.member1', 'MyEnum.member2', 'MyEnum.member3']}
     */

    //Explicit TcContext kill call
    await context.kill();

})
```

`TcSymbol` provides the base foundation for `TcContext` Symbol Map creation. Each of the `TcSymbols`, has a concrete type, depending on the PLC Symbol Type. The concrete `TcSymbol` performs type checks and range checks, as well as exposes additional, type specific, functionality. The concrete types of `TcSymbol` and their unique functionality is described below.

There is no implicit type conversion done. All symbols must be provided with the exact type of value, when performing `TcSymbol.$set()` operations. The reason is to ensure there is no ambiguity when operating on the PLC.

### [TcBooleanSymbol](#table-of-contents)

`TcBooleanSymbol` represents the `BOOL` Data Type of the PLC, and is the most similar to the base `TcSymbol`. The only difference is, that it performs type checking abd throwing an exception of type `TcBindingInvalidTypeException`, if during the `TcSymbol.$set()` call, the value passed is not of type `boolean`.

### [TcNumericSymbol](#table-of-contents)

`TcNumericSymbol` represents all the numeric Data Type Symbols of the PLC, and exposes additional symbol information, in the form of `TcNumericSymbol.$upperBorder` and `TcNumericSymbol.$lowerBorder`.

When performing a `TcSymbol.$set()`, the input value is check to be of type `number`, and that the value is within the specified range. Failure to comply results in exceptions of type `TcBindingInvalidTypeException` and `TcBindingOutOfRangeException` respectfully.

### [TcStringSymbol](#table-of-contents)

`TcStringSymbol` represents `STRING` and `WSTRING` Data Types of the PLC, and exposes the `TcStringSymbol.$length` property, which states the maximum length of a string, that can be written to it.

`TcStringSymbol` performs type checking on the the passed argument to `TcSymbol.$set()` to make sure it is of type `string` and does not exceed the specified length. Failure to comply results in exceptions of type `TcBindingInvalidTypeException` and `TcBindingOutOfRangeException` respectfully.

### [TcEnumSymbol](#table-of-contents)

`TcEnumSymbol` represents the `ENUM` Data Types of the PLC and provides the `TcEnumSymbol.$fields` property. This property provides a list of strings of all the acceptable inputs to the `TcSymbol.

The `TcEnumSymbol` performs type checking on the the passed argument to `TcSymbol.$set()` to make sure it is of type `string` and is part of the `TcEnumSymbol.$fields` list. Failure to comply results in exceptions of type `TcBindingInvalidTypeException` and `TcBindingOutOfRangeException` respectfully.

***IMPORTANT:*** Alias to `ENUM` is treated as its own unique type. Be aware of this.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    enumValue : MyEnum;

END_VAR
```
*MyEnum(ENUM)*
```
TYPE MyEnum :
(
	member1 := 0,
	member2 := 1,
	member3 := 2
);
END_TYPE
```
*index.js*
```js
const { TcContext, TcEnumSymbol } = require('tc-context');

TcContext.create().then(async context => {

    if (context.$.MAIN.enumValue instanceof TcSymbols.TcEnumSymbol) {
        console.log(context.$.MAIN.enumValue.$fields)
    }
    /**
     * Output :
     * ['MyEnum.member1', 'MyEnum.member2', 'MyEnum.member3']
     */

    await context.$.MAIN.enumValue.$set('MyEnum.member3');
    let result = await context.$.MAIN.enumValue.$get;
    /**
     * result : 'MyEnum.member3'
     */

    await context.$.MAIN.enumValue.$set('WrongValue')
        .catch(err => console.log(err))
    /**
     * Output :
     *  TcBindingOutOfRangeException
     */

    await context.kill()

})
```

### [TcStructureSymbol](#table-of-contents)

`TcStructureSymbol` represents `Structure` and `Function_Block` Data Types of the PLC. As of now, no distinction between the two types is made from the pointer of view of `TcContext`.

The `TcStructureSymbol` performs a type check, to make sure any argument that is passed to `TcSymbol.$set()` is a plain Javascript Object, otherwise a `TcBindingInvalidTypeException` exception is raised.

Additionally, `TcStructureSymbol` provides `TcStructureSymbol.$each()` function, which iterates over all of its children `TcSymbols`.

### [TcArraySymbol](#table-of-contents)

`TcArraySymbol` represents `ARRAY[...] OF <type>` Data Type of the PLC. Similarly to the `TcStructureSymbol`, the `TcArraySymbol` also provides a `TcArraySymbol.$each()` function, which iterates over all of its children `TcSymbols`.

Due to TwinCAT allowing to explicitly specify the starting index of an array, that start index can be read through the `TcArraySymbol.$startIndex` property. Lastly, `TcArraySymbol.$length` allows to read the length of the `TcArraySymbol` array.

When writing to `TcSymbol.$set()`, the `TcArraySymbol` will perform type checking on the input argument, to make sure it is of type `array`, as well as that the written array does not exceed the length of the `TcArraySymbol`. Failure to comply results in exceptions of type `TcBindingInvalidTypeException` and `TcBindingOutOfRangeException` respectfully.

## [Invalidated TcSymbol](#table-of-contents)

In a situation the where the `TcContext` was `reinitialized`, any previously stored `TcSymbol` becomes invalidated. One way to managed invalidation, is by assigning a callback to `TcSymbol.$onInvalidated()` method. This method will be called, when the `TcContext` invalidates the `TcSymbol`. Invalidation in a Symbol Map happens from the bottom-up, where children are invalidated before their parents are.

## [TcSymbol Attributes](#table-of-contents)

Beckhoff PLC Symbol can be marked with special attributes, which are processed by `TcContext`. These attributes alter the behavior of some `TcSymbols` and impose additional rules.

### [TcSymbol Default Attribute](#table-of-contents)

All Primitive Data Types (Not `Structures`, `Function_Blocks` or `Arrays`) support the `Default` Attribute. This attribute informs what value to write upon a call to `TcSymbol.$clear()`. If no value is specified, the value that is written, is that of a an initial value (false for `boolean`, 0 for `numbers` and empty string for `string`).

`Structures`, `Function_Blocks` and `Arrays` are not affected by the `Default` attribute.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    {attribute 'Default' := 'true'}
    booleanValue : BOOL;
    {attribute 'Default' := '5'}
    numericValue : INT;
    {attribute 'Default' := 'hello world'}
    stringValue : STRING(50);
    {attribute 'Default' := 'member3'}
    enumValue : MyEnum;

END_VAR
```
*MyEnum(ENUM)*
```
TYPE MyEnum :
(
	member1 := 0,
	member2 := 1,
	member3 := 2
);
END_TYPE
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //MAIN.booleanValue is set to true
    await context.$.MAIN.booleanValue.$clear()

    //MAIN.numericValue is set to 5
    await context.$.MAIN.numericValue.$clear()

    //MAIN.stringValue is set to 'hello world'
    await context.$.MAIN.stringValue.$clear()

    //MAIN.enumValue is set to 'MyEnum.member3'
    await context.$.MAIN.enumValue.$clear()

    //Explicit TcContext kill call
    await context.kill();

})
```

### [TcSymbol ReadOnly Attribute](#table-of-contents)

All Bindable Types support the `ReadOnly` Attribute. The `ReadOnly` attributes ensures that no write operation can be made to the `TcSymbol` Object, either through the `TcSymbol.$set()` method or `TcSymbol.$clear()`. If a write operation is made to a `ReadOnly` Object, a `TcBindingReadOnlyException` Exception is thrown.

If `TcStructureSymbol` or `TcArraySymbol` is marked as `ReadOnly`, then all of their children `TcSymbols` are marked as `ReadOnly` as well. When calling `TcSymbol.$clear()` on `TcStructureSymbol` Object that is not `ReadOnly`, but has children marked as `ReadOnly`, those children will be ignored during the `TcSymbol.$clear()` operation.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    {attribute 'ReadOnly'}
    booleanValue : BOOL;
    {attribute 'ReadOnly'}
    numericValue : INT;
    {attribute 'ReadOnly'}
    readOnlyFoo : Foo;
    normalFoo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    {attribute 'ReadOnly'}
    stringValue: STRING := 'hello world';
    numericValue : BYTE := 100;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //MAIN.booleanValue will throw exception
    await context.$.MAIN.booleanValue.$clear().catch(err => {
        //MAIN.booleanValue is ReadOnly. This block will execute
    })

    //MAIN.numericValue will throw exception
    await context.$.MAIN.numericValue.$clear().catch(err => {
        //MAIN.numericValue is ReadOnly. This block will execute
    })

    //MAIN.foo will throw exception
    await context.$.MAIN.foo.$clear().catch(err => {
        //MAIN.foo is ReadOnly. This block will execute
    })

    //This will not raise an exception, however MAIN.normalFoo.stringValue will be left untouched
    const result = await context.$.MAIN.normalFoo.$clear().then(() => context.$.MAIN.normalFoo.$get);
    /**
     * result : {
     *      stringValue : 'hello world'
     *      numericValue : 0
     * }
     */

    //Explicit TcContext kill call
    await context.kill();

})
```

### [TcSymbol Ignore Attribute](#table-of-contents)

All bindable types support the `Ignore` Attribute. The `Ignore` attributes ensures that no `TcSymbol` generation takes place by the `TcContext`. The `Ignore` attribute, when applied to `TcStructureSymbol` and `TcArraySymbol`, will also be applied to its children. If the end result of a `TcStructureSymbol` is an Object with no children, then that `TcStructureSymbol` will also be ignored.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    numericValue : INT;
    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    {attribute 'Ignore'}
    stringValue: STRING := 'hello world';
    byteValue : BYTE := 100;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //booleanValue is defined
    const booleanValue = context.$.MAIN.booleanValue;

    //numericValue is defined
    const numericValue = context.$.MAIN.numericValue;

    //byteValue is defined
    const byteValue = context.$.MAIN.foo.byteValue;

    //stringValue is undefined
    const stringValue = context.$.MAIN.foo.stringValue;

    //Explicit TcContext kill call
    await context.kill();

})
```

### [TcSymbol Event Alias Attribute](#table-of-contents)

It is possible to apply an alias to the events produced by `TcSymbols`. This way it is possible to narrow-down event handling, based on the specified alias.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    {attribute 'onSet' := 'stringSet'}
    stringValue: STRING := 'hello world';

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Listen for the aliased event
    context.$.MAIN.foo.stringValue.$on('stringSet', (e) => {
        console.log('set was aliased to stringSet : ', e.data);
    })

    //Explicit TcContext kill call
    await context.kill();

})
```

When aliasing a `TcSymbol's` event, the default event name will be replaced by the provided name, based on the Attribute Parameter. These attributes are:
* `onSet` - will replace the `set` event
* `onGet` - will replace the `get` event
* `onClear` - will replace the `cleared` event
* `onChange` - will replace the `changed` event.

# [TcEvents](#table-of-contents)

All events emitted by the components of `TcContext` inherit from `TcEvent`. The `TcEvent` in `TcContext` are designed to propagate the emitted event up from the component , all the way to the `TcContext` Object.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL;
    numericValue : INT;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    context.$.MAIN.booleanValue.$on('set', () => {
        console.log('set was called on MAIN.booleanValue')
    })

    context.on('set', () => {
        console.log('event propagated to context, where it was also caught')
    })

    await context.$.MAIN.booleanValue.$set(true);
    /**
     * When set completed output :
     * 'set was called on MAIN.booleanValue'
     * 'context also caught the event'
     */

    //Explicit TcContext kill call
    await context.kill();

})
```

If the `TcEvent` has been handled, and the propagation of the event is no longer wanted, a call to `TcEvent.stopPropagation()` function will stop any propagation up towards `TcContext`.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    foo : Foo;

END_VAR
```
*Foo(FB)*
```
FUNCTION_BLOCK Foo
VAR

    {attribute 'onChange' := 'booleanChanged'}
    booleanValue: BOOL;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    context.$.on('booleanChanged', (e) => {
        console.log('caught booleanChanged event')
        e.stopPropagation()
    })

    context.on('booleanChanged', () => {
        //This will never happen, because event stopped Propagated
    })

    //Explicit TcContext kill call
    await context.kill();

})
```

## [TcEvent List](#table-of-contents)

List of all events produced by the `tc-context` library.

Component | Event | Event Type | Description
-|-|-|-
`TcComponent` | `killed` | `TcContextKilledEvent` | When the current `TcContext` is killed and no longer is valid
| `reinitialized` | `TcContextReinitializedEvent` | When the current `TcContext` was rebuild and is once again valid
`TcCom`| `connected` | `TcComConnectedEvent` | When the current `TcContext` established the initial connection to the PLC
| `disconnected` | `TcComDisconnectedEvent` | When the current connection to the PLC has been closed
| `sourceChanged` | `TcComSourceChangedEvent` | When the PLC Code base changes during an active connection
| `connectionLost` | `TcComConnectionLostEvent` | When the TcCom looses connection to the Target PLC
| `reconnected` | `TcComReconnectedEvent` | When the TcCom reestablishes the connection to the Target PLC
`TcSymbol` | `set` | `TcSymbolSetEvent` | When a `.$set()` operation was completed
| `get` | `TcSymbolGetEvent` | When a `.$get` operation was completed
| `cleared` | `TcSymbolClearedEvent` | When a `.$clear()` operation was completed
| `changed` | `TcSymbolChangedEvent` | When the symbol value changed post `.$subscribe()` operation
`TcSymbolRegistry` | `created` | `TcSymbolRegistryCreatedEvent` | When the Symbol Map has been created
| `destroyed` | `TcSymbolRegistryDestroyedEvent` | When the Symbol Map has been destroyed
`TcTypeRegistry` | `created` | `TcTypeRegistryCreatedEvent` | When the Type Map has been created
| `destroyed` | `TcTypeRegistryDestroyedEvent` | When the Type Map has been destroyed

## [TcEvent Hierarchy](#table-of-contents)

Base | Component | Concrete
-|-|-
`TcEvent` | `TcContextEvent` | `TcContextReinitializedEvent`
|| `TcContextKilledEvent`
| `TcSymbolEvent` | `TcSymbolGetEvent`
|| `TcSymbolSetEvent`
|| `TcSymbolClearedEvent`
|| `TcSymbolChangedEvent`
| `TcComEvent` | `TcComConnectedEvent`
|| `TcComDisconnectedEvent`
|| `TcComSourceChangedEvent`
| `TcTypeRegistryEvent` | `TcTypeRegistryCreatedEvent`
|| `TcTypeRegistryDestroyedEvent`
| `TcSymbolRegistryEvent` | `TcSymbolRegistryCreatedEvent`
|| `TcSymbolRegistryDestroyedEvent`

# [Understanding TcContext Lifecycle](#table-of-contents)

```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Attach listeners for kill event...
    context.on('killed', () => console.log('context was killed'));

    //TcContext manipulation code.....

    //Explicit TcContext kill call
    await context.kill();

    //TcContext is no longer valid after this point, and
    //any symbols produced by it should no longer be used...

})

/**
 * Expected output:
 *
 * context was killed
 */
```
During normal operation, a `TcContext` is valid from the moment it was created through `TcContext.create()` call, upon until a call to `TcContext.kill()` is made. When `TcContext.kill()`completes its task, a `killed` event of type `TcContextKilledEvent` is emitted, which can be captured.

This holds true if ***no PLC-side code changes have been made from `TcContext's` creation moment***. If Activation of new configuration, or any Code Change takes place after `TcContext.create()` was called, then that change in `TcContext` will be detected. When detected, the `TcContext` will invalidate all the created `TcSymbols`, remove all subscriptions, clear Type and Symbol maps, kill itself, and then it will build a new map, based on the new symbols types and locations, which are present in the PLC.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL := TRUE;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

TcContext.create().then(async context => {

    //Attach listeners for kill and reinitialized events...
    context.on('killed', () => console.log('context was killed'));
    context.on('reinitialized', () => console.log('context was reinitialized'));

    //Storing the symbol for use.
    const booleanValue = context.$.MAIN.booleanValue;

    /**
     * Hypothetical scenario...
     * Some code that uses the context cyclically for undefined period of time
     * without yet reaching the .kill() call.
     *
     * During this hypothetical time - the PLC Configuration was changed
     */

    //The line below is reached only after the PLC Configuration was changed
    //in the above hypothetical scenario
    await booleanValue.$set(true)
        .catch(err => console.log(err));

/**
 * Expected output:
 *
 * context was killed
 * context was reinitialized
 * TcBindingIsInvalidException :
 *      Attempting to read an Invalidated TcBinding[\<symbol name\>] ( \<symbol path\> )...
 */
})
```

As seen above, if after `TcContext` was created, changes to code of the PLC have been made, the `TcContext` will detect it, and perform the `TcContext.kill()` operation automatically, upon completion of which, the `killed` event of type `TcContextKilledEvent` will be raised. Afterwards, the `TcContext` will reconnect to the PLC, and a generation and build of new Type and Symbol Maps is executed. When completed the `TcContext` will raise the `reinitialized` event of type `TcContextReinitializedEvent`. Any attempt to perform operations on any previously stored Invalidated `TcSymbols` (such as `booleanValue` in the example above), will result in an exception of type `TcBindingIsInvalidException`

These events can be used, as means of updating any dependencies, which utilize the created `TcSymbols` by the `TcContext` and thus ensuring stability.

***NOTE:*** The reason for this approach, is because upon `TcContext` creation, a scan is performed, which caches all the Types and Symbols, as well as their memory locations in the PLC. These memory locations are used as a means of reading, writing, clearing and subscribing to symbols, simple or complex. When an online change is performed, there are no guaranties that the location of the previously cached symbols is same, and even if an update to it can be made, the symbol itself could be of different type. All this would result in **undefined behavior**.

*MAIN(PRG)*
```
PROGRAM MAIN
VAR

    booleanValue : BOOL := TRUE;

END_VAR
```
*index.js*
```js
const { TcContext } = require('tc-context')

//Example of class which uses a symbol for its operation
class Foo {

    //Bind the symbol at construction
    constructor(symbol) { this.__symbol = symbol; }

    //Means to update the binding of the symbol
    bind(symbol) {
        console.log('setting new symbol')
        this.__symbol = symbol
    }

    //Method which uses the symbol
    async printState() {
        if (this.__symbol) {
            const val = await this.__symbol.$get;
            return (val) ? 'Symbol is on' : 'Symbol is off'
        }
    }
}

TcContext.create().then(async context => {

    //Create the object which is dependent on the TcContext's symbol
    const bar = new Foo(context.$.MAIN.booleanValue);

    //When invalidated set the binding to null
    context.$.MAIN.booleanValue.$onInvalidated(() => {
        console.log('symbol was invalidated')
        bar.bind(null);
    })

    context.on('reinitialized', () => {
        console.log('context was reinitialized')
        bar.bind(context.$.MAIN.booleanValue);
    })

    /**
     * Hypothetical scenario...
     * Some code that uses the context cyclically for undefined period of time
     * without yet reaching the .kill() call.
     *
     * During this hypothetical time - the PLC Configuration was changed
     */

    //The line below is reached only after the PLC Configuration was
    //changed in the above hypothetical scenario
    await bar.printState()
    await context.kill()
})

/**
 * Expected output:
 *
 * symbol was invalidated
 * setting new symbol
 * context was reinitialized
 * setting new symbol
 * Symbol is on
 * symbol was invalidated
 * setting new symbol
 */
```

The example above illustrates how any components, which depends on `TcSymbol`, can use the emitted events to refresh its bindings, thus ensuring defined behavior.

# [TcExceptions](#table-of-contents)

Base | Component | Concrete | Description
-|-|-|-
`TcException` | `TcBindingException` | `TcBindingIsInvalidException` | When operations are made on a `TcSymbol` of a killed `TcContext`
|| `TcBindingInvalidTypeException` | When input type does not match `TcSymbol` type
|| `TcBindingOutOfRangeException` | When input data length is outside the boundaries of `TcSymbol`
|| `TcBindingReadOnlyException` | When write commands are called on a Read-only `TcSymbol`
| `TcComException` | `TcComBusyException` | Connection to a PLC has already been made
|| `TcComConnectException` | When an error occurred with establishing connection
|| `TcComIsInvalidException` | When operations are made on a `TcCom` of a killed `TcContext`
|| `TcComDisconnectException` | When an error occurred with disconnecting from Target
|| `TcComChangeDetectionException` | When an error occurred with establishing Code Change Monitoring
|| `TcComUnsubscribeException` | When an error occurred with unsubscribing from TwinCAT Symbol
|| `TcComFromRawException` | When an error occurred when transforming Data from Raw
|| `TcComToRawException` | When an error occurred when transforming Data to Raw
|| `TcComSubscribeException` | When an error occurred with subscribing to a TwinCAT Symbol
|| `TcComDataWriteException` | When an error occurred during data writing to TwinCAT
|| `TcComDataReadException` | When an error occurred during data reading from TwinCAT
|| `TcComTypeQueryException` | When an error occurred with querying Type Data from TwinCAT
|| `TcComSymbolQueryException` | When an error occurred with querying Symbol Data from TwinCAT
|| `TcComMethodCallException` | When an error occurred with invoking a RPC Method over ADS

# [Documentation](#table-of-contents)

Detailed documentation of the `TcContext` code base itself can be found under the /docs/ folder in this repository.

# [Acknowledgments](#table-of-contents)

* Jussi Isotalo<EMAIL_ADDRESS>and his [ads-client](https://github.com/jisotalo/ads-client) library

# [License](#table-of-contents)

*Licensed under MIT License.*

*Copyright (c) 2020 Dmitrij Trifanov<EMAIL_ADDRESS>
*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*

*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*

*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*

repository: DmitrijTrifanov/TcContext

gha_language: TypeScript

repo_name: DmitrijTrifanov/TcContext


text:
---
layout: default
modal-id: 3
date: 2014-07-16
img: speech-bubble.png
alt: image-alt
title: North Highland
project-date: Fall 2015
subject: Consulting and Marketing
category: School - MGT 201
computer-languages: N/A

description1: North Highland is a global consulting firm with a differentiated business model. Instead of centralizing operations at a large main office and flying consultants to their engagements, North Highland opens branches where their clients are. In 2010, North Highland opened a St. Louis branch.

description2: As a part of a Management Communications course, our team developed a communication strategy to aid the St. Louis branch of North Highland in increasing its presence and preference in the region. Our analysis included an executive summary, an industry report, an audience profile, and various potential vehicles and messaging strategies to bolster North Highland's position in St. Louis. After developing our comprehensive communication strategy, we presented our solutions to the St. Louis' branch's upper management.

---


text:
## Services

Services are expandable modules that can be added or removed. Dependencies between services should be avoided.

```bash
|-- services
    |-- auth
    |-- express
    |-- mongoose
    |-- request
    |-- response
```

If the module also offers the possibility to extend it, you can create subfolders like plugins. For example with mongoose

```bash
|-- services
    |-- mongoose
        |-- plugins
            |-- filter.js
            |-- gravatar.js
            |-- ownership.js
            |-- paginate.js
        |-- index.js
```

repository: lokabees/api

repo_name: lokabees/api


text:
# This rule warns about the usage of extra whitespaces between attributes (no-multi-spaces)

The `--fix` option on the command line can automatically fix some of the problems reported by this rule.

This rule aims to remove multiple spaces in a row between attributes witch are not used for indentation.

## Rule Details

Examples of **incorrect** code for this rule:

```html
<template>
  <div class="foo"      :style="foo"
    :foo="bar"         >
  </div>
</template>
```

Examples of **correct** code for this rule:

```html
<template>
  <div class="foo"
    :style="foo">
  </div>
</template>
```

### Options

Nothing

repository: silyont/eslint-plugin-vue

repo_name: silyont/eslint-plugin-vue


text:
## Restic IDs

Or [storage IDs](https://restic.readthedocs.io/en/latest/100_references.html#terminology), are what restic uses to name files in a repository. The [official documentation](https://restic.readthedocs.io/en/latest/100_references.html#repository-format) talks about them.

From a practical point of view, it means that you can `sha256sum` a file like `/tmp/restic/data/18/183f81b766a871529418937195e967f0d1b8c5b7d81b24cee601e3f4ec21a388` (a pack file) and the SHA256 hash of the contents will be equal to the file name:

```
sha256sum /tmp/restic/data/18/183f81b766a871529418937195e967f0d1b8c5b7d81b24cee601e3f4ec21a388
183f81b766a871529418937195e967f0d1b8c5b7d81b24cee601e3f4ec21a388  /tmp/restic/data/18/183f81b766a871529418937195e967f0d1b8c5b7d81b24cee601e3f4ec21a388
```

This can be easily used to detect file tampering or corruption in a repository, ensuring the integrity of the blobs contained in a pack or other repository files.


text:
# Textifai
A web-based and social text analyzation project aiming to provide insights about language and its usage.
http://textifai.herokuapp.com

## General Dependencies:
- NLTK
- Pillow
- Indicoio
- Whitenoise

Install these dependencies using pip by typing the following commands in a terminal:
```
pip install nltk
pip install pillow
pip install indicoio
pip install whitenoise
```

## NLTK Dependencies
1 - After installing NLTK, you need to install a few NLTK-specific packages for everything to work properly.
Type the following in the python3 interactive shell:
```
import nltk
nltk.download()
```
2 - The NLTK Downloader GUI should display. Click the "All Packages" tab, and install the following:
- averaged_perceptron_tagger
- punkt
- vader_lexicon

If a NLTK Downloader GUI didn't display in step 2, type the following commands in a terminal:
```
python -m nltk.downloader averaged_perceptron_tagger
python -m nltk.downloader punkt
python -m nltk.downloader vader_lexicon
```

gha_language: HTML


text:
# WebDVM

A low-cost Digital Volt-Meter (DVM) using an Arduino and Raspberry Pi zero
with a browser interface.

You can find websocketd [here](https://github.com/joewalnes/websocketd).
Yiou can download the latest release [here](https://github.com/joewalnes/websocketd/releases)

I've described the project in a series of three blog posts. Start
[here](https://blog.rareschool.com/2019/06/build-web-based-dvm-using-arduino-and.html).

## Hardware required

1. An Arduino Uno. (Other models would work; I've tested it with a Nano.)
1. A Raspberry Pi zero W or a full-size Pi, with Raspbian Stretch and WiFi set up
or a wired (Ethernet) connection.
1. A cable or cables to connect the Arduino to the USB port on the Pi.
1. A power source for the Pi and a cable to connect it.
1. A computer with a browser connected to the same network as the Pi.

## Installation

1. On the Arduino, install dvm.ino from this repository
1. On the Pi,
    1. Download the zip file from GitHub.

        `wget https://github.com/romilly/WebDVM/archive/master.zip`
    1. Unzip it: `unzip master.zip`
    1. Change to the newly created directory: `cd WebDVM-master`
    1. If you've changed the Raspberry Pi's hostname, edit `index.html`
    to reflect the current hostname.
    1. Run `./websocketd --port=8080 --staticdir=. ./read-dvm.py`
1. In your browser, open `raspberrypi:8080` (or use whatever hostname you chose for the Pi)

Have fun!

If you hit problems, please raise an issue on GitHub.

If you have questions, I'm [@rareblog](https://twitter.com/rareblog) on Twitter.

repository: romilly/WebDVM

repo_name: romilly/WebDVM


text:
# Reporting
Once your tests have run, you most likely would want to save the result of these testruns somewhere. With Playwright you can use the built-in reporters, integrate with a few third party reporters such as Allure or even built your own custom reporters using the [Reporter API](https://playwright.dev/docs/api/class-reporter).

## Exercise: Configure a built-in reporter
You can specify the type of reporter in the Playwright config file (`playwright.config.ts`).
Try replacing the HTML reporter by the [List reporter](https://playwright.dev/docs/api/class-reporter), run your test and notice how the output is different.

You are only able to see the HTML reporter output if your tests fails with the command `npx playwright test`.

## Exercise: Multiple reporters

You can also have more than 1 reporter. Try to combine the line reporter with the HTML reporter. More information can be found [HERE](https://playwright.dev/docs/test-reporters#multiple-reporters).

repository: xebia/cypress-training

path: /docs/Playwright/4. Reporting.md

filename: 4. Reporting.md

repo_name: xebia/cypress-training


text:
# Dictionary / Locals

Unlike many other languages, f♭ does not have a concept of variables or lambdas.  Like most stack based languages the primary location for value storage is the stack.  f♭ has a write once dictionary for storage of word definitions.  Values within a dictionary cannot be overwritten or deleted. However, using child stacks \(discussed later\) dictionary words can be shadowed. \(similar to JS scoping rules\).

Values can be stored and recalled from the stack using the `sto` and `rcl` verbs.

```
f♭> 123 x: sto
[  ]

f♭> x: rcl
[ 123 ]

f♭> x: 456 sto
Error: Cannot overrite definitions in strict mode: x
[  ]

f♭> x: rcl
[ 123 123 ]

f♭> clr [ 456 x: sto x: rcl ] fork x: rcl
[ [ 456 ] 123 ]
```

## Word requirements

* Cannot contain a colon \(`:`\) \(special meaning\)
* Cannot start with a period `.`
* Cannot contain white space \(space, new lines, tabs, or comma `,`\).
* Cannot contain brackets \( `(){}[]` \).
* Cannot contain quotes \( '"\` \)
* Cannot be numeric \(starting with a numeric value is ok\)
* Cannot begin with a hash \(`#`\)
* Cannot be a reserved word \(`null`, `true` or `false`\)


text:
# Wrappers (experimental)

This is a placeholder for now: we will likely soon start adding
standardized wrappers for environments. (Only stable and
general-purpose wrappers will be accepted into gym core.)

Note that we may later restructure any of the files, but will keep the
wrappers available at the wrappers' top-level folder. So for
example, you should access `MyWrapper` as follows:

```
# Will be supported in future releases
from environments.mujoco2.rand_param_envs.gym.wrappers import MyWrapper
```

## How to add new wrappers to Gym

1. Write your wrapper in the wrappers' top-level folder.
2. Import your wrapper into the `__init__.py` file. This file is located at `/gym/wrappers/__init__.py`. Add `from environments.mujoco2.rand_param_envs.gym.wrappers.my_awesome_wrapper import MyWrapper` to this file.
3. Write a good description of the utility of your wrapper using python docstring format (""" """ under the class definition)

## Quick Tips

- Don't forget to call super(class_name, self).__init__(env) if you override the wrapper's __init__ function
- You can access the inner environment with `self.unwrapped`
- You can access the previous layer using `self.env`
- The variables `metadata`, `action_space`, `observation_space`, `reward_range`, and `spec` are copied to `self` from the previous layer
- Create a wrapped function for at least one of the following: `__init__(self, env)`, `_step`, `_reset`, `_render`, `_close`, `_configure`, or `_seed`
- Your layered function should take its input from the previous layer (`self.env`) and/or the inner layer (`self.unwrapped`)

repository: lmzintgraf/varibad

gha_license_id: NOASSERTION

repo_name: lmzintgraf/varibad


text:
## Setup to edit the talk page
The slides were created using Reveal.js. The HTML content was generated using the ~~Jade~~ Pug template engine. Quick setup:

If you don't have it, get [node.js](https://nodejs.org/en/) and npm. Most nodejs packages bundle npm.
```
git clone https://github.com/andrewadare/arduino-201.git
cd arduino-201/slides
npm install
git clone https://github.com/hakimel/reveal.js.git
git checkout -b 3.3.0 3.3.0  # Do this in reveal.js/
```
Then, in slides/, try editing index.pug and do `pug index.pug` to generate index.html.


text:
---
uid: oliviernicole
date: 2016-10-31
enddate: 2016-11-06
week: 45
generator: furore
---

* Monday (2016-11-07)
: Laptop still in repair, spent all day trying to get a desktop PC as a
  replacement. Will use one of the lab shared computers from now on.
* Tuesday
: Added a new `value_kind` for macros and made the typechecker tag macros with
  it.
* Wednesday
: Stopped keeping track of cross-stage identifiers in the typing environment.
  Instead, iterate through the typed tree to find them in a expression when
  needed.
During the Compiler hacking event at Pembroke, paired with Maxime to work on
signatured opens (https://github.com/ocamllabs/compiler-hacking/wiki/Things-to-work-on#signatured-open-command); we're about halfway through it.
* Thursday
: Add support (parser and typechecker) for macros in signatures.
* Friday
: Add a closure argument to macros, yet unused.

repository: ocamllabs/ocamllabs-www

gha_language: CSS

repo_name: ocamllabs/ocamllabs-www


text:
# @jspsych/plugin-initialize-camera

## 1.0.1

### Patch Changes

- [#2781](https://github.com/jspsych/jsPsych/pull/2781) [`12956b3c`](https://github.com/jspsych/jsPsych/commit/12956b3cc130676a81e4a4536d68800a4d34e8a8) Thanks [@jadeddelta](https://github.com/jadeddelta)! - added readme for visibility on npmjs.com

## 1.0.0

### Major Changes

- [#2649](https://github.com/jspsych/jsPsych/pull/2649) [`133d85f4`](https://github.com/jspsych/jsPsych/commit/133d85f498f9bacbfb40b9abd8f135f99fbe947c) Thanks [@jodeleeuw](https://github.com/jodeleeuw)! - A new plugin to get permission to access the user's camera and allow the user to select which camera to use

repository: nadavWeisler/jsPsych

branch_name: refs/heads/main

repo_name: nadavWeisler/jsPsych


text:
# kopt - Hyper-parameter optimization for Keras

[![Build Status](https://travis-ci.org/Avsecz/kopt.svg?branch=master)](https://travis-ci.org/avsecz/kopt)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)](https://github.com/avsecz/kopt/blob/master/LICENSE)

kopt is a hyper-parameter optimization library for Keras. It is based on [hyperopt](https://github.com/hyperopt/hyperopt).

## Installation

```bash
# Install hyperopt from the master branch
pip install git+https://github.com/hyperopt/hyperopt.git

# Install kopt
pip install kopt
```

Alternatively, kopt can be installed using [Conda](https://conda.io/docs/) (most easily obtained via the [Miniconda Python distribution](https://conda.io/miniconda.html)):

```bash
conda install -c bioconda kopt
```

### Installation issues

- Reported by [gokceneraslan](https://github.com/gokceneraslan/) - 2018-03-11
  - > hyperopt on pypi doesn't work with latest networkx 2, there are [several issues](https://github.com/hyperopt/hyperopt/issues/333). Maybe it would have been better to wait for the [upcoming hyperopt release](https://github.com/hyperopt/hyperopt/milestone/3) and then pin required hyperopt to new version.
    - possible solution to networkx 2 issue: `pip install networkx==1.11` before installing hyperopt

## Getting started

Here is an example of hyper-parameter optimization for the Keras IMDB
example model.

```python
from keras.datasets import imdb
from keras.preprocessing import sequence
from keras.models import Sequential
import keras.layers as kl
from keras.optimizers import Adam
# kopt and hyoperot imports
from kopt import CompileFN, KMongoTrials, test_fn
from hyperopt import fmin, tpe, hp, STATUS_OK, Trials

# 1. define the data function returning training, (validation, test) data
def data(max_features=5000, maxlen=80):
    (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
    x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
    x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
    return (x_train[:100], y_train[:100], max_features), (x_test, y_test)

# 2. Define the model function returning a compiled Keras model
def model(train_data, lr=0.001,
          embedding_dims=128, rnn_units=64,
          dropout=0.2):
	# extract data dimensions
    max_features = train_data[2]

    model = Sequential()
    model.add(kl.Embedding(max_features, embedding_dims))
    model.add(kl.LSTM(rnn_units, dropout=dropout, recurrent_dropout=dropout))
    model.add(kl.Dense(1, activation='sigmoid'))

    model.compile(loss='binary_crossentropy',
                  optimizer=Adam(lr=lr),
                  metrics=['accuracy'])
    return model

# Specify the optimization metrics
db_name="imdb"
exp_name="myexp1"
objective = CompileFN(db_name, exp_name,
                      data_fn=data,
                      model_fn=model,
                      loss_metric="acc", # which metric to optimize for
                      loss_metric_mode="max",  # try to maximize the metric
                      valid_split=.2, # use 20% of the training data for the validation set
                      save_model='best', # checkpoint the best model
                      save_results=True, # save the results as .json (in addition to mongoDB)
                      save_dir="./saved_models/")  # place to store the models

# define the hyper-parameter ranges
# see https://github.com/hyperopt/hyperopt/wiki/FMin for more info
hyper_params = {
	"data": {
	    "max_features": 100,
		"maxlen": 80,
	},
	"model": {
     	"lr": hp.loguniform("m_lr", np.log(1e-4), np.log(1e-2)), # 0.0001 - 0.01
	    "embedding_dims": hp.choice("m_emb", (64, 128)),
	    "rnn_units": 64,
		"dropout": hp.uniform("m_do", 0, 0.5),
	},
	"fit": {
	    "epochs": 20
	}
}

# test model training, on a small subset for one epoch
test_fn(objective, hyper_params)

# run hyper-parameter optimization sequentially (without any database)
trials = Trials()
best = fmin(objective, hyper_params, trials=trials, algo=tpe.suggest, max_evals=2)

# run hyper-parameter optimization in parallel (saving the results to MonogoDB)
# Follow the hyperopt guide:
# https://github.com/hyperopt/hyperopt/wiki/Parallelizing-Evaluations-During-Search-via-MongoDB
# KMongoTrials extends hyperopt.MongoTrials with convenience methods
trials = KMongoTrials(db_name, exp_name,
                      ip="localhost",
	              port=22334)
best = fmin(objective, hyper_params, trials=trials, algo=tpe.suggest, max_evals=2)
```

## See also

- [nbs/imdb_example.ipynb](nbs/imdb_example.ipynb)

The documentation of `concise.hyopt` (`kopt` was ported from `concise.hyopt`):

- [Tutorial](https://i12g-gagneurweb.in.tum.de/public/docs/concise/tutorials/hyper-parameter_optimization/)
- [API documentation](https://i12g-gagneurweb.in.tum.de/public/docs/concise/hyopt/)
- [Jupyter notebook](https://github.com/gagneurlab/concise/blob/master/nbs/hyper-parameter_optimization.ipynb)

repository: Avsecz/kopt

repo_name: Avsecz/kopt


text:
## Principles
- Dependencies may only go down or sideways, never up (e.g. from Layer 2 to Layer 3)
- Componentization / Design for upgradability: Strive for self-contained components so that they can be upgraded independently of each other. For example:
  - RHEL-OSP with default SDN can be replaced whith RHEL-OSP with 3rd party SDN without affecting any other component
  - A subset of the demo with smaller footprint can be extracted easily, e.g. just OpenStack (running on bare metal) + CloudForms + OpenShift
- Immutable Infrastructure: No manual configuration, EVERYTHING needs to be scripted.
  - "Scripts" in this context means code that is checked into a repository,
  be it puppet classes, ansible playbooks, shell scripts or similar
  - Events to create scripts for:
    - Creation
    - Deletion
    - Startup
    - Shutdown
    - Data Export (e.g. satellite subscription data, openstack base images, ....)
    - Data Import
    - Reset to known state (demo reset)
    - Validation (to ensure the demo will likely work at a known date in the future)
  - This will reduce the need for backup / restore: Instead of backup up/restoring a known good configuration, we can recreate it from scratch
- Test (Driven/Augmented) Development: For all use cases, tests should be added
to the repository so a correct behavior can be validated. This includes testing the scripts to set up / tear down components as well as testing demo use cases.
  - To be discussed:
    - Level/Rigor of testing
    - Test Automation / Continuous Build

repository: DanielFroehlich/hailstorm

gha_language: Ruby

repo_name: DanielFroehlich/hailstorm


text:
# Basic PHP PDFtk Tutorial

Learn how to fill a fillable PDF in PHP using PDFTK

## Getting Started

Watch this video

* [Video Tutorial on YouTube](https://www.youtube.com/watch?v=SJNCc2GwREA)

### Prerequisites

* [PDFtk Server](https://www.pdflabs.com/tools/pdftk-server/) - PDF manipulation software
* [Composer](https://getcomposer.org) - Composer
* [PHP PDFtk](https://github.com/mikehaertl/php-pdftk) - php-pdftk Library for PDFtk
* [Laragon](https://laragon.org/) - The best FREE local server software with heaps of features

## Deployment

You will need to install PDFtk Server on your web server for this to work

## Authors

* **Sean Freitas** [Mr Digital](https://www.youtube.com/channel/UCrGZCgKfpPANtEG0bHESUOA)

## License

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

## Acknowledgments

* Developers of PDFtk
* Mike Haertl who created the PHP library

repository: adminakumosolutions/PHP-PDFTK-Tutorial

repo_name: adminakumosolutions/PHP-PDFTK-Tutorial