text:
---
layout: post
title: "Explicit Strongly Typed Selective Proxies"
comments: true
date: 2008-01-30 09:00
categories:
- c sharp
---

Had the question the other day:

'How could I dynamically create a proxy around an object (interface based proxies are not a problem) and then selectively apply interceptors at a method by method level if necessary'.

Let's clear up a bit of terminology so that everyone is on the same page with regards to the problem at hand:

Proxy - An object that implements the same interface as a target object and intercepts methods calls to the target to perform some sort of pre and or post method invocation.

Interceptor - An object that can be plugged into a proxy to perform a pre/post method invocation step. Common example that most people are familiar with is a LoggingInterceptor.

Attacking the problem test first drove me down a fairly interesting path that I was pleased with for a first cut. I'll explain the details in a minute, but examples speak a lot louder than words. I created a couple of dummy interfaces and a simple object to demonstrate the proxying/interception capabilities. It should also be noted that I am making use of Castle DynamicProxy as I feel it is an much easier barrier of entry for people who want to take advantage of creating dynamic proxies vs dropping down to the wire and leveraging Reflection.Emit classes directly (though that is something that I strongly recommend playing with a couple of times, just so you have an understanding for it). Here are the interceptors that will be used in this example:
{% codeblock lang:csharp %}
public class SomeInterceptor : IInterceptor
{
  public void Intercept(IInvocation invocation)
  {
    Console.Out.WriteLine("Interception occured on method{0} with {1} ",invocation.Method.Name,this.GetType().Name);
    invocation.Proceed();
  }
}

public class SomeOtherInterceptor : IInterceptor
{
  public void Intercept(IInvocation invocation)
  {
    Console.Out.WriteLine("Interception occured on method {0} with {1} ",invocation.Method.Name,this.GetType().Name);
    invocation.Proceed();
  }
}

{% endcodeblock %}

As you can see. Both of these interceptors are ridiculously simple. They both implement the IInterceptor interface that comes from Castle.Core, the interface itself only has one method called Intercept which is the method that will get invoked by the proxy when a method call is intercepted. Both of these classes lived in a test fixture class file, so I was not concerned with the evident duplication. Here are the interface and implementation for the item that is going to be proxies:
{% codeblock lang:csharp %}
public interface IAnInterface
{
    void OneMethod();
    void SecondMethod();
    int FirstValueReturningMethod();
    int ValueReturningMethodWithAnArgument(int number);
}

public class SomeImplementation : IAnInterface
{
    public void OneMethod()
    {
        Console.Out.WriteLine("Real work is being done in OneMethod");
    }

    public void SecondMethod()
    {
        Console.Out.WriteLine("Real work is being done in SecondMethod");
    }

    public int FirstValueReturningMethod()
    {
        Console.Out.WriteLine("Real work is being done in FirstValueReturningMethod");
        return 1;
    }

    public int ValueReturningMethodWithAnArgument(int number)
    {
        Console.Out.WriteLine("Real work is being done in ValueReturningMethodWithAnArgument");
        return 1 + number;
    }
}
{% endcodeblock %}

Again, substitute this interface and implementation with any interface/implementation pair that you would want to create a proxy for in your own application. With all of those, I'll show you some usages of the final product before explaining the solution:

Scenario 1 : Intercept on all method invocations with a SomeInterceptor
{% codeblock lang:csharp %}
[Test]
public void Should_proxy_all_methods_with_some_interceptor()
{
    IAnInterface anImplementationOfTheInterfaceToProxy = new SomeImplementation();

    sut = new ProxyBuilder<IAnInterface>();
    sut.AddInterceptor<SomeInterceptor>();

    IAnInterface proxy = sut.CreateProxyFor(anImplementationOfTheInterfaceToProxy);
    proxy.OneMethod();
    proxy.SecondMethod();
}
{% endcodeblock %}

Which results in the following console output:
Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeInterceptor
Real work is being done in SecondMethod

Notice that the interceptor was leveraged on both method calls prior to the call on the underlying item being made.

Scenario 2 : Intercept on all method invocations with multiple interceptors
{% codeblock lang:csharp %}
[Test]
public void Should_proxy_all_methods_with_multiple_interceptors()
{
    IAnInterface anImplementationOfTheInterfaceToProxy = new SomeImplementation();

    sut = new ProxyBuilder<IAnInterface>();
    sut.AddInterceptor<SomeInterceptor>();
    sut.AddInterceptor<SomeOtherInterceptor>();

    IAnInterface proxy = sut.CreateProxyFor(anImplementationOfTheInterfaceToProxy);
    proxy.OneMethod();
    proxy.SecondMethod();

}
{% endcodeblock %}

Which produces the following console output:
Interception occured on method OneMethod with SomeInterceptor
Interception occured on method OneMethod with SomeOtherInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeInterceptor
Interception occured on method SecondMethod with SomeOtherInterceptor
Real work is being done in SecondMethod

In this scenario both of the individual interceptors were invoked on any method call to the proxied item. Ok, so that was easy, lets try the next one:

Scenario 3 : Intercept on specific method invocations with a Single interceptor:

{% codeblock lang:csharp %}
[Test]
public void Should_proxy_only_targeted_methods_with_a_single_interceptor()
{
    sut = new ProxyBuilder<IAnInterface>();
    anImplementation = new SomeImplementation();

    IInterceptorConstraint<IAnInterface> constraint = sut.AddInterceptor<SomeInterceptor>();
    constraint.InterceptOn.OneMethod();

    IAnInterface proxy = sut.CreateProxyFor(anImplementation);
    proxy.OneMethod();
    proxy.SecondMethod();
}
{% endcodeblock %}

Which produces the following output:
Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Real work is being done in SecondMethod

Notice in the test above the use of the constraint that is returned from the Add method. Notice the call to the constraint.InterceptOn.OneMethod(). That is actually setting a filter to only enable the interceptor when that method is invoked on the proxy. For those familiar with Natural Mocks syntax (Rhino Mocks / TypeMock) this should look similar. It also has the nice benefit of not requiring the use of strings to specify which methods to filter on. Which means that it is also refactoring friendly. Notice that even though 2 method calls are made on the proxy, the interceptor only kicks in for the method that the constraint was configured for!!

Scenario 4 : Intercept on specific method invocations with differing interceptors:
{% codeblock lang:csharp %}
[Test]
public void Should_proxy_only_targeted_methods_with_differing_interceptors()
{
  sut = new ProxyBuilder<IAnInterface>();
  anImplementation = new SomeImplementation();
  IInterceptorConstraint<IAnInterface> constraint1 = sut.AddInterceptor<SomeInterceptor>();
  constraint1.InterceptOn.OneMethod();
  IInterceptorConstraint<IAnInterface> constraint2 = sut.AddInterceptor<SomeOtherInterceptor>();
  constraint2.InterceptOn.SecondMethod();
  IAnInterface proxy = sut.CreateProxyFor(anImplementation);
  proxy.OneMethod();
  proxy.SecondMethod();
}
{% endcodeblock %}

Which results in the following console output:
Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeOtherInterceptor
Real work is being done in SecondMethod

Notice how in this example the interceptors are firing selectively for the methods that they were configured for.

Finally you can configure multiple method constraints at a time using the following syntax:
{% codeblock lang:csharp %}
constraint.InterceptOnMethods( constraint.InterceptOn.FirstValueReturningMethod(), constraint.InterceptOn.ValueReturningMethodWithAnArgument(0));
{% endcodeblock %}

Again, the syntax for this was heavily inspired by prolonged usage of Rhino Mocks. So let's inspect the players that come together to make this all work:

{% codeblock lang:csharp %}
public class ProxyBuilder<T> : IProxyBuilder<T>
{
  private IProxyFactory proxyFactory;
  private IInterceptorConstraintSet constraintSet;
  public ProxyBuilder():this(new ProxyFactory(),new InterceptorConstraintSet())
  {

  }
  public ProxyBuilder(IProxyFactory proxyFactory, IInterceptorConstraintSet constraintSet)
  {
    this.proxyFactory = proxyFactory;
    this.constraintSet = constraintSet;
  }
  public IInterceptorConstraint<T> AddInterceptor<Interceptor>() where Interceptor : IInterceptor,new()
  {
    constraintSet.AddConstraintFor<Interceptor,T>();
    return constraintSet.GetConstraintFor<Interceptor,T>();
  }
  public T CreateProxyFor<T>(T instance)
  {
    return proxyFactory.CreateProxyUsing<T>(instance, constraintSet);
  }

}
{% endcodeblock %}

This is entry point to the api used to create proxies and associate interceptors with them. Driving out the design in a test first manner really helped me push off responsibilities to the last possible moment. Which leaves the ProxyBuilder class fairly simple. It leverages both a ProxyFactory and an InterceptorContraintSet. The InterceptorConstraintSet is just a strongly typed collection of constraints with a little bit of smarts to it:
{% codeblock lang:csharp %}
public class InterceptorConstraintSet : IInterceptorConstraintSet
{
  private IDictionary<Type, object> constraints;
  private IInterceptorConstraintFactory constraintFactory;
  public InterceptorConstraintSet():this(new Dictionary<Type,object>(),new InterceptorConstraintFactory(new ProxyFactory()))
  {

  }
  public InterceptorConstraintSet(IDictionary<Type, object> constraints, IInterceptorConstraintFactory constraintFactory)
  {
    this.constraints = constraints;
    this.constraintFactory = constraintFactory;
  }
  public void AddConstraintFor<Interceptor, Target>() where Interceptor : IInterceptor, new()
  {
    if (constraints.ContainsKey(typeof(Interceptor))) return;
    constraints.Add(typeof (Interceptor), constraintFactory.CreateFor<Interceptor, Target>());
  }
  public IInterceptorConstraint<Target> GetConstraintFor<Interceptor, Target>() where Interceptor : IInterceptor, new()
  {
    return (IInterceptorConstraint<Target>) constraints[typeof (Interceptor)];
  }
  public IInterceptor[] AllInterceptors<Target>()
  {
    return SetOfAllInterceptorsFor<Target>().AsList().ToArray();
  }
  private IEnumerable<IInterceptor> SetOfAllInterceptorsFor<Target>()
  {
    foreach (IInterceptorConstraint<Target> constraint in constraints.Values)
    {
      yield return constraint.BuildInterceptor();
    }
  }
}
{% endcodeblock %}

The SetOfAllInterceptorsFor<Target> method is interesting as this is where the work to create the interceptors for a proxy is delegated to the constraint. The InterceptorConstraint and its accompanying collaborators is what allows for the natural syntax:

{% codeblock lang:csharp %}
public class InterceptorConstraint<Target,Interceptor> : IInterceptorConstraint<Target> where Interceptor : IInterceptor,new()
{
    private readonly IMethodCallTracker<Target> callTracker;

    public InterceptorConstraint(IMethodCallTracker<Target> callTracker)
    {
        this.callTracker = callTracker;
    }

    public Target InterceptOn
    {
        get { return callTracker.Target; }
    }

    public void InterceptOnMethods(params object[] makeMethodCallsUsingInterceptOnProperty)
    {

    }

    public void InterceptOnMethods(params Action[] makeMethodCallsToInterceptOnPropertyInsideOfActionDelegate)
    {
        foreach (Action action in makeMethodCallsToInterceptOnPropertyInsideOfActionDelegate)
        {
            action();
        }
    }

    public IInterceptor BuildInterceptor()
    {
        if (callTracker.CallsWereMade) return new SelectiveInterceptor(new Interceptor(), callTracker.AllMethods());

        return new Interceptor();
    }
}
{% endcodeblock %}

The work of doing the interceptor filtering is done in the BuildInterceptor method. The InterceptorConstraint makes use of a MethodCallTracker which keeps track of whether calls were made to filter on selective methods. If the client is requesting a filtered interceptor the InterceptorConstraint returns an instance of a SelectiveInterceptor. SelectiveInterceptor is a proxy for an Interceptor (I know that is a mouthful!!):
{% codeblock lang:csharp %}
public class SelectiveInterceptor : IInterceptor
{
  private IInterceptor interceptor;
  private IDictionary<string,string> methodsToInterceptOn;
  public SelectiveInterceptor(IInterceptor interceptor, IDictionary<string, string> methodsToInterceptOn)
  {
    this.interceptor = interceptor;
    this.methodsToInterceptOn = methodsToInterceptOn;
  }
  public void Intercept(IInvocation invocation)
  {
    if (methodsToInterceptOn.ContainsKey(invocation.Method.Name))
    {
      interceptor.Intercept(invocation);
      return;
    }
    invocation.Proceed();
  }
}

{% endcodeblock %}

Selective interceptor decides whether or not to forward the call onto the associated interceptor, if the method is not in the dictionary of methods to intercept on, it bypasses the interceptor and directly forwards the call onto the item to proxy.

Notice the user of : {% codeblock lang:csharp %}new Interceptor(); {% endcodeblock %}

This creates a new instance of whatever the interceptor type was that was specified by the AddInterceptor<Interceptor> method call back on the ProxyBuilder. This works because of the generic constraint that ensured that the IInterceptor implementation also had a public no-arg constructor.

Last but not least, you are probably curious as to how the natural syntax is enabled? Take a look at the MethodCallFactory class:

{% codeblock lang:csharp %}
public class MethodCallTrackerFactory : IMethodCallTrackerFactory
{
    private ProxyGenerator proxyGenerator;

    public MethodCallTrackerFactory(ProxyGenerator proxyGenerator)
    {
        this.proxyGenerator = proxyGenerator;
    }

    public IMethodCallTracker<T> CreateFor<T>()
    {
        MethodCallTracker<T> methodCallTracker = new MethodCallTracker<T>();
        T target = proxyGenerator.CreateInterfaceProxyWithoutTarget<T>(methodCallTracker);
        methodCallTracker.Target = target;
        return methodCallTracker;
    }
}
{% endcodeblock %}

The ProxyGenerator class is supplied by Castle.DynamicProxy. I am using it to create a proxy around an interface without an actual underlying target:
{% codeblock lang:csharp %}
T target = proxyGenerator.CreateInterfaceProxyWithoutTarget<T>(methodCallTracker);
{% endcodeblock %}

Notice how after the MethodCallTracker is instantiated, it is passed in as an argument to the CreateInterfaceProxyWithoutTarget method? This method takes either a single or variable array of IInterceptor implementations. That’s right. The MethodCallTracker is itself as IInterceptor implementation. It intercepts calls on its Target property so that it can store the calls to be used in the Interception filtering process:

{% codeblock lang:csharp %}
public class MethodCallTracker<T> : IMethodCallTracker<T>
{
  public T Target{get;set;}

  private IDictionary<string, string> methodNames;

  public MethodCallTracker() : this(new Dictionary<string, string>())
  {
  }

  public MethodCallTracker(IDictionary<string, string> methodNames)
  {
    this.methodNames = methodNames;
  }

  public void Intercept(IInvocation invocation)
  {
    SetReturnValueFor(invocation);

    if (methodNames.ContainsKey(invocation.Method.Name)) return;

    methodNames.Add(invocation.Method.Name, invocation.Method.Name);
  }

  private void SetReturnValueFor(IInvocation invocation)
  {
    Type returnType = invocation.Method.ReturnType;

    if (returnType == typeof(void)) return;

    invocation.ReturnValue = (returnType.IsValueType ? Activator.CreateInstance(returnType) : null);
  }

  public bool CallsWereMade
  {
    get { return methodNames.Count > 0; }
  }

  public IDictionary<string, string> AllMethods()
  {
    return methodNames.Copy();
  }
}
{% endcodeblock %}

And finally, the glue that ties it all together. ProxyFactory, this class actually creates proxies instances leveraging the Castle ProxyGenerator as well as the completed InterceptorConstraintSet:

{% codeblock lang:csharp %}
public class ProxyFactory : IProxyFactory
{
    private ProxyGenerator proxyGenerator;
    private IMethodCallTrackerFactory methodCallTrackerFactory;

    public ProxyFactory():this(new ProxyGenerator(),new MethodCallTrackerFactory(new ProxyGenerator()))
    {
    }

    public ProxyFactory(ProxyGenerator proxyGenerator, IMethodCallTrackerFactory methodCallTrackerFactory)
    {
        this.proxyGenerator = proxyGenerator;
        this.methodCallTrackerFactory = methodCallTrackerFactory;
    }

    public IMethodCallTracker<T> CreateMethodCallTracker<T>()
    {
        return methodCallTrackerFactory.CreateFor<T>();
    }

    public T CreateProxyUsing<T>(T instance, IInterceptorConstraintSet constraints)
    {
        return proxyGenerator.CreateInterfaceProxyWithTarget<T>(instance, constraints.AllInterceptors<T>());
    }
}
{% endcodeblock %}

People ask me why I love TDD? It's because you can start with a blank slate, drive out the components one at a time in isolation from another, isolating/deferring responsibilities as you go, and finally you can plug all of the pieces together. In all of the code samples above I added in the poor mans dependency injection so that people could see the concretes being injected into the dependent. In the actual source code, an IOC container is being used. As when driving out the solution the interfaces were used to defer responsiblity to another object that did not exist yet. Taking this code, it would not be hard to add the pre/post/both filter also so that you could choose when specifically to apply an interceptor!! And of course I could eliminate the method call tracker altogether if I made use of lambda expressions and parsed the expression tree to see what method was called. I'll leave that for another day!!

Develop With Passion!!


text:
# Release process

## Prior to release: 1 week out

* Ensure the version specified in `docs/conf.py` and `VERSION` align with the intended release version.
* Check all dependency version ranges.
  * Ensure all dependencies are not capped by major version, unless the reason is documented inline.
    * Example of major version cap: `scikit-learn<2`
  * Ensure all dependencies have an upper cap, unless the reason is documented inline.
    * Example of no upper cap: `scikit-learn>=1.0`
  * Ensure no dependency is pinned to an exact version unless the reason is documented inline.
    * Example: `scikit-learn==1.1.3`. This is very fragile and overly strict.
  * Ensure all dependencies are capped by minor version and not micro version unless the reason is documented inline.
    * Minor version capping would be `<x.y`. Micro version capping would be `<x.y.z`.
    * Avoid capping to `<x.y.0`, instead do the cleaner identical cap: `<x.y`.
  * Ensure all dependencies are lower bound capped to a reasonable version.
    * Example: `scikit-learn<1.2` is not reasonable because it is almost certain that `scikit-learn==0.0.1` is not supported.
      * A better range: `scikit-learn>=1.0,<1.2`
  * Ensure dependencies shared across multiple AutoGluon modules have the same version range in each module, unless the reason is documented inline.
    * If the same version range is used in multiple modules, ensure the version range is defined only once by defining it in `core/_setup_utils.py`
  * Ensure all upper caps are using `<` and not `<=`.
  * Ensure all dependencies whose ranges are obtained via `core/_setup_utils.py` have the following inline comment:
    * """# version range defined in `core/_setup_utils.py`"""
* Try upgrading all dependency version range upper caps to include the latest stable release.
  * Note: For micro releases such as AutoGluon 0.6.2, this is optional.
  * If increasing the range causes an error, either:
    1. Fix the error.
    2. Avoid the range change and add an inline comment in setup.py that an error occurred and why we didn't fix.
  * If increasing the range causes a warning, either:
    1. Fix the warning.
    2. Suppress the warning for the user + provide justification and appropriate TODOs.
    3. Avoid the range change and add an inline comment in setup.py that a warning occurred and why we didn't fix.
  * Ensure CI passes, potentially benchmark to catch performance regressions / more complex bugs.
  * Note: To truly catch potential errors, you will need to use the latest supported Python version, since some packages may only support the newer Python version in their latest releases.
* Make final call for which in-progress PRs are release critical.
* Communicate with in-progress PR owners that code freeze is in effect, no PRs will be merged that are not release critical.
* Wait 1 day after code-freeze for pre-release to be published.
* Ensure latest pre-release is working via `pip install --pre autogluon` and testing to get an idea of how the actual release will function (Ideally with fresh venv). DO NOT RELEASE if the pre-release does not work.
* Ensure pip install instructions are working correctly for both CPU and GPU.
  * Ensure explicit torch installs have the correct version range and are not overwritten during `pip install autogluon`.
* Ensure each sub-module is working IN ISOLATION via `pip install --pre autogluon.{submodule}`.
  * Ensure a fresh venv is used for each submodule.
  * Doing this will avoid issues like in v0.4 release with `autogluon.text` crashing when installed standalone due to missing setup.py dependencies
    * https://github.com/autogluon/autogluon/issues/1607
* If minor fixes are needed, create PRs and merge them as necessary if they are low risk. Ensure fixes are tested manually.
* If major fixes are needed, consider the severity and if they are release critical. If they are, consider delaying release to ensure the issue is fixed (and tested).

## Prior to release: 1 day out

* Ensure that the mainline code you are planning to release is stable: Benchmark, ensure CI passes, check with team, etc.
* Cut a release branch with format `0.x.y` (no v) - this branch is required to publish docs to versioned path
  * Clone from master branch
  * Add 1 commit to the release branch to remove pre-release warnings and update install instructions to remove `--pre`: [Old diff](https://github.com/autogluon/autogluon/commit/1d66194d4685b06e884bbf15dcb97580cbfb9261)
  * Add 1 commit that converts notebook links from `master` to `stable` by running this command from the root project directory: `LC_ALL=C find docs/tutorials/ -type f -exec sed -i '' 's#blob/master/docs#blob/stable/docs#' {} +`
  * Update links to AG sub-modules website to be stable ones, i.e. cloud
  * Push release branch
  * Build the release branch docs in [CI](https://ci.gluon.ai/job/autogluon/).
  * Once CI passes, verify it's available at `https://auto.gluon.ai/0.x.y/index.html`
* Prepare the release notes located in `docs/whats_new/v0.x.y.md`:
  * This will be copy-pasted into GitHub when you release.
  * Include all merged PRs into the notes and mention all PR authors / contributors (refer to past releases for examples).
  * Prioritize major features before minor features when ordering, otherwise order by merge date.
  * Review with at least 2 core maintainers to ensure release notes are correct.

## Release

* Update the `stable` documentation to the new release:
  * Delete the `stable` branch.
  * Create new `stable` branch from `0.x.y` branch (They should be identical).
  * Add and push any change in `docs/README.md` (i.e. space) to ensure `stable` branch is different from `0.x.y`.
    * This is required for GH Action to execute CI continuous integration step if `0.x.y` and `stable` hashes are matching.
  * Wait for CI build of the `stable` branch to pass
  * Check that website has updated to align with the release docs.
* Perform version release by going to https://github.com/autogluon/autogluon/releases and click 'Draft a new release' in top right.
  * Tag release with format `v0.x.y`
  * Name the release identically to the tag (ex: `v0.x.y`)
  * Select `master` branch as a target
    * Note: we generally use master unless there are certain commits there we don't want to add to the release
  * DO NOT use the 'Save draft' option during the creation of the release. This breaks GitHub pipelines.
  * Copy-paste the content of `docs/whats_new/v0.x.y.md` into the release notes box.
    * Ensure release notes look correct and make any final formatting fixes.
  * Click 'Publish release' and the release will go live.
* Wait ~10 minutes and then locally test that the PyPi package is available and working with the latest release version, ask team members to also independently verify.

## Conda-Forge Release

After GitHub & PyPi release, conduct release on Conda-Forge
* [TODO] Add Conda-Forge release steps.

## Release Cheatsheet

* If intending to create a new cheatsheet for the release, refer to [autogluon-doc-utils README.md](https://github.com/Innixma/autogluon-doc-utils) for instructions on creating a new cheatsheet.
* If a cheatsheet exists for `0.x.y` (or `0.x`), update the `docs/cheatsheet.md` url paths ([example](https://github.com/autogluon/autogluon/blob/0.4.1/docs/cheatsheet.rst)) in branch `0.x.y` to the correct location ([example for v0.4.0 and v0.4.1](https://github.com/Innixma/autogluon-doc-utils/tree/main/docs/cheatsheets/v0.4.0)).
  * Example urls: [JPEG](https://raw.githubusercontent.com/Innixma/autogluon-doc-utils/main/docs/cheatsheets/v0.4.0/autogluon-cheat-sheet.jpeg), [PDF](https://nbviewer.org/github/Innixma/autogluon-doc-utils/blob/main/docs/cheatsheets/v0.4.0/autogluon-cheat-sheet.pdf)
  * Do NOT do this for `stable` branch or `master` branch, instead have them continue pointing to the [stable cheatsheet files](https://github.com/Innixma/autogluon-doc-utils/tree/main/docs/cheatsheets/stable). This is to ensure that as we release new versions of the cheatsheet, old docs will still refer to the correct cheatsheet for their version.
  * Finally, update the stable files [here](https://github.com/Innixma/autogluon-doc-utils/tree/main/docs/cheatsheets/stable) to reflect the latest released version of the cheatsheet.

## Post Release

* IF THERE IS A MAJOR ISSUE: Do an emergency hot-fix and a new release ASAP. Releases cannot be deleted, so a new release will have to be done.

After release is published, on the mainline branch:
* Update `release` in `docs/conf.py`
* Increment version in the `VERSION` file
* Update doc links in `docs/versions.rst`
* Update `README.md` sample code with new release version.
* Send release update to internal and external slack channels and mailing lists
* Publish any blogs / talks planned for release to generate interest.

## Post Release Conda-Forge Patching

Conda-Forge releases are mutable and can be changed post-release to fix breaking bugs without releasing a new version.

* [TODO] Add Conda-Forge post-release patching guidelines.

repository: stjordanis/autogluon

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: stjordanis/autogluon


text:
# Full editor example

Heavily inspired by Atlassian's editor https://atlaskit.atlassian.com/packages/editor/editor-core

In conjunction with using React for NodeViews, also through sharing the same EditorContext the components have access to same global providers eg StyledComponents, translation and so on.

Which saves a lot of trouble when sharing a lot of state without wanting to write a lot of boilerplate eg mapStateToProps to every component. Or at least that is what I think it does. Not sure yet.

## Commands

Can be found in `package.json`. Use `yarn <cmd>` or `npm run <cmd>` or sometimes `npm <cmd>` works too.


text:
## Headings

Headings from `h1` through `h6` are constructed with a `#` for each level:

```markdown
# h1 Heading
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
```

## Horizontal Rules

The HTML `<hr>` element is for creating a "thematic break" between paragraph-level elements. In markdown, you can create a `<hr>` with any of the following:

* `___`: three consecutive underscores
* `---`: three consecutive dashes
* `***`: three consecutive asterisks

## Emphasis

### Bold
For emphasizing a snippet of text with a heavier font-weight.

```markdown
**rendered as bold text**
```
### Italics
For emphasizing a snippet of text with italics.

```markdown
_rendered as italicized text_
```

### Strike through

```markdown
~~Strike through this text.~~
```

## Blockquotes
For quoting blocks of content from another source within your document.

Add `>` before any text you want to quote.

```markdown
Add `>` before any text you want to quote.
```

Blockquotes can also be nested:

```markdown
> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue.
Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi.
>> Sed adipiscing elit vitae augue consectetur a gravida nunc vehicula. Donec auctor
odio non est accumsan facilisis. Aliquam id turpis in dolor tincidunt mollis ac eu diam.
>>> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue.
Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi.
```

## Lists

### Unordered
A list of items in which the order of the items does not explicitly matter.

You may use any of the following symbols to denote bullets for each list item:

### Unordered

```markdown
* Lorem ipsum dolor sit amet
* Consectetur adipiscing elit
* Integer molestie lorem at massa
* Facilisis in pretium nisl aliquet
* Nulla volutpat aliquam velit
  - Phasellus iaculis neque
  - Purus sodales ultricies
  - Vestibulum laoreet porttitor sem
  - Ac tristique libero volutpat at

+ Faucibus porta lacus fringilla vel
+ Aenean sit amet erat nunc
+ Eget porttitor lorem
```

### Ordered

```markdown
1. Start with a number
1. Consectetur adipiscing elit
1. Integer molestie lorem at massa
1. Facilisis in pretium nisl aliquet
1. Nulla volutpat aliquam velit
1. Faucibus porta lacus fringilla vel
1. Aenean sit amet erat nunc
2. Eget porttitor lorem
```

## oEmbed
oEmbed is a format which allows embedding a representation of an URL of a third-party site.

```markdown
[embed https://www.flickr.com/photos/leesjewel/17177375049]
```

## Code

### Inline code

```
Look at this ```Inline code here...``` :)
```

### Indented code

Or indent several lines of code by at least four spaces, as in:

```
    // Some comments
    line 1 of code
    line 2 of code
    line 3 of code
```

### Block code "fences"

Use "fences"  ```` ``` ```` to block in multiple lines of code.

    ```
    Sample text here...
    ```

### Syntax highlighting
Add the file extension of the language you want to use directly after the first code "fence" and syntax highlighting will automatically be applied in the rendered HTML. For example, to apply syntax highlighting to JavaScript code:

    ```js
    grunt.initConfig({
      assemble: {
        options: {
          assets: 'docs/assets',
          data: 'src/data/*.{json,yml}',
          helpers: 'src/custom-helpers.js',
          partials: ['src/partials/**/*.{hbs,md}']
        },
        pages: {
          options: {
            layout: 'default.hbs'
          },
          files: {
            './': ['src/templates/pages/index.hbs']
          }
        }
      }
    };
    ```

## HTML blocks
HTML blocks (e.g. div, table, pre, p) must be separated from surrounding content by blank lines and the start and end of the block should not be indented with tabs or spaces

```markdown
**Bold** text

<div>

**Bold** text

</div>

**Bold** text
```

## Tables
Tables are created by adding pipes as dividers between each cell, and by adding a line of dashes (also separated by bars) beneath the header. Note that the pipes do not need to be vertically aligned.

```markdown
| Option | Description |
| ------ | ----------- |
| data   | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext    | extension to be used for dest files. |
```

### Aligned text

Adding a colon on the right side of the dashes below any heading will right align text for that column.

```markdown
| Option | Type    | Description |
| :------| :-----: | -----------:|
| data   | text    | path to data files to supply the data that will be passed into templates. |
| engine | text    | engine to be used for processing templates. Handlebars is the default. |
| ext    |  text   | extension to be used for dest files. |
```

## Links and Images

### Basic link

```markdown
[MODX](http://modx.com)
```

### With a title

```markdown
[MODX](http://modx.com "MODX")
```

### Images
Images have a similar syntax to links but include a preceding exclamation point.

```markdown
![Minion](http://octodex.github.com/images/minion.png)
```

```markdown
![Alt text](http://octodex.github.com/images/homercat.png "The Homercat")
```

### Footnote style

```markdown
![Alt text][image]
[MODX][link]

[image]: http://octodex.github.com/images/dojocat.jpg  "The Dojocat"
[link]: http://modx.com "MODX"
```

license: MIT

repository: theboxer/markdown-editor

gha_language: JavaScript

gha_license_id: MIT

repo_name: theboxer/markdown-editor


text:
# Software for High Energy Astrophysics

## Where to find the software:

**HEASOFT**: http://heasarc.gsfc.nasa.gov/docs/software/lheasoft/

  - Versatile multi-mission tools, includes *Xspec*, *Xronos*, etc.
  - Mission-specific reduction tools (for Suzaku, RXTE, etc.)
  - Official Instructions to Download : http://heasarc.gsfc.nasa.gov/docs/software/lheasoft/download.html
  - Official Instructions to Install: http://heasarc.gsfc.nasa.gov/docs/software/lheasoft/install.html
  - Mission-specific calibraton files: http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/caldb_intro.html
  - **Astutos guide to install: [HEASOFT guide](../install_HEASOFT)**

**XMM SAS**: http://xmm.esac.esa.int/sas/current/download/
  - Tools to reduce XMM-Newton data
  - Instructions to Download: http://xmm.esac.esa.int/sas/current/download/
  - Instructions to Install: http://xmm.esac.esa.int/sas/current/installation/
  - Software requirements: http://xmm.esac.esa.int/sas/current/requirements/
  - *Calibration* files and Instructions: http://xmm2.esac.esa.int/external/xmm_sw_cal/calib/ccf.shtml

**CIAO** (and *CALDB*): http://cxc.harvard.edu/ciao/
  - Software to reduce Chandra data and Calibration database
  - Tools to fit, plot and edit non-mission specific data
  - Instructions to Download: http://cxc.harvard.edu/ciao/download/
  - Instructions to Install: http://cxc.harvard.edu/ciao/threads/ciao_install_tool/

repository: evandromr/astutos

repo_name: evandromr/astutos


text:
## turbosDefaulttheme

## Author: © Turboblack 2018 www.torba.tk

## Description
Based on thr default template, added some changes, logo, background, button up, add js animation.
You can add by inserting links into any page on your site, just add the below to your theme.php
```
<center>
<a href="#" class="fa fa-facebook"></a>
<a href="#" class="fa fa-twitter"></a>
<a href="#" class="fa fa-youtube"></a>
<a href="#" class="fa fa-instagram"></a>
<a href="#" class="fa fa-vk"></a>
<a href="#" class="fa fa-skype"></a>
</center>
```

## Preview
![Theme preview](/preview.jpg)

## How to use
1. Login to your WonderCMS website.
2. Click "Settings" and click "Themes".
3. Find theme in the list and click "install".
4. In the "General" tab, select theme to activate it.

repository: robiso/turbosDefault

repo_name: robiso/turbosDefault


text:
### [CVE-2021-34590](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-34590)
![](https://img.shields.io/static/v1?label=Product&message=CC612&color=blue)
![](https://img.shields.io/static/v1?label=Product&message=CC613&color=blue)
![](https://img.shields.io/static/v1?label=Product&message=ICC15xx&color=blue)
![](https://img.shields.io/static/v1?label=Product&message=ICC16xx&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=5.11.x%3C%205.11.2%20&color=brighgreen)
![](https://img.shields.io/static/v1?label=Vulnerability&message=CWE-79%20Cross-site%20Scripting%20(XSS)&color=brighgreen)

### Description

In Bender/ebee Charge Controllers in multiple versions are prone to Cross-site Scripting. An authenticated attacker could write HTML Code into configuration values. These values are not properly escaped when displayed.

### POC

#### Reference
- https://cert.vde.com/en/advisories/VDE-2021-047

#### Github
No PoCs found on GitHub currently.

repository: trickest/cve

branch_name: refs/heads/main

gha_language: HTML

repo_name: trickest/cve


text:
Android Client for Indicative's REST API

This REST client creates a JSON representation of your event and posts it to Indicative's Event endpoint.

Features:

+ No external dependencies, so you'll never have library conflicts.
+ Asynchronous, designed to never slow down or break your app.
+ Fault tolerent: if network connectivity is lost, events are queued and retried.

Sample usage:

    // Our Android library is available on Maven Central as an AAR artifact.
    // If your project uses Gradle, you can integrate by adding the following dependency:

    repositories {
        mavenCentral()
    }

    dependencies {
        compile 'com.indicative.client.android:Indicative-Android:1.10.0'
    }

    // In the onCreate() method of your Application class, call the launch()
    // method, passing in the application context and your project's API key.
    // You can find yours by logging in at indicative.com and navigating to
    // the Project Settings page.
    @Override
	public void onCreate() {
	    Indicative.launch(getApplicationContext(), "Your-API-Key-Goes-Here");
	}

    // Then start tracking events with the recordEvent() method
    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("Age", 23);
    properties.put("Gender", "Female");
    Indicative.recordEvent("Registration", "user47", properties);

We've added common properties and cached unique identifiers!

A common property is a property that gets recorded for all events. Common properties are stored in SharedPreferences and appended to each event's properties when the event is recorded.

You can also set a unique identifier to be recorded for all events. This value will be stored in SharedPreferences as well, and will be set for all events that don't otherwise have a unique identifier specified.  If you haven't set a unique identifier, Indicative will generate a UUID during initialization and and treat that UUID as the default unique identifier for all events. To set a different unique identifier for a specific event, simply call the `recordEvent()` method and pass in a different `uniqueId` value.

Our API -- all are static methods:

         Method Name
         Method Description

         launch(Context context, String apiKey)
         Initializes the static Indicative instance with the project's API Key, using the application context.  This method will generate and store a UUID unique identifier if one isn't already stored.

         recordEvent(String eventName, String uniqueId, Map<String, Object> properties)
         Queues an event to be processed with the given event name, uniqueness identifier, and properties (common properties will be appended to this event). NOTE: the objects stored as property values should be String, numeric, or boolean objects.

         recordEvent(String eventName)
         Queues an event to be processed with the given event name, uniqueness identifier stored previously by initialization or explicitly set by setUniqueID(), and any common properties previously stored.

         recordEvent(String eventName, String uniqueId)
         Queues an event to be processed with the given event name, uniqueness identifier, and any common properties previously stored.

         recordEvent(String eventName,  Map<String, Object> properties)
         Queues an event to be processed with the given event name, uniqueness identifier generated by the app or cached previously, and properties (common properties will be appended to this event). NOTE: the objects stored as property values should be String, numeric, or boolean objects.

         setUniqueID(String uniqueID)
         Stores (in SharedPreferences) a unique identifier to be used for all `recordEvent()` calls that don't provide a `uniqueId`.

         clearUniqueID()
         Clears the unique identifier stored using `setUniqueID()`. All events, if not provided a unique identifier, will default to the UUID generated on first initialization.

         addProperty(String name, String value)
         Stores a common property in SharedPreferences with the given name and value.

         addProperty(String name, int value)
         Stores a common property in SharedPreferences with the given name and value.

         addProperty(String name, boolean value)
         Stores a common property in SharedPreferences with the given name and value.

         addProperties(Map<String, Object> properties)
         Stores all common properties in SharedPreferences with the given name and value.  NOTE: we only accept type String, boolean, and int within this Map.

         removeProperty(String name)
         Removes a single common property from storage with given name (key).

         clearProperties()
         Removes all common properties from storage.

         reset()
         Removes all state from the Indicative SDK and regenerates the anonymous ID. This should be called in your application on logout.

You should modify and extend this class to your heart's content.  If you make any changes please send a pull request!

As a best practice, consider adding a method that takes as a parameter the object representing your user, and adds certain default properties based on that user's characteristics (e.g., gender, age, etc.).

For more details, see our documentation at: http://app.indicative.com/docs/integration.html

repository: Indicative/Indicative-Android

gha_language: Java

repo_name: Indicative/Indicative-Android


text:
---
title: Linking between pages
---

This guide covers how to link between pages in a Gatsby site.

## The Gatsby link component

The Gatsby `<Link />` component is for linking between pages within your site. For external links to pages not handled by your Gatsby site, use the regular HTML `<a>` tag.

## Using the `<Link />` component

Here's an example of creating a link between two pages in a Gatsby site.

Open a page component (e.g. `src/pages/index.js`) in your Gatsby site. Import the `<Link />` component from Gatsby. Add a `<Link />` component below the header, and give it a `to` property, with the value of `"/contact/"` for the pathname:

```jsx
import React from "react"
import { Link } from "gatsby"

export default () => (
  <div>
    <Link to="/page-2/">Page 2</Link>
  </div>
)
```

## Other resources

-  For the complete example of how to link between pages, see [Part One](/tutorial/part-one/#linking-between-pages/) in the Tutorial
- Check out more detail on routing in Gatsby in the [API doc for Gatsby Link](/docs/gatsby-link/).


text:
---
name: ❓ Questions/Help
about: If you have questions, please check our Slack channel.
labels: 'questions, needs triage'
---

## ❓ Questions and Help

### Please note that this issue tracker is not a help form and this issue will be closed.

Please contact us instead. We have a few channels:

- [![Slack](https://img.shields.io/badge/slack-opctl-E01563.svg)](https://join.slack.com/t/opctl/shared_invite/zt-51zodvjn-Ul_UXfkhqYLWZPQTvNPp5w)

repository: apexskier/opctl

gha_language: Go

repo_name: apexskier/opctl


text:
# Cloud Conversation Engine iOS Samples

Apps here demonstrate how to make API calls to the Cloud Cloud Conversation API
using audio recorded from an iOS device's microphone. Check out the app's README
for full getting started instructions.

## Contents

### [Stopwatch](stopwatch)

repository: IntelliMindTeam/ios-docs-samples

repo_name: IntelliMindTeam/ios-docs-samples


text:
# gfc-crypto [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.gfccollective/gfc-crypto_2.12/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/org.gfccollective/gfc-crypto_2.12) [![Build Status](https://github.com/gfc-collective/gfc-crypto/workflows/Scala%20CI/badge.svg)](https://github.com/gfc-collective/gfc-crypto/actions) [![Coverage Status](https://coveralls.io/repos/gfc-collective/gfc-crypto/badge.svg?branch=main&service=github)](https://coveralls.io/github/gfc-collective/gfc-crypto?branch=main)

A library that contains cryptography related scala utility classes.
A fork and new home of the now unmaintained Gilt Foundation Classes (`com.gilt.gfc`), now called the [GFC Collective](https://github.com/gfc-collective), maintained by some of the original authors.

## Getting gfc-crypto

The latest version is 1.0.0, released on 21/Jan/2020 and cross-built against Scala 2.12.x and 2.13.x.

If you're using SBT, add the following line to your build file:

```scala
libraryDependencies += "org.gfccollective" %% "gfc-crypto" % "1.0.0"
```

For Maven and other build tools, you can visit [search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Corg.gfccollective).
(This search will also list other available libraries from the GFC Collective.)

## Contents and Example Usage

### org.gfccollective.crypto.HashFunctions

Helper library to create cryptographic hashes (SHA-256, SHA-512, of input Strings. For a complete list of supported
message digest (hash) formats see the documentation for java.security.MessageDigest.

## License

Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0

repository: gfc-collective/gfc-crypto

gha_language: Scala

repo_name: gfc-collective/gfc-crypto


text:
# snippets
Various code snippets I use

They are stored using my gist. this page only make references to them

# Bash

* [Find files having one line](https://gist.github.com/ftorto/117825954bd5d0a49c32b5fbd8b6fbd1)
* [Limit parallel tasks](https://gist.github.com/ftorto/f090cf69f0cf21f5fb48adbfb812c816)
* [only in A / common](https://gist.github.com/ftorto/9e268900f1fbd62448e8fd9c9015c97f)
* [Bash variable replace pattern](https://gist.github.com/ftorto/fe0438009112777d56371308eebf6620)
* [Sum the numbers (1 per line)](https://gist.github.com/ftorto/b0c3188bdda646f53bff604eb14f6191)
* [Top10 biggest files from current location](https://gist.github.com/ftorto/257c5e22faaf4badbdcdafc41725f767)
* [Git recursive](https://gist.github.com/ftorto/641ced2c03950d715b7b259dbec4ffa3)
* [Draw horizontal line](https://gist.github.com/ftorto/0fb755d8007a31ebfb014b2528c0ea23)

# Raspberry pi

* [Know current temperature](https://gist.github.com/ftorto/d44f032fec2185543d3dfbdc2f159e0c)

# Docker

* [Clean docker](https://gist.github.com/ftorto/66b0ea5b11691d3553dc003dab1004de)

# Python

* [Singleton](https://gist.github.com/ftorto/806fb2ffb60a8fd3e77a44068f7ea325)
* [Spark tips](https://gist.github.com/ftorto/a21b72f25a2f7da38a041f6b1a598e24)
* [Namespace in different location](https://gist.github.com/ftorto/e565f33565f7843d2a82d44bb603a184)
* [Split list into chunks](https://gist.github.com/ftorto/026c3d91fc66a571b923a8a9cf3d6df4)

repository: ftorto/snippets

repo_name: ftorto/snippets


text:
# quickbase-textmate

A command line tool that automates the creation of a TextMate grammar for Quickbase formulae. The primary goal is to make it easier to maintain IDE extentions like the one at https://github.com/jdklub/vscode-quickbase-formula for VS Code.

## Installation

With a [correctly configured](https://golang.org/doc/install#install) Go toolchain, clone the repository to a directory of your choosing, change into it, and run `make`:

```
git clone https://github.com/cpliakas/quickbase-textmate.git
cd ./quickbase-textmate
make
```

## Usage

The `data/Formula_Functions_Reference.csv` file is the CSV file downloaded from the [Quickbase Formula Functions Reference](https://login.quickbase.com/db/6ewwzuuj?a=td) documentation.

To build the [snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets) file:

```
./quickbase-textmate snippets --file data/Formula_Functions_Reference.csv
```

To build the list of functions for the `support.function.quickbase` pattern:

```
./quickbase-textmate functions --file data/Formula_Functions_Reference.csv
```

To build the list of operators for the `keyword.operator.quickbase` pattern:

```
./quickbase-textmate operators --file data/Formula_Functions_Reference.csv
```

repository: cpliakas/quickbase-textmate

repo_name: cpliakas/quickbase-textmate


text:
# Pycalc
A very basic calculator implemented in `Python` using `Tkinter`.

## Index

- [To Play](https://github.com/diego-asterisk/pycalc#to-play)
- [Features](https://github.com/diego-asterisk/pycalc#features)
- [Usage](https://github.com/diego-asterisk/pycalc#features)
- [Contributing](https://github.com/diego-asterisk/pycalc#contributing)
- [Issues](https://github.com/diego-asterisk/pycalc#issues)
- [License](https://github.com/diego-asterisk/pycalc#license)

## To Play

Just run `python3 pycalc.py`

## Features :

#### Version1.0

* Cross-platform
* Easy to use
* Supports common mathematical functions like

| `+`   | `-`  | `*`  | `/`  |  `%` |

* Supports `Random` and `AC`

## Usage:

![Usage](http://misosguar.com.ar/games/calc.gif)

## Contributing

[[Back to top]](https://github.com/diego-asterisk/pycalc#index)

Feel free to contribute.

For details, please refer [the Contributing page](https://github.com/diego-asterisk/pycalc/blob/master/CONTRIBUTING.rst)

## Issues

[[Back to top]](https://github.com/diego-asterisk/pycalc#index)

You can report the bugs at the [issue tracker](https://github.com/diego-asterisk/pycalc/issues)

## License

[[Back to top]](https://github.com/diego-asterisk/pycalc#index)

Built with ♥ by [Diego Mañas](https://github.com/diego-asterisk) under [MIT License](https://xn--diegomaas-r6a.mit-license.org/)

You can find a copy of the License at http://diegomañas.mit-license.org/

repository: diego-asterisk/pycalc

repo_name: diego-asterisk/pycalc


text:
# 🧩 match-with

Pattern matching object structures. Semi-related to [tc39/proposal-pattern-matching](https://github.com/tc39/proposal-pattern-matching).

## Installation

```bash
yarn add match-with
```

## Usage

Basic syntax:

```ts
import { match } from "match-with";

match(subject: any)
  .with(pattern1: any, callback1: (subject, pattern1) => result: any)
  .with(pattern2: any, callback2: (subject, pattern2) => result: any)
  .default(callback3: (subject) => result: any)
  .result;
```

Examples:

```ts
...
const subject = {
  one: 1,
  two: undefined,
  three: "3",
};

match(subject)
  .with({ one: 1, two: undefined }, () => {
    return "match";
  })
  .result; // "match";

match(subject)
  .with({ one: 2 }, () => {
    // Skipped.
  })
  .default(() => {
    return 1;
  });

match(subject)
  .with({ one: n => n < 2 }, () => {
    console.log(true);
  });

match(subject)
  .with({ four: match.EXISTS }, () => {
    // Skipped.
  })
  .with({ four: undefined }, () => {
    return 4;
  });
```

## Community

Let me know what you think. After you ★ this project, follow me [@Rygu](https://twitter.com/rygu) on Twitter.

## License

BSD 3-Clause license. Copyright © 2019, Rick Wong. All rights reserved.

repository: RickWong/match-with

repo_name: RickWong/match-with


text:
# install-linux

> Softwares to install on Linux just with one command

## Usage

Just run:

```sh
bash -c "$(wget -O - https://raw.githubusercontent.com/fdaciuk/install-linux/master/install.sh)"
```

## Softwares that will be installed:

- XSel
- SMB Client
- HTop
- OpenSSH Server
- S3 CMD
- ZSH
- Terminator
- Curl
- Vim
- KeePassX
- Git
- Atom
- Chrome
- Docker
- Dropbox
- Diffmerge
- Skype
- Strem.io
- Simple Screen Recorder
- NVM
  - Nodemon
- Apache 2
- MySQL
- PHP
- PHPMyAdmin
- WP-CLI
- Composer
- Redis Server

> Enjoy it ;)

## Useful commands

[**1. Relase idle memory:**](http://www.vivaolinux.com.br/dica/Liberando-memoria-RAM-ociosa)

```sh
sudo sysctl -w vm.drop_caches=3
```

**2. Clear swap:**

```sh
sudo swapoff -a
sudo swapon -a
```

## License

[MIT](https://github.com/fdaciuk/licenses/blob/master/MIT-LICENSE.md) © Fernando Daciuk


text:
---
title: Context
description: Stencil has a number of add-ons that you can use with the build process.
url: /docs/context
contributors:
  - jthoms1
---

# Context

### What is Context?

Context is a global object which can be used to store global variables, singleton objects etc. and bind them in your components as props. You can see it as a dependency injector for Stencil.

### How to Bind a Context Item

```tsx
@Component({
  tag: 'my-component'
});
export class MyComponent {
  @Prop({ context: 'myObj' }) private myObj: any;
}
```

### How to Define a Context Item

Context items are defined by directly binding to the global `Context` object. As a best practice you can use `src/global` to store the definitions.

First you need to define the item:

```tsx
// src/global/myObj.ts

export default (function() {
  const privateInstance = ...

  return {
    call: () => {
      privateInstance.method();
    }
  };
})();
```

Then create a global script that will be used to reference all the context items:

```tsx
// src/global/index.ts

import myObj from './myObj';

declare var Context: any;

Context.globalVar = '';
Context.myObj = myObj;
```

Finally just add the global script in config:

```tsx
export.config = {
  // ...
  globalScript: 'src/global/index.ts'
};
```

repository: dgautsch/stencil-site

repo_name: dgautsch/stencil-site


text:
# Open Sound Control (OSC)

How to use the OSC protocol with LevelMagic(TM)

## The OSC protocol

The OSC protocol is a way of controlling devices via the network. Here we present a way of taking control of the
LevelMagic(TM) plug-in using this protocol.

## Using the Bonjour protocol, Zero Conf
If your control device uses bonjour or Zero conf protocol configuration will be quick and simple. Just select Flux::OSC
in the ZeroConf device of your controller. Then, write the output port and IP address of your device in the labels of
the plug-in. Remember that in the output port label of the plug-in you should write the input port of your controller
and in the output address of the plug-in you should write the IP address of your device.

## Configuring OSC parameters manually.
The following parameters are used to configure OSC manually in LevelMagic(TM)

- Network configuration: OSC is a network based protocol so make sure that both your controller and the host
    are connected to the same network.
- OSC Enable: When turned on this parameter creates a thread for receiving and sending OSC messages. This
    thread is multi-instances. This means that this will control all the instances of the plug-in. For example, if you
    have four LevelMagic(TM) opened, all the communication and control via OSC will be done via this one configured thread. You just have to be sure that the following parameters are well configured.
- Input Port: This is the port where the plug-in will be receiving OSC messages (the output of your control
    surface)
- Output Port: This is the port where the plug-in will send feedback to (the input of your control surface).
- Output IP Address: This is the address of destination of the outgoing OSC packets of the plug-in. You should
    write here the IP address of your controller

The image below presents the different OSC parameters used for configuration.

![](include/level_magic_10.png)

## Feedback from the plug-in to the controller

The Flux:: OSC manager will send feedback to your controller. These are the different situations when you will
receive feedback:

- When a parameter begins to be edited
In this situation, the plug-in will send the following OSC messages:
    - Address Pattern: /NumberOfInstance/ControlBeginEdit
    - Argument: Name of the parameter.
    - Type: String

- When the edition of a parameter ends
    - Address Pattern: /NumberOfInstance/ControlEndEdit
    - Argument: Name Of the parameter
    - Type: String

- When a value is changed
When a parameter is changed in the plug-in by any mean (OSC, mouse, automation or other... ) Flux :: Osc will
send a message with the new value of the parameter and the instance number of the plug-in it belongs to.
    - Address Pattern: /NumberOfInstance/ParameterName
    - Argument: Float from 0 to 1, represents the value of the parameter.
    - Type: Float

- When creating a new instance
When a new instance of a plug-in is created Flux:: OSC will send the following message:
    - Address Pattern: /NewInstanceRegisteredWithNumber
    - Argument: The number assigned to the new instance created.
    - Type: Float

- When an instance of a plug-in is destroyed
    - Address Pattern: /InstanceUnregisteredWithNumber
    - Argument: Represents the index of the instance that was destroyed.
    - Type: Float,

## Using multiple controllers and advanced configurations
Flux :: OSC gives you the possibility to use multiple controllers for one instance of a plug-in and have a particular
feedback for each one. If you want to use multiple controllers refer to the use of the /TalkToMeOnPort Command
found under “Commands”.

## Commands

### How to use the commands
At first you have to know what an OSC message is composed of. Mainly, these two parts: The Address Pattern and
the Argument.

For controlling parameters Flux:: only supports arguments of float type so make sure that the arguments you are
sending via your controller are Floats. Float arguments must always be from 0 to 1 for controlling a parameter so
you don’t have to deal with scale conversion.

### The LevelMagic(TM) OSC commands
When OSC is enabled in the Plug-in Settings (2) the file “OSC_Dict.xml” is automatically created in:
/Documents/Flux/LevelMagic

This is a properties dictionary with each parameter that can be controlled and mapped using OSC. The commands
in the dictionary includes a ”Translation” attribute that can be used in order translate the OSC name into the Flux::
internal parameter name in both directions.

### Global Commands
Global commands allow you to access to some additional information. These commands don’t need an instance
number. These are the available additional commands:
- Address Pattern:/GetDeviceInfo
- Type: Float
- Value: 1
- Explanation: Get all the names of the controllable parameters

- Address Pattern: /TalkToMeOnPort
- Type: Float
- Value: Port Number
- Explanation: This command is very strong. It will store the IP address and the port in argument as an endpoint. All
the different messages will be sent to this endpoint. This command is very useful for using many controllers.

- Address Pattern: /GetCurrentValues
- Type: Float
- Value: 1
- Explanation: This command will send all the current values of the different instances of a plug-in. The structure of
the sent OSC messages is the same as the one for controlling them.

- Address Pattern: /GetNumberOfInstances
- Type: Float
- Value: 1
- Explanation: This command returns the opened number of instances of a plug-in. If you have five LevelMagic(TM)
opened this command will return 5.


text:
---
layout: article
title:  Week 4
tags: internship kernel-drivers
date:   2021-10-30 08:00:00 +0100
show_edit_on_github: false
show_subscribe: false
license: false
key: 2021-10-30-week-4
categories: active
---

Unfortunately, this week my steady assault on the EDR drivers came to a grinding halt when I had to take a couple days off.
<!--more-->

### 1. Error 404 - Intern not found

The past few weeks I spent a lot of time getting acquainted with the windows kernel and the inner workings of an EDR/AV product. I also covered the two main methods of attacking the EDR/AV drivers, namely **kernel callback patching** and **IRP MajorFunction hooking**. I've been working on my own driver called *Interceptor*, which will implement both these techniques as well as a method to load itself into kernel memory bypassing [Driver Signing Enforcement (DSE)](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/driver-signing).

I'm of the opinion that when writing tools or exploits, the author should know exactly what each part of his/her code is responsible for, how it works and avoid copy pasting code from similar projects without fully understanding it. With that said, I'm writing *Interceptor* based on numerous other projects, so I'm taking my time to go through their associated blogposts and understand their working and purpose.

Interceptor currently supports IRP hooking/unhooking drivers by name or by index based on loaded modules.

![Interceptor functionality](/assets/images/interceptor-functionality.png)

Using the `-l` option, Interceptor will list all the currently loaded modules on the system and assign them an index. This index can be used to hook the module with the `-h` option.

![Interceptor loaded modules](/assets/images/interceptor-loaded-modules.png)

Using the `-lh` option, Interceptor will list all the currently hooked modules with their corresponding index in the global *hooked drivers* array. Interceptor currently supports hooking up to 64 drivers. The index can be used with the `-u` option to unhook the module.

![Interceptor list hooked drivers](/assets/images/interceptor-list-hooked-drivers.png)

Once a module is hooked, Interceptor's `InterceptGenericDispatch()` function will be called whenever an IRP is received. The current function notifies a call was intercepted via a debug message and then call the original completion routine. I'm currently working on a method to inspect and modify the IRPs before passing them to their completion routine.

```c++
NTSTATUS InterceptGenericDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
	UNREFERENCED_PARAMETER(DeviceObject);
    auto stack = IoGetCurrentIrpStackLocation(Irp);
	auto status = STATUS_UNSUCCESSFUL;
	KdPrint((DRIVER_PREFIX "GenericDispatch: call intercepted\n"));

    //inspect IRP
    if(isTargetIrp(Irp)) {
        //modify IRP
        status = ModifyIrp(Irp);
        //call original
        for (int i = 0; i < MaxIntercept; i++) {
            if (globals.Drivers[i].DriverObject == DeviceObject->DriverObject) {
                auto CompletionRoutine = globals.Drivers[i].MajorFunction[stack->MajorFunction];
                return CompletionRoutine(DeviceObject, Irp);
            }
        }
    }
    else if (isDiscardIrp(Irp)) {
        //call own completion routine
        status = STATUS_INVALID_DEVICE_REQUEST;
	    return CompleteRequest(Irp, status, 0);
    }
    else {
        //call original
        for (int i = 0; i < MaxIntercept; i++) {
            if (globals.Drivers[i].DriverObject == DeviceObject->DriverObject) {
                auto CompletionRoutine = globals.Drivers[i].MajorFunction[stack->MajorFunction];
                return CompletionRoutine(DeviceObject, Irp);
            }
        }
    }
    return CompleteRequest(Irp, status, 0);
}
```

I'm also working on a module that supports patching kernel callbacks. The difficulty here is locating the different callback arrays by enumerating their calling functions and looking for certain opcode patterns, which change between different versions of Windows.

As mentioned in one of my previous blogposts, locating the callback arrays for `PsSetCreateprocessNotifyRoutine()` and `PsSetCreateThreadNotifyRoutine()` is done by looking for a `CALL` instruction to `PspSetCreateProcessNotifyRoutine()` and `PspSetCreateThreadNotifyRoutine()` respectively, followed by looking for a `LEA` instruction.

Finding the callback array for `PsSetLoadImageNotifyRoutine()` is slightly different as the function first jumps to `PsSetLoadImageNotifyRoutineEx()`. Next, we skip looking for the `CALL` instruction and go straight for the `LEA` instruction instead, which puts the callback array address into `RCX`.

![LoadImage callback array](/assets/images/load-image-callback-array.png)

Interceptor's callback module currently implements patching functionality for Process and Thread callbacks.

![Callback patching functionality](/assets/images/interceptor-callback-patching-functionality.png)

The registered callbacks on the system and their patch status can be listed using the `-lc` command.

![Callback listing](/assets/images/interceptor-list-callbacks.png)

### 2. Conclusion

In the previous blogpost of this series, we combined the functionality of two drivers, Evil and Interceptor, to partially bypass ESET Internet Security. In this post we took a closer look at Interceptor’s capabilities and future features that are in development. In the upcoming blogposts we’ll see how Interceptor as a fully standalone driver is able to conquer not just ESET Internet Security, but other EDR products as well.

(Un)fortunately, I received my first COVID-19 vaccination shot in the middle of the week, which has knocked me out quite good, so I had to take a couple days off.


text:
---
title: Find Peak Element
date: "2020-04-11"
type: problem-solving
description: Find Peak Element
tags: csharp
---

Note: This problem was taken from LeetCode - [Find Peak Element](https://leetcode.com/problems/find-peak-element/)

### Brute Force Approach

```csharp
public int FindPeakElement(int[] nums) {
	int n = nums.Length;
	if(n == 0){
		return 0;
	}
	else if(n == 1){
		return 0;
	}

	// Check if the first element is the peak element
	if(nums[0] > nums[1]){
		return 0;
	}

	// Check if the last element is the peak element
	if(nums[n-1] > nums[n-2]){
		return n - 1;
	}

	// Iteratively check all the elements in the array if it is a peak element.
	for(int i = 1; i < n-1; i++){
		if(nums[i] > nums[i-1] && nums[i] > nums[i+1]){
			return i;
		}
	}

	return 0;
}
```

### Binary Search Approach

The Binary search algorithm is used mostly with the problems where the input array is sorted, but in this case, we know that the input array is not in a sorted format. But it works because, at a certain part of the array where peak element lies, that part will be in a sorted format. We use this property along with Binary search to find the peak element.

Consider the following example with the input array:
```
[5,6,4,3,2,9,3]
```
In the above example, the peak elements are 6 and 9.

Let's apply binary search on the array:

```
left: 0
right: 6
mid: 3
```
Check if `mid[3] < mid[4]`. In this scenario, yes it is. So this implies that there has to be a peak element in the right half of the array. Why is that?.
Consider the element mid[4], it's left element is lesser than it. And the right element can be either of the two:

- Higher than mid[4] - Then we repeat the same process, that is the right of mid[5] should have at least one peak element.
- Lower than mid[4]. If mid[5] is lower than mid[4] then mid[4] is the peak element.

Repeat this process by dividing the array into half on each traversal, and this will get you the required solution.

```csharp
public int FindPeakElement(int[] nums) {
	int left = 0;
	int right = nums.Length - 1;

	while(left < right){
		int mid = (left + right)/2;

		if(nums[mid] < nums[mid+1]){
			left = mid + 1;
		}
		else{
			right = mid;
		}
	}
	return left;
}
```

| Approach | Time Complexity | Space Complexity |
| ------------- |:-------------:| :-----:|
| Brute Force | O(n) | O(1) |
| Binary Search | O(log n) | O(1) |

repository: melwinalm/my-gatsby-blog

repo_name: melwinalm/my-gatsby-blog


text:
# SnakeProgressView
A youtube style android progress view for playing the classic snake game.

##Demo

![](https://github.com/vishnus1224/SnakeProgressView/blob/master/Project/demo/demo.gif)

#Usage

Add the following line to the build.gradle file in order to use the library:
```
compile 'com.vishnus1224.snakeprogressview:library:1.0'
```

Set the view's visibility to `INVISIBLE` to hide the view whenever a long running task is complete. Similarly make it `VISIBLE` to allow the user to interact with it, while data is being fetched in the background.

Currently, the snake color and the item color are customizable and can be done either via xml or through code.

For doing it in xml:
Create an identifier for the namespace to use custom attributes in xml. I have named it snake.
```
xmlns:snake="http://schemas.android.com/apk/res-auto"
```

The namespace has following custom attributes:
```
 <declare-styleable name="SnakeProgressView">
    <attr name="snakeColor" format="color|reference"></attr> //specifies the color of the snake.
    <attr name="itemColor" format="color|reference"></attr> // specifies the color of the item.
 </declare-styleable>
```

***Usage Tips***
-For using this view in a layout, define it as the last child as it will be drawn on top of other views.
-The view has a transparent background color. Hence the content below will be visible.
-Preferably set the view width and height to match_parent so that the entire screen is available as the playing area.

#Sample
Following is the xml layout from the sample project:
```
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:snake="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"  tools:context=".MainActivity">

    <Button
        android:text="Button"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_alignParentBottom="true"
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.vishnus1224.snakeprogressview.SnakeProgressView
        android:id="@+id/snakeProgressView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>
```

***Java code example***
For adding and customizing the view in code, follow the same steps used for creating any other view through code.
e.g.
```
SnakeProgressView snakeProgressView = new SnakeProgressView(context);
snakeProgressView.setSnakeColor(specify the desired color);
snakeProgressView.setItemColor(specify the desired color);

rootLayout.addView(snakeProgressView);
```

#ENJOY


text:
#  <img src="skill_icon" alt="My First Trivia Skill icon" width="36"> [My First Trivia Skill](http://alexa.amazon.com/#skills/amzn1.ask.skill.9e4c2481-f05e-4386-a256-a54dd971d188)
![0 stars](../../images/ic_star_border_black_18dp_1x.png)![0 stars](../../images/ic_star_border_black_18dp_1x.png)![0 stars](../../images/ic_star_border_black_18dp_1x.png)![0 stars](../../images/ic_star_border_black_18dp_1x.png)![0 stars](../../images/ic_star_border_black_18dp_1x.png) 0

To use the My First Trivia Skill skill, try saying...

* *Alexa, launch Seinfeld Guru*

* *Repeat*

* *Help*

Seinfeld Guru is a fun trivia skill that gives users ability to test their knowledge about the TV show. Players can see what they really remember about Jerry, George, Elaine, Kramer, and the rest of the gang by answering multiple choice questions. Great for parties or solo play.

***

### Skill Details

* **Invocation Name:** seinfeld guru
* **Category:** null
* **ID:** amzn1.ask.skill.9e4c2481-f05e-4386-a256-a54dd971d188
* **ASIN:** B01K12LFKK
* **Author:** Greg Lieber
* **Release Date:** August 9, 2016 @ 02:37:34
* **In-App Purchasing:** No


text:
GlobeCopter LED

## TODOs
- Add a Kalman filter.
- convert arduino sketch in enc directory to ESP32-idf format.

## Abstract
This code is a program for the GlobeCopter LED ring that runs on the ESP32 board.
One core is used to send the SPI signals to the LED when a signal is received.
The other core has a Kalman filter and controls the motor with PWM. When the ring comes to
a specific angle, it will send a signal to the other core.

## How to build

### Create a cross compile environment

### Build the project
Run the following command at the root directory of this repository.
```
make
```

## Configure the ESP32
It's almost ok with the default settings, but you have to enable dual core mode to have this
operate properly.
To configure the ESP32, execute the following command.
```
make menuconfig
```

## Flash the built binary to the ESP32
Run the following command at the same directory where you built the project.
```
make flash
```

## Run the code at the ESP32
After flashing to the ESP32, it will automatically restart, and the project will be executed automatically.

## Debbuging
There are logging features defined by macros in ESP32. In order to view the logging console, run the following command.
```
make monitor
```

## Troubleshooting
### Flashing fails.
The device boot mode is not set properly. I'll recomend you to use the ESP32 dev kit, and the flashing tool will do the reset for you.


text:
Little command-line utility to put to Azure Blob Storage.

It will be deprectated after this functionality gets implemented in the [azure-cli](https://github.com/WindowsAzure/azure-sdk-tools-xplat).

![ss-2013-07-04T11-56-59.png](http://blog.auth0.com.s3.amazonaws.com/ss-2013-07-04T11-56-59.png)

## Installation

	npm install -g put-blob

## Usage

	put-blob -a <account name> -k "<account key>" -c <container> <file>

Copy a blob on the same container as follows

	put-blob -a <account name> -k "<account key>" -c <container> -f <source blob name> <target blob name>

By default it uploads chunks of 4Mb, use `-z 2` to change to an arbitrary size.

## License

MIT - 2013 - Jose F. Romaniello

repository: jfromaniello/put-blob

repo_name: jfromaniello/put-blob


text:
---
title: "Fair Trade/Organic Coffee, Rural Livelihoods, and the “Agrarian Question”: Southern Mexican Coffee Families in Transition"
date: 2011-01-01
publishDate: 2020-05-04T22:04:17.640217Z
authors: ["Bradford L. Barham", "Mercedez Callenes", "Seth Gitter", "Jessa Lewis", "Jeremy Weber"]
publication_types: ["2"]
abstract: "Summary We use a random sample of coffee producing households in southern Mexico to compare opportunities associated with government subsidies and migration to the role of Fair Trade/organic coffee in household livelihoods. Although land and labor returns among Fair Trade/organic coffee growers are higher than for conventional growers, differences in yields are more important than price premiums. Moreover, investment in education and labor opportunities outside coffee dominate those in Fair Trade/organic coffee. The results highlight the value of an integrated approach to the agrarian question that improves productivity and prices and supports other pathways for improving incomes."
featured: false
publication: "*World Development*"
tags: ["Latin America", "Mexico", "Fair Trade", "organic", "migration", "education"]
url_pdf: "http://www.sciencedirect.com/science/article/pii/S0305750X10001427"
doi: "https://doi.org/10.1016/j.worlddev.2010.08.005"
---

repository: MercedezCM/WebSource

repo_name: MercedezCM/WebSource


text:
Functional Component Description Template
=======================

## Specific scope of the component

## What does the component do? (envisioned feature set)

## What does the component __not__ do? (excluded features to avoid misperception / confusion)

## Lead of development team

## Link to component specs repo

repository: DINA-Web/dina-model-concepts

repo_name: DINA-Web/dina-model-concepts


text:
---
title: "Palladium"
date: 2019-08-25T21:39:56+05:30
draft: false
LatinName: "Palladium"
atomicnumber: "46"
AtomicWeight: "106.42"
NumberOfElectrons: "46"
NumberOfProtons: "46"
NumberOfNeutrons: "60"
classification: "Transition-Metal"
stateAtRoomTemp: Solid
DiscoveredBy: "William Hyde Wollaston"
DiscoveredIn: 1803
imgurl: "paladium.jpeg"
Link: "https://en.wikipedia.org/wiki/Palladium"
about: "Palladium is a chemical element with the symbol Pd and atomic number 46. It is a rare and lustrous silvery-white metal discovered in 1803 by William Hyde Wollaston. He named it after the asteroid Pallas, which was itself named after the epithet of the Greek goddess Athena, acquired by her when she slew Pallas. Palladium, platinum, rhodium, ruthenium, iridium and osmium form a group of elements referred to as the platinum group metals (PGMs). These have similar chemical properties, but palladium has the lowest melting point and is the least dense of them."

---

repository: ChivukulaVirinchi/periodic-table

repo_name: ChivukulaVirinchi/periodic-table


text:
# DELANI-STUDIO

## Author
SHARON KIMANI

## Description
Delani-Studio project implements Bootstrap and jQuery to recreate a landing page for a fictional studio.

## Technologies Used
* HTML
* CSS
* BOOTSTRAP
* J.Query
* JavaScript

## Known Bugs
No known bugs detected.

## Setup Instructions and Installation
* Clone this repository to a location in your file system.

* git clone https://shazzkimani.github.io/Delani-Studio/

## Live link
* https://shazzkimani.github.io/Delani-Studio/

## Behaviour Driven Development

Displays Form For Entering name, email and message
INPUT: "Name Entered"
INPUT: "Email Entered"
INPUT: "Message Entered"
OUTPUT: "Displays an alert message referring to the name inputted that we have received their message"

## Development
Want to contribute? Great!

To fix a bug or enhance an existing module, follow these steps:

* Fork the repo
* Create a new branch (git checkout -b improve-feature)
* Make the appropriate changes in the files
* Add changes to reflect the changes made
* Commit your changes (git commit -am 'Improve feature')
* Push to the branch (git push origin improve-feature)
* Create a Pull Request

## Contact

Incase of anything, please reach out via<EMAIL_ADDRESS>
## License

The MIT License (MIT)

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.

 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.

Copyright (c) 2020 Sharon Kimani

repository: ShazzKimani/Delani-Studio

repo_name: ShazzKimani/Delani-Studio


text:
# mongo_deep
 Python tool used to make a deep and precise analysis of a Mongo database

# usage:

mongo_reader.py [-h] [-d DB] [-c COLLECTIONS] [-s] [-p] [-v] [-i IO]

optional arguments:
- -h, --help            show this help message and exit
- -d DB, --db DB        Database to explore.
- -c COLLECTIONS, --collections COLLECTIONS
                        Precise collections to explore
- -s, --stats           Display statistics of collection(s).
- -p, --path            Display every different path present in collection,
                        only the first occurence is displayed.
- -v, --value           Display value of each path present in collection,
                        every values are displayed. This can take a long time.
- -i IO, --io IO        Put result into a file.


text:
# Analysis Services

This module deploys Analysis Services.

## Resources

The following Resources are deployed.

+ **Microsoft.AnalysisServices/servers**
+ **Microsoft.AnalysisServices/servers/providers/diagnosticsettings**

## Parameters

| Parameter Name | Default Value | Required | Description |
| :-             | :-            | :-       |:-           |
| `serverName` || **Required** | The name of the Azure Analysis Services server to create
| `location` || **Optional** | Location for all Resources
| `skuName` | S0 | **Optional** | The sku name of the Azure Analysis Services server to create
| `skuCapacity` | 1 | **Optional** | The total number of query replica scale-out instances
| `firewallSettings` | AllowFromAll | **Optional** | The inbound firewall rules to define on the server. If not specified, firewall is disabled
| `diagnosticStorageAccountId` || **Required** | Resource identifier of the Diagnostic Storage Account
| `logAnalyticsWorkspaceId` || **Required** | Resource identifier of Log Analytics Workspace
| `logsRetentionInDays` | 30 |**Optional** | Specifies the number of days that logs will be kept for, a value of 0 will retain data indefinitely
| `cuaId` || **Optional** | Customer Usage Attribution Id (GUID). This GUID must be previously registered
| `tagValues` || **Optional** | Optional. Azure Resource Tags object

## Outputs

| Output Name | Description |
| :-          | :-          |
| `analysisServicesName` |  Analysis Services Name output parameter
| `analysisServicesResourceId` | Analysis Services ResourceId output parameter
| `analysisServicesResourceGroup` | Analysis Services ResourceGroup output parameter

## Scripts

+ There is no deployment considerations for this Module.

## Considerations

+ There is no deployment considerations for this Module

## Additional resources

+ [Microsoft Analysis Services template reference](https://docs.microsoft.com/en-us/azure/templates/microsoft.analysisservices/allversions)
+ [Microsoft Analysis Services diagnostic settings reference](https://azure.microsoft.com/en-us/blog/azure-analysis-services-integration-with-azure-diagnostic-logs/)

repository: RKSelvi/vdc

gha_language: PowerShell

repo_name: RKSelvi/vdc


text:
## Xanathar's Guild

1. ~~When one of the PCs is separated from the group, they're mugged by a teenage boy with a crossbow and a Kenku shadowing him.~~
    1. ~~Brendaniel Skwik, a merchant's son looking to join the Guild~~
    1. ~~If the party attacks, the Kenku escapes.~~
    1. ~~The boy tells the group that this was his task to get inducted into the Xanathar's Guild.~~
    1. ~~Kicked out of his house for stealing, just wants a place to belong~~
1. ~~The players come across some Xanathar's Guild members mugging someone in an alley.~~
1. ~~Tally's shop is wrecked in the middle of the day because he refuses to pay the Guild's protection money.~~
1. A thug pushes past the party, trying to get all "Do you know who I am?" on them.
1. Thugs show up and try to extort protection money from the PCs.
    1. A duergar and bugbear
    1.

## Zhentarim

1. ~~The party is attacked by a guy high on "magic dust", which is the D&D version of PCP. It gives the effects of Heroism (immune to fear, 5 temp HP every turn). If the players track the source of these drugs down, they find the Zhentarim are responsible.~~
    1. ~~Ethel Carpenter, female human in her 40s, ex-city watch.~~
    1. ~~Wearing old city watch uniform, picking fights.~~
    1. ~~Has her old sword, but won't use it because she feels she could kill anyone with her bare hands.~~
1. ~~A warehouse nearby is raided and the players witness the City Watch hauling crates of goods out into wagons. This was a storehouse the Zhentarim were using to store their stolen goods before selling it.~~
1. ~~Embric is attacked in the middle of the night by Zhent assassins because he won't sell weapons exclusively through them.~~

## Both

1. The Zhentarim and Xanathar's Guild members pass in the street and start throwing insults at each other before breaking out into a brawl. They scatter if the City Watch is called.


text:
# Ranger

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

## Usage

**Ranger** provides two new operators for reverse ranging:

1. `..>` which works as the inverse of `..<`; `max..>min` is equivalent to `min+1...max`
2. `>>>` which works the same as `...` but allows for the lhs to be smaller than rhs -- `max>>>min` is equivalent to `(min...max).reversed()`

So you may be asking, "Why would I want to use this instead of calling `reversed()`?"

Good question! Calling `reversed()` or `reverse()` is much slower than using a stride, as I'm doing in this framework. And the stride function is unusually long, especially for these commonplace operations.

## Requirements
Swift 3

## Installation

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

```ruby
pod "Ranger"
```

## Author

Hesham Salman<EMAIL_ADDRESS>
## License

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

repository: Iron-Ham/Ranger

repo_name: Iron-Ham/Ranger


text:
# EzBlocker

EZBlocker is a simple-to-use ad blocker/muter for Spotify. EZBlocker will attempt to block ads on Spotify from loading. If an ad does load, EZBlocker will mute Spotify until the ad is over.

There are no fancy features, just pure ad blocking. When an ad is blocked, only Spotify is muted, so no other sounds will be affected. EZBlocker aims to be the most stable and reliable ad blocker for Spotify.


text:
# FRCC WebLab - Internet Plumbing

Internet "Plumbing"

* TCP/IP
* HTTP, SMTP, FTP
* Headers, response codes
* Lions, tigers, bears!

## Question: Why?

Why do I need to know this??? You don’t. At least not fully, or immediately. But, as you become a more advanced developer, creating more sophisticated web software, and in particular troubleshooting/debugging complex software and systems, an understanding of things at this level becomes really important.

## Wikipedia - TCP

[http://en.wikipedia.org/wiki/Transmission_Control_Protocol](http://en.wikipedia.org/wiki/Transmission_Control_Protocol)

## Wikipedia - SMTP

[http://en.wikipedia.org/wiki/Smtp](http://en.wikipedia.org/wiki/Smtp)

## Internet Protocol Suite

Internet Protocol Suite

[http://en.wikipedia.org/wiki/Internet_protocol_suite](http://en.wikipedia.org/wiki/Internet_protocol_suite)

## Next: Servers & Server-Side Concepts

[Servers & Server-Side Concepts](?md=/course-content/module1/servers_and_server-side_concepts.md)

repository: WebDevBootcamp/course-content

repo_name: WebDevBootcamp/course-content


text:
---
layout: post
title: "Learning Java: Garbage Collection in Java"
date: 2019-07-22 23:15:00 +0200
category: tutorial
tagline: ""
tags: [Java]
abstract : "Learning Note: how does garbage collection work in Java."
---
{% include JB/setup %}

* [Introduction](#introduction)
* [How a Garbage Collector Works](#how-a-garbage-collector-works)
    - [How to Identify Garbage](#how-to-identify-garbage)
        + [Reference Counting](#reference-counting)
        + [Reachability Analysis](#reachability-analysis)
    - [How to Collect Garbage](#how-to-collect-garbage)
        + [Stop and Copy](#stop-and-copy)
        + [Mark and Sweep](#mark-and-sweep)
        + [Mark and Compact](#mark-and-compact)
* [Garbage Collection in Java](#garbage-collection-in-java)
    - [Finalization and Termination Condition](#finalization-and-termination-condition)
    - [Java Memory Management and Garbage Collection](#java-memory-management-and-garbage-collection)
* [Summary](#summary)
* [References](#references)

# Introduction

Garbage Collection (GC) is a form of automatic memory management. Its aim is to reclaim garbage or memory occupied by objects that are no longer in use by the program.
Garbage collection was invented by John McCarthy around 1959 to simplify manual memory management in [Lisp](http://www-formal.stanford.edu/jmc/history/lisp/lisp.html){:target="_blank"}.
It has a longer history than Java.

# How a Garbage Collector Works

There are several garbage-collection schemes.

## How to Identify Garbage

First of all, we need to find out what should be considered as garbages and which storages should be released.

### Reference Counting

Reference Counting(引用计数算法) is a simple but slow scheme.

In this scheme, each object contains a reference counter.
Every time a reference is attached to that object, its reference counter is increased.
Every time a reference goes out or is set to null, its counter is decreased.
Once the reference counter of an object becomes zero, that storage will be released.

But one shortcoming is that if objects circularly refer to each other they can have nonzero reference counts.
Below is an example:
```java
public class ReferenceCountingGC {
    public Object instance;
    public static void main(String...strings) {
        ReferenceCountingGC a = new ReferenceCountingGC(); // 1st instance
        ReferenceCountingGC b = new ReferenceCountingGC(); // 2nd instance
        a.instance = b;
        b.instance = a;
        a = null;
        b = null;
    }
}
```

It creates two instances.
The first instance has two references, one is from a and the other is from b.instance. The second instance also has two references.
After two variables are set to null, the two instances still have one reference from their members.
In this case, their reference counter will never be zero.

Another drawback is that reference counting scheme requires extra space for each object to store its reference counter and extra process resource to deal with counter.

### Reachability Analysis

The basic idea of Reachability Analysis(可达性分析算法) is to trace which objects are reachable by a chain of references from "root" objects.
The "root" is called GC Roots and the path from root to the certain object is called reference chain.
If one object cannot be reachable from any GC Roots, it will be considered as garbage and the storage will be released.

As shown in the image below, the objects in blue rectangle should be kept alive and the objects in gray rectable can be recycled:
![GC Roots]({{ site.url }}/assets/images/java_gc/gc_roots.png){:height="300px" width="600px"}

In Java, there are 4 types of objects can be used as GC Roots:
1. objects referenced in VM Stack;
2. objects referenced by static members or methods in Method Area;
3. objects referenced by constants in Method Area;
4. objects referenced by JNI in Native Method Stack.

```java
public class ReachabilityAnalysisGC {
    public static ReachabilityAnalysisGC staticMember;
    public static final ReachabilityAnalysisGC finalMember = new ReachabilityAnalysisGC("FinalMember");
    public ReachabilityAnalysisGC(String name) {}
    public static void main(String...strings) {
        ReachabilityAnalysisGC ragc = new ReachabilityAnalysisGC("first");
        ragc.staticMember = new ReachabilityAnalysisGC("StaticMember");
        ragc = null;
    }
}
```

In the example above, instance `ragc` can be used as GC Root.
When it is set to null. The string "first" can be recycled.
But the static member `staticMember` and the final member `finalMember` will not be recycled.

## How to Collect Garbage

After garbage identification, the collector will collect the garbages and release the storage.
But another important factor is the efficiency.

### Stop and Copy

Stop-and-Copy algorithm divides memory into two equal sections(heaps).
Every time only one section will be used.
When the program stops and the collection stars, all live objects are copied from one heap to another, leaving behind all the garbages.
In addition, as the objects are copied into the new heap, they are packed end-to-end and compacting the new heap.

There are two issues for this algorithm.
The first one is that two heaps are needed. So that we have to maintain twice as much memory as we actually need and it is kind of waste.
The second one is the copying process itself. The program needs to spend some time and resources on running the copying process no matter how many garbages there are. Besides, all references that point at the object must be hcanged.

### Mark and Sweep

Mark-and-Sweep algorithm has 2 steps.
In the first step - mark, it traces through all the references to find live objects or dead objects, and marks them.
During the second step - sweep, the dead objects will be released and the storage can be used again.

One big problem of this algorithm is memory fragments.
Since the dead objects might be stored in different parts of memory, the memory will be split into several parts when they are released.
It will cause that the memory cannot be used even there are a lot of spaces.

### Mark and Compact

Mark-and-Compact algorithm is similar to Mark-and-Sweep algorithm.
After marking the live objects and the dead objects, it will move all the live objects to the end.
Then all the storage that can be collected and is not used will be in the other end together.

It solves the problem of memory fragments and memory waste.
But it is much slower than other two algorithms.

# Garbage Collection in Java

## Finalization and Termination Condition

Java has its own garbage collector that only knows how to release memory allocated with __new__.
And it also provides a method called __finalize()__ to release the object's special memory.

The basic process of this is like:
"When the garbage collector is ready to release the storage used for object, it will first call finalize(), and only on the next garbage-collection pass will it reclaim the object's memory."

Something must be remembered:
1.
2. "_Garbage collection is not destruction._"
3. "_Garbage collection is only about memory._"

Unlike in C++ (if object was created using new in C++, the destructor is called when calling delete operator), Java doesn't provide a similar method for releasing objects.

In Java, __System.gc()__ is used to force finalization.
However, neither garbage collection nor finalization is guaranteed.

In some classes, their instances should be in a state whereby their memory can be safely released when they are ready to be cleaned up.

## Java Memory Management and Garbage Collection

In fact, Java uses an algorithm called "Adaptive generational stop-and-copy mark-and-sweep collection".

The Heap in Java is split into several parts(generations): Young Generation, Old Generation(or Tenured Generation) and Permanent Generation. It is shown as below:

![Hotspot Heap Structure]({{ site.url }}/assets/images/java_gc/hotspot_heap_structure.png){:width="600px"}
<small>(Source: https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/images/gcslides/Slide5.png)</small>

The __Young Generation__ is where all new objects are allocated and aged. When the young generation fills up, this causes a minor garbage collection. Some surviving objects are aged and eventually move to the old generation.
The Young Generation is divided into __Eden__ and __Survivor Space__ that contains two equal sections.
Survivor Space is like a buffer space between Eden and Old Generation.

The __Old Generation__ is used to store long surviving objects.

The __Permanent Generation__ contains metadata required by the JVM to describe the classes and methods used in the application.

Normally:
1. Heap Space = Young Generation (1/3) + (Old Generation + Permanent Generation) (2/3)
2. Young Generation = Eden (8/10) + S0 (1/10) + S1 (1/10)

These Generations perform like stop-and-copy and mark-and-sweep.

There are a number of additional speedups possible in JVM. An especially important one involves the operation of the loader and what is called a just-in-time (JIT) compiler. A JIT compiler partially or fully converts a program into native machine code so that it doesn't need to be interpreted by JVM and thus runs much faster.

# Summary

In this blog, only some basic ideas about garbage collection are introduced.
More details and explanation can be found in the references.

# References

1. "_Thinking in Java (4th Edition)_" by Bruce Eckel - Cleanup: finalization and garbage collection.
2. "_深入理解Java虚拟机：JVM高级特性与最佳实践_" by 周志明 - 第3章　垃圾收集器与内存分配策略
3. [Managing Memory and Garbage Collection](https://docs.oracle.com/cd/E19159-01/819-3681/6n5srlhqf/index.html){:target="_blank"}
4. [Java Garbage Collection Basics](https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html){:target="_blank"}


text:
# Plugins

Graffiti provides a way to extend its functionality with plugins.
You can find two example plugins in this repo:

- [graffiti-plugin-auth](../packages/graffiti-plugin-auth) - simple email & password-based auth
- [graffiti-plugin-next](../packages/graffiti-plugin-next) - Next.js integration to allow for easy creation of frontend

## Using plugins

Plugins can be added to your Graffiti project by simply create `graffiti.config.js` file and adding corresponding plugin(s) to it.

In example shown below we add auth plugin and pass `secret` as option to it:

```js
const authPlugin = require('graffiti-plugin-auth');

module.exports = {
  mongoUrl: 'mongodb://localhost/graffiti-example',
  plugins: [authPlugin({ secret: 'my_super_secret_jwt_secret' })],
};
```

## Creating plugins

Plugins are separate modules, that might optionally take in user options, and contain set of properties that are automatically used withing Graffiti when plugin is registered.

```js
module.exports = (options) => {
  return {
    // additional schemas that should be registered
    schemas: [
      {
        // new schema name, in this case - user
        name: 'user',
        // other properties follow the structure of schema/*.js files
        schema: {
          username: 'String',
          password: 'String',
        },
      },
    ],
    // setup function that has access to fastify server instance
    // usually, you want to add fastify plugins here
    setup: async ({ server }) => {
      await server.register(fastifyPlugin);
    },
    // context function that allows adding data to graphql via context
    // in this case add `context.hello === 'world'`
    // to consume context - you will need to use custom resolvers
    context: (request, reply) => {
      return {
        hello: 'world',
      };
    },
  };
};
```