text:
function resetPage() {
    var obj = document.getElementById('emails')
    if (obj) {
        obj.innerHTML = ""
    }
}

// toggleEmail: Fetch a list of emails from an ML in a specific year/month
function toggleEmail(year, mo, nopush) {
    if (typeof year == 'string' && year.search(/-/) && typeof(mo) == 'undefined') {
        var m = year.split(/-/)
        year = parseInt(m[0])
        mo = parseInt(m[1])
    }
    global_deep = false
    current_query = ""
    current_retention = year + "-" + mo
    var arr = xlist.split('@', 2)
    var listname = arr[0]
    var domain = arr[1]
    var s = year + "-" + mo
    var e = s
    // if year and month is supplied, the calendar (to the left) should show where we are
    // so let's open up the right year and set the CSS for the selected month
    if (year && mo) {
        kiddos = []
        traverseThread(document.getElementById('datepicker'), 'calmonth', 'LABEL')
        for (var n in kiddos) {
            // if this is the active month, blue-ify it
            if (kiddos[n].getAttribute("id") == ("calmonth_" + year + "-" + mo)) {
                kiddos[n].setAttribute("class", "label label-info")
            // otherwise, default css
            } else {
                kiddos[n].setAttribute("class", "label label-default label-hover")
            }
        }
    }

    // if month is supplied, prettify it
    var xmo = mo ? parseInt(mo).toString() : ""
    if (mo.length > 0 && mo <= 9) {
        xmo = '0' + xmo
    }
    // push history state, fetch the data from API
    if (!nopush) {
        window.history.pushState({}, "", "list.html?" + xlist + ":" + year + '-' + xmo);
    }
    // update the quick search box
    var dp = document.getElementById('d')
    dp.value = datePickerValue(current_retention)
    dp.setAttribute("data", current_retention)
    GetAsync("/api/stats.lua?list=" + listname + "&domain=" + domain + "&s=" + s + "&e=" + e, null, buildPage)

    // set list title to list and year/month
    document.getElementById('listtitle').innerHTML = xlist + " (" + months[mo - 1] + ", " + year + ")" + "  "
}

// Top 10 search alias - for some reason search() can't be called from there... o.O
function searchTop(a,b,c,d) {
    var obj = document.getElementById('q')
    if (obj) {
        obj.value = a
    }
    search(a,b,c,d)
}

// search: run a search
function search(q, d, nopush, all) {
    keywords = q
    current_retention = d // we use this later in the pagebuilder
    current_query = q // ditto
    var arr = xlist.split('@', 2)
    var listname = arr[0]
    var olist = listname
    var domain = arr[1]

    // are we checking *@foo.tld ?
    if (document.getElementById('checkall')) {
        all = document.getElementById('checkall').checked
    }
    // If checking multiple lists, the globa_deep will tell the pagebuilder to also
    // include the mailing list name in each result
    global_deep = false
    if (all == true) {
        listname = "*"
        global_deep = true
    }

    // we just made a new search, clear the selected month in the calendar to the left if that makes sense
    clearCalendarHover()

    // As usual, push new history state
    if (!nopush) {
        window.history.pushState({}, "", "list.html?" + listname + "@" + domain + ":" + d + ":" + encodeURIComponent(q));
    }

    // get the data from backend, push to page builder func
    GetAsync("/api/stats.lua?list=" + listname + "&domain=" + domain + "&q=" + encodeURIComponent(q) + "&d=" + d, null, buildPage)

    // for the list title, prepare the date range
    // TODO: improve this much like we have with trends.html
    var arr = datePickerDouble(d)
    var howlong = datePickerValue(d)
    // howlong may begin with a month which should not be lower-cased.
    // or it may be 'Less than 1 month ago'
    // Avoid checking by starting a new sentence
    document.getElementById('listtitle').innerHTML = listname + "@" + domain + " (Quick Search. " + howlong + ") Clear filters"
    xlist = olist + "@" + domain
    return false;
}

// searchAll: run a deep search of all lists
// much the same as search(), but with added stuff for from and subject field searches.
function searchAll(q, dspan, from, subject, where) {
    keywords = q
    current_retention = dspan
    current_query = q
    global_deep = true
    var wherel = "*"
    var whered = "*"
    if (where && where == 'xlist') {
        var a = xlist.split(/@/)
        wherel = a[0]
        whered = a[1]
    }
    var url = "/api/stats.lua?list="+wherel+"&domain="+whered+"&q=" + encodeURIComponent(q) + "&d=" + encodeURIComponent(dspan)
    if (from) {
        url += "&header_from="  + "\""+ encodeURIComponent(from) + "\""
        current_query += " FROM:"  + "\""+ encodeURIComponent(from) + "\""
    }
    if (subject) {
        url += "&header_subject=\"" + encodeURIComponent(subject) + "\""
        current_query += " SUBJECT:\"" + encodeURIComponent(subject) + "\""
    }
    GetAsync(url, {
        deep: true
    }, buildPage)
    var arr = datePickerDouble(dspan)
    var howlong = arr[3]
    if (howlong == null || isNaN(howlong)) {
        howlong = "custom date range"
    } else {
        if (howlong >= 365) {
            howlong = parseInt(howlong/365) + " year"
        } else if (howlong >= 30) {
            howlong = "last " + parseInt(howlong/30) + " month" + (howlong>59 ? "s" : "")
        } else {
            howlong =  howlong + " day"
        }
    }
    document.getElementById('listtitle').innerHTML = "Deep Search, " + howlong + " view Clear filters"
    clearCalendarHover()
    return false;
}

// Adds an opensearch engine to the browser
function addSearchEngine() {
    window.external.AddSearchProvider(URL_BASE + "/api/websearch.lua?" + gxdomain)
}

// for firefox (chrome doesn't seem to get it just yet): add an opensearch header element,
// so the browser will notice that it's available, and inform the user in the quick search bar
function addSearchBar() {
    var h = document.getElementsByTagName('head')[0]
    var sl = document.createElement('link')
    sl.setAttribute("rel", "search")
    sl.setAttribute("type", "application/opensearchdescription+xml")
    sl.setAttribute("href", URL_BASE + "/api/websearch.lua?" + gxdomain)
    sl.setAttribute("title", "PonyMail: " + gxdomain + " mailing lists")
    h.appendChild(sl)
}


text:
namespace vulkan
{

    template<typename ubo_t>
    class UniformBuffer : public vulkan::Buffer
    {
    public:
        UniformBuffer (vulkan::Renderer *_renderer)
                : Buffer (_renderer, vk::BufferUsageFlagBits::eUniformBuffer)
        {
        }

        void create (ubo_t ubo)
        {
            vulkan::Buffer::create (sizeof (ubo), &ubo);
        }

        void update (ubo_t ubo)
        {
            vulkan::Buffer::update (sizeof (ubo), &ubo);
        }

    private:

    };

}

#endif //VULKANTEST_UNIFORMBUFFER_H

redpajama_set_name: RedPajamaGithub


text:
package calculationstrategy

const (
	defaultPercentageIncreaseCap = 0.5
)

// PercentageIncreaseCappedCalculator is a probability calculator that caps the probability
// increase to a certain percentage of the previous probability.
//
// Given prevProb = 0.1, newProb = 0.5, and cap = 0.5:
// (0.5 - 0.1)/0.1 = 400% increase. Given that our cap is 50%, the probability can only
// increase to 0.15.
//
// Given prevProb = 0.4, newProb = 0.5, and cap = 0.5:
// (0.5 - 0.4)/0.4 = 25% increase. Given that this is below our cap of 50%, the probability
// can increase to 0.5.
type PercentageIncreaseCappedCalculator struct {
	percentageIncreaseCap float64
}

// NewPercentageIncreaseCappedCalculator returns a new percentage increase capped calculator.
func NewPercentageIncreaseCappedCalculator(percentageIncreaseCap float64) PercentageIncreaseCappedCalculator {
	if percentageIncreaseCap == 0 {
		percentageIncreaseCap = defaultPercentageIncreaseCap
	}
	return PercentageIncreaseCappedCalculator{
		percentageIncreaseCap: percentageIncreaseCap,
	}
}

// Calculate calculates the new probability.
func (c PercentageIncreaseCappedCalculator) Calculate(targetQPS, curQPS, prevProbability float64) float64 {
	factor := targetQPS / curQPS
	newProbability := prevProbability * factor
	// If curQPS is lower than the targetQPS, we need to increase the probability slowly to
	// defend against oversampling.
	// Else if curQPS is higher than the targetQPS, jump directly to the newProbability to
	// defend against oversampling.
	if factor > 1.0 {
		percentIncrease := (newProbability - prevProbability) / prevProbability
		if percentIncrease > c.percentageIncreaseCap {
			newProbability = prevProbability + (prevProbability * c.percentageIncreaseCap)
		}
	}
	return newProbability
}


text:
package com.codahale.jerkson.deser

import language.higherKinds

import com.fasterxml.jackson.databind.JavaType
import com.fasterxml.jackson.databind.{ DeserializationContext, JsonDeserializer }
import com.fasterxml.jackson.core.{ JsonToken, JsonParser }
import collection.generic.MapFactory
import collection.MapLike
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer

class ImmutableMapDeserializer[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]](companion: MapFactory[CC],
  valueType: JavaType)
    extends JsonDeserializer[Object] with ResolvableDeserializer {

  var valueDeserializer: JsonDeserializer[Object] = _

  def deserialize(jp: JsonParser, ctxt: DeserializationContext): CC[String, Object] = {
    val builder = companion.newBuilder[String, Object]

    if (jp.getCurrentToken == JsonToken.START_OBJECT) {
      jp.nextToken()
    }

    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&
      jp.getCurrentToken != JsonToken.END_OBJECT) {
      throw ctxt.mappingException(valueType.getRawClass)
    }

    while (jp.getCurrentToken != JsonToken.END_OBJECT) {
      val name = jp.getCurrentName
      jp.nextToken()
      builder += ((name, valueDeserializer.deserialize(jp, ctxt)))
      jp.nextToken()
    }

    builder.result()
  }

  def resolve(ctxt: DeserializationContext) {
    valueDeserializer = ctxt.findRootValueDeserializer(valueType)
  }

  override def isCachable = true
}


text:
package io.kubernetes.client.openapi.models;

import io.kubernetes.client.fluent.BaseFluent;
import java.time.OffsetDateTime;

/** Generated */
@SuppressWarnings(value = "unchecked")
public class V1alpha1StorageVersionConditionFluentImpl<
        A extends V1alpha1StorageVersionConditionFluent<A>>
    extends BaseFluent<A> implements V1alpha1StorageVersionConditionFluent<A> {
  public V1alpha1StorageVersionConditionFluentImpl() {}

  public V1alpha1StorageVersionConditionFluentImpl(V1alpha1StorageVersionCondition instance) {
    this.withLastTransitionTime(instance.getLastTransitionTime());

    this.withMessage(instance.getMessage());

    this.withObservedGeneration(instance.getObservedGeneration());

    this.withReason(instance.getReason());

    this.withStatus(instance.getStatus());

    this.withType(instance.getType());
  }

  private OffsetDateTime lastTransitionTime;
  private String message;
  private Long observedGeneration;
  private String reason;
  private String status;
  private String type;

  public OffsetDateTime getLastTransitionTime() {
    return this.lastTransitionTime;
  }

  public A withLastTransitionTime(OffsetDateTime lastTransitionTime) {
    this.lastTransitionTime = lastTransitionTime;
    return (A) this;
  }

  public Boolean hasLastTransitionTime() {
    return this.lastTransitionTime != null;
  }

  public String getMessage() {
    return this.message;
  }

  public A withMessage(String message) {
    this.message = message;
    return (A) this;
  }

  public Boolean hasMessage() {
    return this.message != null;
  }

  public Long getObservedGeneration() {
    return this.observedGeneration;
  }

  public A withObservedGeneration(Long observedGeneration) {
    this.observedGeneration = observedGeneration;
    return (A) this;
  }

  public Boolean hasObservedGeneration() {
    return this.observedGeneration != null;
  }

  public String getReason() {
    return this.reason;
  }

  public A withReason(String reason) {
    this.reason = reason;
    return (A) this;
  }

  public Boolean hasReason() {
    return this.reason != null;
  }

  public String getStatus() {
    return this.status;
  }

  public A withStatus(String status) {
    this.status = status;
    return (A) this;
  }

  public Boolean hasStatus() {
    return this.status != null;
  }

  public String getType() {
    return this.type;
  }

  public A withType(String type) {
    this.type = type;
    return (A) this;
  }

  public Boolean hasType() {
    return this.type != null;
  }

  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    V1alpha1StorageVersionConditionFluentImpl that = (V1alpha1StorageVersionConditionFluentImpl) o;
    if (lastTransitionTime != null
        ? !lastTransitionTime.equals(that.lastTransitionTime)
        : that.lastTransitionTime != null) return false;
    if (message != null ? !message.equals(that.message) : that.message != null) return false;
    if (observedGeneration != null
        ? !observedGeneration.equals(that.observedGeneration)
        : that.observedGeneration != null) return false;
    if (reason != null ? !reason.equals(that.reason) : that.reason != null) return false;
    if (status != null ? !status.equals(that.status) : that.status != null) return false;
    if (type != null ? !type.equals(that.type) : that.type != null) return false;
    return true;
  }

  public int hashCode() {
    return java.util.Objects.hash(
        lastTransitionTime, message, observedGeneration, reason, status, type, super.hashCode());
  }

  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("{");
    if (lastTransitionTime != null) {
      sb.append("lastTransitionTime:");
      sb.append(lastTransitionTime + ",");
    }
    if (message != null) {
      sb.append("message:");
      sb.append(message + ",");
    }
    if (observedGeneration != null) {
      sb.append("observedGeneration:");
      sb.append(observedGeneration + ",");
    }
    if (reason != null) {
      sb.append("reason:");
      sb.append(reason + ",");
    }
    if (status != null) {
      sb.append("status:");
      sb.append(status + ",");
    }
    if (type != null) {
      sb.append("type:");
      sb.append(type);
    }
    sb.append("}");
    return sb.toString();
  }
}


text:
package org.elasticsearch.index.query.functionscore;

import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.lucene.search.function.ScriptScoreFunction;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.Script.ScriptField;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.SearchScript;

import java.io.IOException;
import java.util.Collections;
import java.util.Objects;

/**
 * A function that uses a script to compute or influence the score of documents
 * that match with the inner query or filter.
 */
public class ScriptScoreFunctionBuilder extends ScoreFunctionBuilder<ScriptScoreFunctionBuilder> {
    public static final String NAME = "script_score";

    private final Script script;

    public ScriptScoreFunctionBuilder(Script script) {
        if (script == null) {
            throw new IllegalArgumentException("script must not be null");
        }
        this.script = script;
    }

    /**
     * Read from a stream.
     */
    public ScriptScoreFunctionBuilder(StreamInput in) throws IOException {
        super(in);
        script = new Script(in);
    }

    @Override
    protected void doWriteTo(StreamOutput out) throws IOException {
        script.writeTo(out);
    }

    public Script getScript() {
        return this.script;
    }

    @Override
    public void doXContent(XContentBuilder builder, Params params) throws IOException {
        builder.startObject(getName());
        builder.field(ScriptField.SCRIPT.getPreferredName(), script);
        builder.endObject();
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    protected boolean doEquals(ScriptScoreFunctionBuilder functionBuilder) {
        return Objects.equals(this.script, functionBuilder.script);
    }

    @Override
    protected int doHashCode() {
        return Objects.hash(this.script);
    }

    @Override
    protected ScoreFunction doToFunction(QueryShardContext context) {
        try {
            SearchScript searchScript = context.getScriptService().search(context.lookup(), script, ScriptContext.Standard.SEARCH,
                    Collections.emptyMap());
            return new ScriptScoreFunction(script, searchScript);
        } catch (Exception e) {
            throw new QueryShardException(context, "script_score: the script could not be loaded", e);
        }
    }

    public static ScriptScoreFunctionBuilder fromXContent(QueryParseContext parseContext)
            throws IOException, ParsingException {
        XContentParser parser = parseContext.parser();
        Script script = null;
        String currentFieldName = null;
        XContentParser.Token token;
        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
            if (token == XContentParser.Token.FIELD_NAME) {
                currentFieldName = parser.currentName();
            } else {
                if (parseContext.getParseFieldMatcher().match(currentFieldName, ScriptField.SCRIPT)) {
                    script = Script.parse(parser, parseContext.getParseFieldMatcher(), parseContext.getDefaultScriptLanguage());
                } else {
                    throw new ParsingException(parser.getTokenLocation(), NAME + " query does not support [" + currentFieldName + "]");
                }
            }
        }

        if (script == null) {
            throw new ParsingException(parser.getTokenLocation(), NAME + " requires 'script' field");
        }

        return new ScriptScoreFunctionBuilder(script);
    }
}


text:
# If any previous instances of the runcasperinventory LaunchDaemon and script exist,
# unload the LaunchDaemon and remove the LaunchDaemon and script files

if [[ -f "/Library/LaunchDaemons/com.github.runcasperinventory.plist" ]]; then
   /bin/launchctl unload "/Library/LaunchDaemons/com.github.runcasperinventory.plist"
   /bin/rm "/Library/LaunchDaemons/com.github.runcasperinventory.plist"
fi

if [[ -f "/var/root/runcasperinventory.sh" ]]; then
   /bin/rm "/var/root/runcasperinventory.sh"
fi

# Create the runcasperinventory LaunchDaemon by using cat input redirection
# to write the XML contained below to a new file.
#
# The LaunchDaemon will run at load and every ten minutes thereafter.

/bin/cat > "/tmp/com.github.runcasperinventory.plist" << 'CASPER_POST_OS_UPGRADE_LAUNCHDAEMON'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.github.runcasperinventory</string>
	<key>ProgramArguments</key>
	<array>
		<string>sh</string>
		<string>/var/root/runcasperinventory.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>StartInterval</key>
	<integer>600</integer>
</dict>
</plist>
CASPER_POST_OS_UPGRADE_LAUNCHDAEMON

# Create the runcasperinventory script by using cat input redirection
# to write the shell script contained below to a new file.
#
# You will need to change the "jss_server_address" variable in the
# script below. Please put the complete fully qualified domain name
# address of your Casper server.
#
# You may need to change the "jss_server_port" variable in the
# script below. Please put the port number of your Casper server
# if it is different than 8443.

/bin/cat > "/tmp/runcasperinventory.sh" << 'CASPER_POST_OS_UPGRADE_SCRIPT'
#!/bin/bash

#
# User-editable variables
#

# For the jss_server_address variable, put the complete
# fully qualified domain name address of your Casper server

jss_server_address="casper.server.address.here"

# For the jss_server_address variable, put the port number
# of your Casper server. This is usually 8443; change as
# appropriate.

jss_server_port="8443"

CheckBinary (){

# Identify location of jamf binary.

jamf_binary=`/usr/bin/which jamf`

 if [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ ! -e "/usr/local/bin/jamf" ]]; then
    jamf_binary="/usr/sbin/jamf"
 elif [[ "$jamf_binary" == "" ]] && [[ ! -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then
    jamf_binary="/usr/local/bin/jamf"
 elif [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then
    jamf_binary="/usr/local/bin/jamf"
 fi
}

CheckSiteNetwork (){

  #  CheckSiteNetwork function adapted from Facebook's check_corp function script.
  #  check_corp script available on Facebook's IT-CPE Github repo:
  #
  # check_corp:
  #   This script verifies a system is on the corporate network.
  #   Input: CORP_URL= set this to a hostname on your corp network
  #   Optional ($1) contains a parameter that is used for testing.
  #   Output: Returns a check_corp variable that will return "True" if on
  #   corp network, "False" otherwise.
  #   If a parameter is passed ($1), the check_corp variable will return it
  #   This is useful for testing scripts where you want to force check_corp
  #   to be either "True" or "False"
  # USAGE:
  #   check_corp        # No parameter passed
  #   check_corp "True"  # Parameter of "True" is passed and returned

  site_network="False"
  ping=`host -W .5 $jss_server_address`

  # If the ping fails - site_network="False"
  [[ $? -eq 0 ]] && site_network="True"

  # Check if we are using a test
  [[ -n "$1" ]] && site_network="$1"
}

CheckTomcat (){

# Verifies that the JSS's Tomcat service is responding via its assigned port.

tomcat_chk=`nc -z -w 5 $jss_server_address $jss_server_port > /dev/null; echo $?`

if [ "$tomcat_chk" -eq 0 ]; then
       /usr/bin/logger "Machine can connect to $jss_server_address over port $jss_server_port. Proceeding."
else
       /usr/bin/logger "Machine cannot connect to $jss_server_address over port $jss_server_port. Exiting."
       exit 0
fi

}

CheckLogAge (){

# Verifies that the /var/log/jamf.log hasn't been written to for at least five minutes.
# This should help ensure that jamf manage can run and not have to wait for a policy to
# finish running.

jamf_log="/var/log/jamf.log"
current_time=`date +%s`
last_modified=`stat -f %m "$jamf_log"`

if [[ $(($current_time-$last_modified)) -gt 300 ]]; then
     /usr/bin/logger "Log has not been modified in the past five minutes. Proceeding."
else
     /usr/bin/logger "Log has been modified in the past five minutes. Exiting."
     exit 0
fi

}

UpdateManagementAndInventory (){

# Verifies that the Mac can communicate with the Casper server.
# Once communication is verified, it takes the following actions:
#
# 1. Runs jamf manage to enforce Casper management
# 2. Runs a recon to send an updated inventory to the JSS to report
#    that the OS upgrade has happened.
#

CheckBinary

jss_comm_chk=`$jamf_binary checkJSSConnection > /dev/null; echo $?`

if [[ "$jss_comm_chk" -gt 0 ]]; then
       /usr/bin/logger "Machine cannot connect to the JSS. Exiting."
       exit 0
elif [[ "$jss_comm_chk" -eq 0 ]]; then
       /usr/bin/logger "Machine can connect to the JSS. Enforcing management and updating inventory."
       $jamf_binary manage -verbose
       $jamf_binary recon
fi
}

SelfDestruct (){

# Removes script and associated LaunchDaemon

if [[ -f "/Library/LaunchDaemons/com.github.runcasperinventory.plist" ]]; then
   /bin/rm "/Library/LaunchDaemons/com.github.runcasperinventory.plist"
fi
srm $0
}

CheckSiteNetwork

if [[ "$site_network" == "False" ]]; then
    /usr/bin/logger "Unable to verify access to site network. Exiting."
fi

if [[ "$site_network" == "True" ]]; then
    /usr/bin/logger "Access to site network verified"
    CheckTomcat
    CheckLogAge
    CheckBinary
    UpdateManagementAndInventory
    SelfDestruct
fi
exit 0
CASPER_POST_OS_UPGRADE_SCRIPT

# Once the LaunchDaemon file has been created, fix the permissions
# so that the file is owned by root:wheel and set to not be executable
# After the permissions have been updated, move the LaunchDaemon into
# place in /Library/LaunchDaemons.

/usr/sbin/chown root:wheel "/tmp/com.github.runcasperinventory.plist"
/bin/chmod 755 "/tmp/com.github.runcasperinventory.plist"
/bin/chmod a-x "/tmp/com.github.runcasperinventory.plist"
/bin/mv "/tmp/com.github.runcasperinventory.plist" "/Library/LaunchDaemons/com.github.runcasperinventory.plist"

# Once the script file has been created, fix the permissions
# so that the file is owned by root:wheel and set to be executable
# After the permissions have been updated, move the script into the
# place that it will be executed from.

/usr/sbin/chown root:wheel "/tmp/runcasperinventory.sh"
/bin/chmod 755 "/tmp/runcasperinventory.sh"
/bin/chmod a+x "/tmp/runcasperinventory.sh"
/bin/mv "/tmp/runcasperinventory.sh" "/var/root/runcasperinventory.sh"

# After the LaunchDaemon and script are in place with proper permissions,
# load the LaunchDaemon to begin the script's execution.

if [[ -f "/Library/LaunchDaemons/com.github.runcasperinventory.plist" ]]; then
   /bin/launchctl load -w "/Library/LaunchDaemons/com.github.runcasperinventory.plist"
fi

exit 0


text:
Ext.onReady(function(){
    Ext.get('mb1').on('click', function(e){
        Ext.MessageBox.confirm('Confirm', 'Are you sure you want to do that?', showResult);
    });

    Ext.get('mb2').on('click', function(e){
        Ext.MessageBox.prompt('Name', 'Please enter your name:', showResultText);
    });

    Ext.get('mb3').on('click', function(e){
        Ext.MessageBox.show({
           title: 'Address',
           msg: 'Please enter your address:',
           width:300,
           buttons: Ext.MessageBox.OKCANCEL,
           multiline: true,
           fn: showResultText,
           animEl: 'mb3'
       });
    });

    Ext.get('mb4').on('click', function(e){
        Ext.MessageBox.show({
           title:'Save Changes?',
           msg: 'You are closing a tab that has unsaved changes. <br />Would you like to save your changes?',
           buttons: Ext.MessageBox.YESNOCANCEL,
           fn: showResult,
           animEl: 'mb4',
           icon: Ext.MessageBox.QUESTION
       });
    });

    Ext.get('mb6').on('click', function(){
        Ext.MessageBox.show({
           title: 'Please wait',
           msg: 'Loading items...',
           progressText: 'Initializing...',
           width:300,
           progress:true,
           closable:false,
           animEl: 'mb6'
       });

       // this hideous block creates the bogus progress
       var f = function(v){
            return function(){
                if(v == 12){
                    Ext.MessageBox.hide();
                    Ext.example.msg('Done', 'Your fake items were loaded!');
                }else{
                    var i = v/11;
                    Ext.MessageBox.updateProgress(i, Math.round(100*i)+'% completed');
                }
           };
       };
       for(var i = 1; i < 13; i++){
           setTimeout(f(i), i*500);
       }
    });

    Ext.get('mb7').on('click', function(){
        Ext.MessageBox.show({
           msg: 'Saving your data, please wait...',
           progressText: 'Saving...',
           width:300,
           wait:true,
           waitConfig: {interval:200},
           icon:'ext-mb-download', //custom class in msg-box.html
           animEl: 'mb7'
       });
        setTimeout(function(){
            //This simulates a long-running operation like a database save or XHR call.
            //In real code, this would be in a callback function.
            Ext.MessageBox.hide();
            Ext.example.msg('Done', 'Your fake data was saved!');
        }, 8000);
    });

    Ext.get('mb8').on('click', function(){
        Ext.MessageBox.alert('Status', 'Changes saved successfully.', showResult);
    });

    //Add these values dynamically so they aren't hard-coded in the html
    Ext.fly('info').dom.value = Ext.MessageBox.INFO;
    Ext.fly('question').dom.value = Ext.MessageBox.QUESTION;
    Ext.fly('warning').dom.value = Ext.MessageBox.WARNING;
    Ext.fly('error').dom.value = Ext.MessageBox.ERROR;

    Ext.get('mb9').on('click', function(){
        Ext.MessageBox.show({
           title: 'Icon Support',
           msg: 'Here is a message with an icon!',
           buttons: Ext.MessageBox.OK,
           animEl: 'mb9',
           fn: showResult,
           icon: Ext.get('icons').dom.value
       });
    });

    function showResult(btn){
        Ext.example.msg('Button Click', 'You clicked the {0} button', btn);
    };

    function showResultText(btn, text){
        Ext.example.msg('Button Click', 'You clicked the {0} button and entered the text "{1}".', btn, text);
    };
});


text:
'use strict'
import { Deferred, Promise, defer } from 'q'

export default class Util {
  static streamToPromise(stream: any): Promise<any> {
    const p = defer()
    stream.setEncoding('utf8')
    stream.on('data', (d) => null)
    stream.on('error', (err) => p.reject(err))
    stream.on('end', () => p.resolve(null))
    return p.promise
  }
  static callbackToPromise<T>(deferred: Deferred<T>) {
    return (err, data: T) => {
      if (err) { deferred.reject(err)}
      else { deferred.resolve(data) }
    }
  }
}


text:
package com.alibaba.otter.canal.parse.inbound;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.alibaba.otter.canal.common.AbstractCanalLifeCycle;
import com.alibaba.otter.canal.common.alarm.CanalAlarmHandler;
import com.alibaba.otter.canal.filter.CanalEventFilter;
import com.alibaba.otter.canal.parse.CanalEventParser;
import com.alibaba.otter.canal.parse.exception.CanalParseException;
import com.alibaba.otter.canal.parse.exception.TableIdNotFoundException;
import com.alibaba.otter.canal.parse.inbound.EventTransactionBuffer.TransactionFlushCallback;
import com.alibaba.otter.canal.parse.index.CanalLogPositionManager;
import com.alibaba.otter.canal.parse.support.AuthenticationInfo;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.position.EntryPosition;
import com.alibaba.otter.canal.protocol.position.LogIdentity;
import com.alibaba.otter.canal.protocol.position.LogPosition;
import com.alibaba.otter.canal.sink.CanalEventSink;
import com.alibaba.otter.canal.sink.exception.CanalSinkException;

/**
 * 抽象的EventParser, 最大化共用mysql/oracle版本的实现
 *
 * @author jianghang 2013-1-20 下午08:10:25
 * @version 1.0.0
 */
public abstract class AbstractEventParser<EVENT> extends AbstractCanalLifeCycle implements CanalEventParser<EVENT> {

    protected final Logger                           logger                  = LoggerFactory.getLogger(this.getClass());

    protected CanalLogPositionManager                logPositionManager      = null;
    protected CanalEventSink<List<CanalEntry.Entry>> eventSink               = null;
    protected CanalEventFilter                       eventFilter             = null;

    private CanalAlarmHandler                        alarmHandler            = null;

    // 统计参数
    protected AtomicBoolean                          profilingEnabled        = new AtomicBoolean(false);                // profile开关参数
    protected AtomicLong                             receivedEventCount      = new AtomicLong();
    protected AtomicLong                             parsedEventCount        = new AtomicLong();
    protected AtomicLong                             consumedEventCount      = new AtomicLong();
    protected long                                   parsingInterval         = -1;
    protected long                                   processingInterval      = -1;

    // 认证信息
    protected volatile AuthenticationInfo            runningInfo;
    protected String                                 destination;

    // binLogParser
    protected BinlogParser                           binlogParser            = null;

    protected Thread                                 parseThread             = null;

    protected Thread.UncaughtExceptionHandler        handler                 = new Thread.UncaughtExceptionHandler() {

                                                                                public void uncaughtException(
                                                                                Thread t,
                                                                                Throwable e) {
                                                                                logger.error(
                                                                                "parse events has an error",
                                                                                e);
                                                                                }
                                                                             };

    protected EventTransactionBuffer                 transactionBuffer;
    protected int                                    transactionSize         = 1024;
    protected AtomicBoolean                          needTransactionPosition = new AtomicBoolean(false);

    protected abstract BinlogParser buildParser();

    protected abstract ErosaConnection buildErosaConnection();

    protected abstract EntryPosition findStartPosition(ErosaConnection connection) throws IOException;

    protected void preDump(ErosaConnection connection) {
    }

    protected void afterDump(ErosaConnection connection) {
    }

    public void sendAlarm(String destination, String msg) {
        if (this.alarmHandler != null) {
            this.alarmHandler.sendAlarm(destination, msg);
        }
    }

    public AbstractEventParser(){
        // 初始化一下
        transactionBuffer = new EventTransactionBuffer(new TransactionFlushCallback() {

            public void flush(List<CanalEntry.Entry> transaction) throws InterruptedException {
                boolean successed = consumeTheEventAndProfilingIfNecessary(transaction);
                if (!running) {
                    return;
                }

                if (!successed) {
                    throw new CanalParseException("consume failed!");
                }

                LogPosition position = buildLastTranasctionPosition(transaction);
                if (position != null) { // 可能position为空
                    logPositionManager.persistLogPosition(AbstractEventParser.this.destination, position);
                }
            }
        });
    }

    public void start() {
        super.start();
        MDC.put("destination", destination);
        // 配置transaction buffer
        // 初始化缓冲队列
        transactionBuffer.setBufferSize(transactionSize);// 设置buffer大小
        transactionBuffer.start();
        // 1. 构造bin log parser
        binlogParser = buildParser();// 初始化一下BinLogParser
        binlogParser.start();
        // 启动工作线程
        parseThread = new Thread(new Runnable() {

            public void run() {
                MDC.put("destination", String.valueOf(destination));
                ErosaConnection erosaConnection = null;
                while (running) {
                    try {

                        // 开始执行replication
                        // 1. 构造Erosa连接
                        erosaConnection = buildErosaConnection();
                        erosaConnection.connect();// 链接
                        // 2. 获取最后的位置信息
                        final EntryPosition startPosition = findStartPosition(erosaConnection);
                        if (startPosition == null) {
                            throw new CanalParseException("can't find start position for " + destination);
                        }
                        logger.info("find start position : {}", startPosition.toString());
                        // 重新链接,因为在找position过程中可能有状态,需要断开后重建
                        erosaConnection.reconnect();
                        // 3. 执行dump前的准备工作
                        preDump(erosaConnection);

                        final SinkFunction sinkHandler = new SinkFunction<EVENT>() {

                            private LogPosition lastPosition;

                            public boolean sink(EVENT event) {
                                try {
                                    CanalEntry.Entry entry = parseAndProfilingIfNecessary(event);

                                    if (!running) {
                                        return false;
                                    }

                                    if (entry != null) {
                                        transactionBuffer.add(entry);
                                        // 记录一下对应的positions
                                        this.lastPosition = buildLastPosition(entry);
                                    }
                                    return running;
                                } catch (TableIdNotFoundException e) {
                                    throw e;
                                } catch (Exception e) {
                                    processError(e, this.lastPosition, startPosition.getJournalName(),
                                                 startPosition.getPosition());
                                    // 走到这一步,说明出错了
                                    return false;
                                }
                            }

                        };

                        // 4. 开始dump数据
                        if (StringUtils.isEmpty(startPosition.getJournalName()) && startPosition.getTimestamp() != null) {
                            erosaConnection.dump(startPosition.getTimestamp(), sinkHandler);
                        } else {
                            erosaConnection.dump(startPosition.getJournalName(), startPosition.getPosition(),
                                                 sinkHandler);
                        }

                    } catch (TableIdNotFoundException e) {
                        // 特殊处理TableIdNotFound异常,出现这样的异常,一种可能就是起始的position是一个事务当中,导致tablemap Event时间没解析过
                        needTransactionPosition.compareAndSet(false, true);
                        logger.error(String.format("dump address %s has an error, retrying. caused by ",
                                                   runningInfo.getAddress().toString()), e);
                    } catch (Throwable e) {
                        if (!running) {
                            if (!(e instanceof java.nio.channels.ClosedByInterruptException || e.getCause() instanceof java.nio.channels.ClosedByInterruptException)) {
                                throw new CanalParseException(String.format("dump address %s has an error, retrying. ",
                                                                            runningInfo.getAddress().toString()), e);
                            }
                        } else {
                            logger.error(String.format("dump address %s has an error, retrying. caused by ",
                                                       runningInfo.getAddress().toString()), e);
                            sendAlarm(destination, ExceptionUtils.getFullStackTrace(e));
                        }
                    } finally {
                        // 关闭一下链接
                        afterDump(erosaConnection);
                        try {
                            if (erosaConnection != null) {
                                erosaConnection.disconnect();
                            }
                        } catch (IOException e1) {
                            if (!running) {
                                throw new CanalParseException(
                                                              String.format(
                                                                            "disconnect address %s has an error, retrying. ",
                                                                            runningInfo.getAddress().toString()), e1);
                            } else {
                                logger.error("disconnect address {} has an error, retrying., caused by ",
                                             runningInfo.getAddress().toString(), e1);
                            }
                        }
                    }
                    // 出异常了,退出sink消费,释放一下状态
                    eventSink.interrupt();
                    transactionBuffer.reset();// 重置一下缓冲队列,重新记录数据

                    if (running) {
                        // sleep一段时间再进行重试
                        try {
                            Thread.sleep(10000 + RandomUtils.nextInt(10000));
                        } catch (InterruptedException e) {
                        }
                    }
                }
                MDC.remove("destination");
            }
        });

        parseThread.setUncaughtExceptionHandler(handler);
        parseThread.setName(String.format("destination = %s , AbstractEventParser", destination));
        parseThread.start();
    }

    public void stop() {
        super.stop();

        parseThread.interrupt(); // 尝试中断
        eventSink.interrupt();
        try {
            parseThread.join();// 等待其结束
        } catch (InterruptedException e) {
            // ignore
        }

        if (binlogParser.isStart()) {
            binlogParser.stop();
        }
        if (transactionBuffer.isStart()) {
            transactionBuffer.stop();
        }
    }

    protected boolean consumeTheEventAndProfilingIfNecessary(List<CanalEntry.Entry> entrys) throws CanalSinkException,
                                                                                InterruptedException {
        long startTs = -1;
        boolean enabled = getProfilingEnabled();
        if (enabled) {
            startTs = System.currentTimeMillis();
        }

        boolean result = eventSink.sink(entrys, (runningInfo == null) ? null : runningInfo.getAddress(), destination);

        if (enabled) {
            this.processingInterval = System.currentTimeMillis() - startTs;
        }

        if (consumedEventCount.incrementAndGet() < 0) {
            consumedEventCount.set(0);
        }

        return result;
    }

    protected CanalEntry.Entry parseAndProfilingIfNecessary(EVENT bod) throws Exception {
        long startTs = -1;
        boolean enabled = getProfilingEnabled();
        if (enabled) {
            startTs = System.currentTimeMillis();
        }
        CanalEntry.Entry event = binlogParser.parse(bod);

        if (enabled) {
            this.parsingInterval = System.currentTimeMillis() - startTs;
        }

        if (parsedEventCount.incrementAndGet() < 0) {
            parsedEventCount.set(0);
        }
        return event;
    }

    public Boolean getProfilingEnabled() {
        return profilingEnabled.get();
    }

    protected LogPosition buildLastTranasctionPosition(List<CanalEntry.Entry> entries) { // 初始化一下
        for (int i = entries.size() - 1; i > 0; i--) {
            CanalEntry.Entry entry = entries.get(i);
            if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {// 尽量记录一个事务做为position
                LogPosition logPosition = new LogPosition();
                EntryPosition position = new EntryPosition();
                position.setJournalName(entry.getHeader().getLogfileName());
                position.setPosition(entry.getHeader().getLogfileOffset());
                position.setTimestamp(entry.getHeader().getExecuteTime());
                logPosition.setPostion(position);

                LogIdentity identity = new LogIdentity(runningInfo.getAddress(), -1L);
                logPosition.setIdentity(identity);
                return logPosition;
            }
        }

        return null;
    }

    protected LogPosition buildLastPosition(CanalEntry.Entry entry) { // 初始化一下
        LogPosition logPosition = new LogPosition();
        EntryPosition position = new EntryPosition();
        position.setJournalName(entry.getHeader().getLogfileName());
        position.setPosition(entry.getHeader().getLogfileOffset());
        position.setTimestamp(entry.getHeader().getExecuteTime());
        logPosition.setPostion(position);

        LogIdentity identity = new LogIdentity(runningInfo.getAddress(), -1L);
        logPosition.setIdentity(identity);
        return logPosition;
    }

    protected void processError(Exception e, LogPosition lastPosition, String startBinlogFile, long startPosition) {
        if (lastPosition != null) {
            logger.warn(String.format("ERROR ## parse this event has an error , last position : [%s]",
                                      lastPosition.getPostion()), e);
        } else {
            logger.warn(String.format("ERROR ## parse this event has an error , last position : [%s,%s]",
                                      startBinlogFile, startPosition), e);
        }
    }

    public void setEventFilter(CanalEventFilter eventFilter) {
        this.eventFilter = eventFilter;
    }

    public Long getParsedEventCount() {
        return parsedEventCount.get();
    }

    public Long getConsumedEventCount() {
        return consumedEventCount.get();
    }

    public void setProfilingEnabled(boolean profilingEnabled) {
        this.profilingEnabled = new AtomicBoolean(profilingEnabled);
    }

    public long getParsingInterval() {
        return parsingInterval;
    }

    public long getProcessingInterval() {
        return processingInterval;
    }

    public void setEventSink(CanalEventSink<List<CanalEntry.Entry>> eventSink) {
        this.eventSink = eventSink;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public void setBinlogParser(BinlogParser binlogParser) {
        this.binlogParser = binlogParser;
    }

    public BinlogParser getBinlogParser() {
        return binlogParser;
    }

    public void setAlarmHandler(CanalAlarmHandler alarmHandler) {
        this.alarmHandler = alarmHandler;
    }

    public CanalAlarmHandler getAlarmHandler() {
        return this.alarmHandler;
    }

    public void setLogPositionManager(CanalLogPositionManager logPositionManager) {
        this.logPositionManager = logPositionManager;
    }

    public void setTransactionSize(int transactionSize) {
        this.transactionSize = transactionSize;
    }

}


text:
namespace System.Messaging.Design
{
    using System;
    using System.Drawing;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using System.Windows.Forms.ComponentModel;
    using System.Windows.Forms.Design;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Messaging;

    /// <include file='doc\QueuePathEditor.uex' path='docs/doc[@for="QueuePathEditor"]/*' />
    /// <devdoc>
    ///    <para>[To be supplied.]</para>
    /// </devdoc>
    // permissions demanded by parent class
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
    [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name = "FullTrust")]
    public class QueuePathEditor : UITypeEditor
    {

        /// <include file='doc\QueuePathEditor.uex' path='docs/doc[@for="QueuePathEditor.EditValue"]/*' />
        /// <devdoc>
        ///      Edits the given object value using the editor style provided by
        ///      GetEditorStyle.  A service provider is provided so that any
        ///      required editing services can be obtained.
        /// </devdoc>
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (provider != null)
            {
                IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                if (edSvc != null)
                {
                    QueuePathDialog dialog = new QueuePathDialog(provider);
                    MessageQueue queue = null;
                    if (value is MessageQueue)
                        queue = (MessageQueue)value;
                    else if (value is string)
                        queue = new MessageQueue((string)value);
                    else if (value != null)
                        return value;

                    if (queue != null)
                        dialog.SelectQueue(queue);

                    IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
                    DesignerTransaction trans = null;
                    if (host != null)
                        trans = host.CreateTransaction();

                    try
                    {
                        if ((context == null || context.OnComponentChanging()) && edSvc.ShowDialog(dialog) == DialogResult.OK)
                        {
                            if (dialog.Path != String.Empty)
                            {
                                if (context.Instance is MessageQueue || context.Instance is MessageQueueInstaller)
                                    value = dialog.Path;
                                else
                                {
                                    value = MessageQueueConverter.GetFromCache(dialog.Path);
                                    if (value == null)
                                    {
                                        value = new MessageQueue(dialog.Path);
                                        MessageQueueConverter.AddToCache((MessageQueue)value);
                                        if (context != null)
                                            context.Container.Add((IComponent)value);
                                    }
                                }

                                context.OnComponentChanged();
                            }
                        }
                    }
                    finally
                    {
                        if (trans != null)
                        {
                            trans.Commit();
                        }
                    }
                }
            }

            return value;
        }

        /// <include file='doc\QueuePathEditor.uex' path='docs/doc[@for="QueuePathEditor.GetEditStyle"]/*' />
        /// <devdoc>
        ///      Retrieves the editing style of the Edit method.  If the method
        ///      is not supported, this will return None.
        /// </devdoc>
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
    }
}


text:
#region License

#endregion

using Newtonsoft.Json;

namespace ShipStation4Net.Domain.Entities
{
    public class ShipmentItem
    {
        [JsonProperty("orderItemId")]
        public int? OrderItemId { get; set; }

        [JsonProperty("lineItemKey")]
        public string LineItemKey { get; set; }

        [JsonProperty("sku")]
        public string Sku { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("imageUrl")]
        public string ImageUrl { get; set; }

        [JsonProperty("weight")]
        public Weight Weight { get; set; }

        [JsonProperty("quantity")]
        public int? Quantity { get; set; }

        [JsonProperty("unitPrice")]
        public int? UnitPrice { get; set; }

        [JsonProperty("warehouseLocation")]
        public string WarehouseLocation { get; set; }

        //[JsonProperty("options")]
        //public string Options { get; set; }

        [JsonProperty("productId")]
        public int? ProductId { get; set; }

        [JsonProperty("fulfillmentSku")]
        public string FulfillmentSku { get; set; }
    }

}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Ecosystem Explorer</title>

    <link href="/portfolio/css/bootstrap.css" rel="stylesheet">

    <link href="/portfolio/css/portfolio-item.css" rel="stylesheet">

    <link href="/portfolio/css/background.css" rel="stylesheet">

    <link href="/portfolio/css/animate.css" rel="stylesheet">

                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    Toggle navigation

                </button>
                Brenton Walker

                        Projects Home

Ecosystem Explorer
                    Flora and fauna of Utah

Project Description

                An interactive exhibit in the "Life" section of the Natural History Museum of Utah. A group trivia game that contains 10 categories of '-est' questions about the flora and fauna of Utah.

                The experience is built with the intention of having multiple users participating at the same time.

My Role

                Producer

Published

August 2014

Engine

                     Unity 4.5

Dev Time

                4 months

Team size

                4

Users

Multiple

About
                My role in the project

              I was the producer and a designer on the project. The project did not start with a design and I lead the design process through various iterations.

               I oversaw writing and managing the question database, as well as organized and imported assets into the code. I managed all digital images and their implementation into the code. I also organized and ran various playtests with school groups and pivoted based on feedback.

                I worked with the museum on both front and backend hardware and managed the install of the app on site.

               I developed this app while simultaneously working on 'Which Scientist Am I?'.

Video
                Prototype experience

            The app as run on a touchscreen in the museum

Screenshots
                Captured moments from various stages in development

Download
                Check it out yourself

            Because "Ecosystem Explorer" is a permanent installation of the Natural History Museum, I can't give out the source publicly. Contact me for more information.

© Brenton Walker

	<link href="/portfolio/css/lightbox.css" rel="stylesheet" />


text:
<?php

namespace yii\console\controllers;

use Yii;
use yii\console\Exception;
use yii\console\Controller;
use yii\helpers\FileHelper;

/**
 * BaseMigrateController is base class for migrate controllers.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
abstract class BaseMigrateController extends Controller
{
    /**
     * The name of the dummy migration that marks the beginning of the whole migration history.
     */
    const BASE_MIGRATION = 'm000000_000000_base';

    /**
     * @var string the default command action.
     */
    public $defaultAction = 'up';
    /**
     * @var string the directory storing the migration classes. This can be either
     * a path alias or a directory.
     */
    public $migrationPath = '@app/migrations';
    /**
     * @var string the template file for generating new migrations.
     * This can be either a path alias (e.g. "@app/migrations/template.php")
     * or a file path.
     */
    public $templateFile;

    /**
     * @inheritdoc
     */
    public function options($actionId)
    {
        return array_merge(
            parent::options($actionId),
            ['migrationPath'], // global for all actions
            ($actionId == 'create') ? ['templateFile'] : [] // action create
        );
    }

    /**
     * This method is invoked right before an action is to be executed (after all possible filters.)
     * It checks the existence of the [[migrationPath]].
     * @param \yii\base\Action $action the action to be executed.
     * @throws Exception if db component isn't configured
     * @return boolean whether the action should continue to be executed.
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            $path = Yii::getAlias($this->migrationPath);
            if (!is_dir($path)) {
                echo "";
                FileHelper::createDirectory($path);
            }
            $this->migrationPath = $path;

            $version = Yii::getVersion();
            echo "Yii Migration Tool (based on Yii v{$version})\n\n";

            return true;
        } else {
            return false;
        }
    }

    /**
     * Upgrades the application by applying new migrations.
     * For example,
     *
     * ~~~
     * yii migrate     # apply all new migrations
     * yii migrate 3   # apply the first 3 new migrations
     * ~~~
     *
     * @param integer $limit the number of new migrations to be applied. If 0, it means
     * applying all available new migrations.
     *
     * @return integer the status of the action execution. 0 means normal, other values mean abnormal.
     */
    public function actionUp($limit = 0)
    {
        $migrations = $this->getNewMigrations();
        if (empty($migrations)) {
            echo "No new migration found. Your system is up-to-date.\n";

            return self::EXIT_CODE_NORMAL;
        }

        $total = count($migrations);
        $limit = (int) $limit;
        if ($limit > 0) {
            $migrations = array_slice($migrations, 0, $limit);
        }

        $n = count($migrations);
        if ($n === $total) {
            echo "Total $n new " . ($n === 1 ? 'migration' : 'migrations') . " to be applied:\n";
        } else {
            echo "Total $n out of $total new " . ($total === 1 ? 'migration' : 'migrations') . " to be applied:\n";
        }

        foreach ($migrations as $migration) {
            echo "    $migration\n";
        }
        echo "\n";

        if ($this->confirm('Apply the above ' . ($n === 1 ? 'migration' : 'migrations') . "?")) {
            foreach ($migrations as $migration) {
                if (!$this->migrateUp($migration)) {
                    echo "\nMigration failed. The rest of the migrations are canceled.\n";

                    return self::EXIT_CODE_ERROR;
                }
            }
            echo "\nMigrated up successfully.\n";
        }
    }

    /**
     * Downgrades the application by reverting old migrations.
     * For example,
     *
     * ~~~
     * yii migrate/down     # revert the last migration
     * yii migrate/down 3   # revert the last 3 migrations
     * yii migrate/down all # revert all migrations
     * ~~~
     *
     * @param integer $limit the number of migrations to be reverted. Defaults to 1,
     * meaning the last applied migration will be reverted.
     * @throws Exception if the number of the steps specified is less than 1.
     *
     * @return integer the status of the action execution. 0 means normal, other values mean abnormal.
     */
    public function actionDown($limit = 1)
    {
        if ($limit === 'all') {
            $limit = null;
        } else {
            $limit = (int) $limit;
            if ($limit < 1) {
                throw new Exception("The step argument must be greater than 0.");
            }
        }

        $migrations = $this->getMigrationHistory($limit);

        if (empty($migrations)) {
            echo "No migration has been done before.\n";

            return self::EXIT_CODE_NORMAL;
        }

        $migrations = array_keys($migrations);

        $n = count($migrations);
        echo "Total $n " . ($n === 1 ? 'migration' : 'migrations') . " to be reverted:\n";
        foreach ($migrations as $migration) {
            echo "    $migration\n";
        }
        echo "\n";

        if ($this->confirm('Revert the above ' . ($n === 1 ? 'migration' : 'migrations') . "?")) {
            foreach ($migrations as $migration) {
                if (!$this->migrateDown($migration)) {
                    echo "\nMigration failed. The rest of the migrations are canceled.\n";

                    return self::EXIT_CODE_ERROR;
                }
            }
            echo "\nMigrated down successfully.\n";
        }
    }

    /**
     * Redoes the last few migrations.
     *
     * This command will first revert the specified migrations, and then apply
     * them again. For example,
     *
     * ~~~
     * yii migrate/redo     # redo the last applied migration
     * yii migrate/redo 3   # redo the last 3 applied migrations
     * yii migrate/redo all # redo all migrations
     * ~~~
     *
     * @param integer $limit the number of migrations to be redone. Defaults to 1,
     * meaning the last applied migration will be redone.
     * @throws Exception if the number of the steps specified is less than 1.
     *
     * @return integer the status of the action execution. 0 means normal, other values mean abnormal.
     */
    public function actionRedo($limit = 1)
    {
        if ($limit === 'all') {
            $limit = null;
        } else {
            $limit = (int) $limit;
            if ($limit < 1) {
                throw new Exception("The step argument must be greater than 0.");
            }
        }

        $migrations = $this->getMigrationHistory($limit);

        if (empty($migrations)) {
            echo "No migration has been done before.\n";

            return self::EXIT_CODE_NORMAL;
        }

        $migrations = array_keys($migrations);

        $n = count($migrations);
        echo "Total $n " . ($n === 1 ? 'migration' : 'migrations') . " to be redone:\n";
        foreach ($migrations as $migration) {
            echo "    $migration\n";
        }
        echo "\n";

        if ($this->confirm('Redo the above ' . ($n === 1 ? 'migration' : 'migrations') . "?")) {
            foreach ($migrations as $migration) {
                if (!$this->migrateDown($migration)) {
                    echo "\nMigration failed. The rest of the migrations are canceled.\n";

                    return self::EXIT_CODE_ERROR;
                }
            }
            foreach (array_reverse($migrations) as $migration) {
                if (!$this->migrateUp($migration)) {
                    echo "\nMigration failed. The rest of the migrations migrations are canceled.\n";

                    return self::EXIT_CODE_ERROR;
                }
            }
            echo "\nMigration redone successfully.\n";
        }
    }

    /**
     * Upgrades or downgrades till the specified version.
     *
     * Can also downgrade versions to the certain apply time in the past by providing
     * a UNIX timestamp or a string parseable by the strtotime() function. This means
     * that all the versions applied after the specified certain time would be reverted.
     *
     * This command will first revert the specified migrations, and then apply
     * them again. For example,
     *
     * ~~~
     * yii migrate/to 101129_185401                      # using timestamp
     * yii migrate/to m101129_185401_create_user_table   # using full name
     * yii migrate/to 1392853618                         # using UNIX timestamp
     * yii migrate/to "2014-02-15 13:00:50"              # using strtotime() parseable string
     * ~~~
     *
     * @param string $version either the version name or the certain time value in the past
     * that the application should be migrated to. This can be either the timestamp,
     * the full name of the migration, the UNIX timestamp, or the parseable datetime
     * string.
     * @throws Exception if the version argument is invalid.
     */
    public function actionTo($version)
    {
        if (preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/', $version, $matches)) {
            $this->migrateToVersion('m' . $matches[1]);
        } elseif ((string) (int) $version == $version) {
            $this->migrateToTime($version);
        } elseif (($time = strtotime($version)) !== false) {
            $this->migrateToTime($time);
        } else {
            throw new Exception("The version argument must be either a timestamp (e.g. 101129_185401),\n the full name of a migration (e.g. m101129_185401_create_user_table),\n a UNIX timestamp (e.g. 1392853000), or a datetime string parseable\nby the strtotime() function (e.g. 2014-02-15 13:00:50).");
        }
    }

    /**
     * Modifies the migration history to the specified version.
     *
     * No actual migration will be performed.
     *
     * ~~~
     * yii migrate/mark 101129_185401                      # using timestamp
     * yii migrate/mark m101129_185401_create_user_table   # using full name
     * ~~~
     *
     * @param string $version the version at which the migration history should be marked.
     * This can be either the timestamp or the full name of the migration.
     * @throws Exception if the version argument is invalid or the version cannot be found.
     */
    public function actionMark($version)
    {
        $originalVersion = $version;
        if (preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/', $version, $matches)) {
            $version = 'm' . $matches[1];
        } else {
            throw new Exception("The version argument must be either a timestamp (e.g. 101129_185401)\nor the full name of a migration (e.g. m101129_185401_create_user_table).");
        }

        // try mark up
        $migrations = $this->getNewMigrations();
        foreach ($migrations as $i => $migration) {
            if (strpos($migration, $version . '_') === 0) {
                if ($this->confirm("Set migration history at $originalVersion?")) {
                    for ($j = 0; $j <= $i; ++$j) {
                        $this->addMigrationHistory($migrations[$j]);
                    }
                    echo "The migration history is set at $originalVersion.\nNo actual migration was performed.\n";
                }

                return self::EXIT_CODE_NORMAL;
            }
        }

        // try mark down
        $migrations = array_keys($this->getMigrationHistory(null));
        foreach ($migrations as $i => $migration) {
            if (strpos($migration, $version . '_') === 0) {
                if ($i === 0) {
                    echo "Already at '$originalVersion'. Nothing needs to be done.\n";
                } else {
                    if ($this->confirm("Set migration history at $originalVersion?")) {
                        for ($j = 0; $j < $i; ++$j) {
                            $this->removeMigrationHistory($migrations[$j]);
                        }
                        echo "The migration history is set at $originalVersion.\nNo actual migration was performed.\n";
                    }
                }

                return self::EXIT_CODE_NORMAL;
            }
        }

        throw new Exception("Unable to find the version '$originalVersion'.");
    }

    /**
     * Displays the migration history.
     *
     * This command will show the list of migrations that have been applied
     * so far. For example,
     *
     * ~~~
     * yii migrate/history     # showing the last 10 migrations
     * yii migrate/history 5   # showing the last 5 migrations
     * yii migrate/history all # showing the whole history
     * ~~~
     *
     * @param integer $limit the maximum number of migrations to be displayed.
     * If it is 0, the whole migration history will be displayed.
     * @throws \yii\console\Exception if invalid limit value passed
     */
    public function actionHistory($limit = 10)
    {
        if ($limit === 'all') {
            $limit = null;
        } else {
            $limit = (int) $limit;
            if ($limit < 1) {
                throw new Exception("The limit must be greater than 0.");
            }
        }

        $migrations = $this->getMigrationHistory($limit);

        if (empty($migrations)) {
            echo "No migration has been done before.\n";
        } else {
            $n = count($migrations);
            if ($limit > 0) {
                echo "Showing the last $n applied " . ($n === 1 ? 'migration' : 'migrations') . ":\n";
            } else {
                echo "Total $n " . ($n === 1 ? 'migration has' : 'migrations have') . " been applied before:\n";
            }
            foreach ($migrations as $version => $time) {
                echo "    (" . date('Y-m-d H:i:s', $time) . ') ' . $version . "\n";
            }
        }
    }

    /**
     * Displays the un-applied new migrations.
     *
     * This command will show the new migrations that have not been applied.
     * For example,
     *
     * ~~~
     * yii migrate/new     # showing the first 10 new migrations
     * yii migrate/new 5   # showing the first 5 new migrations
     * yii migrate/new all # showing all new migrations
     * ~~~
     *
     * @param integer $limit the maximum number of new migrations to be displayed.
     * If it is 0, all available new migrations will be displayed.
     * @throws \yii\console\Exception if invalid limit value passed
     */
    public function actionNew($limit = 10)
    {
        if ($limit === 'all') {
            $limit = null;
        } else {
            $limit = (int) $limit;
            if ($limit < 1) {
                throw new Exception("The limit must be greater than 0.");
            }
        }

        $migrations = $this->getNewMigrations();

        if (empty($migrations)) {
            echo "No new migrations found. Your system is up-to-date.\n";
        } else {
            $n = count($migrations);
            if ($limit && $n > $limit) {
                $migrations = array_slice($migrations, 0, $limit);
                echo "Showing $limit out of $n new " . ($n === 1 ? 'migration' : 'migrations') . ":\n";
            } else {
                echo "Found $n new " . ($n === 1 ? 'migration' : 'migrations') . ":\n";
            }

            foreach ($migrations as $migration) {
                echo "    " . $migration . "\n";
            }
        }
    }

    /**
     * Creates a new migration.
     *
     * This command creates a new migration using the available migration template.
     * After using this command, developers should modify the created migration
     * skeleton by filling up the actual migration logic.
     *
     * ~~~
     * yii migrate/create create_user_table
     * ~~~
     *
     * @param string $name the name of the new migration. This should only contain
     * letters, digits and/or underscores.
     * @throws Exception if the name argument is invalid.
     */
    public function actionCreate($name)
    {
        if (!preg_match('/^\w+$/', $name)) {
            throw new Exception("The migration name should contain letters, digits and/or underscore characters only.");
        }

        $name = 'm' . gmdate('ymd_His') . '_' . $name;
        $file = $this->migrationPath . DIRECTORY_SEPARATOR . $name . '.php';

        if ($this->confirm("Create new migration '$file'?")) {
            $content = $this->renderFile(Yii::getAlias($this->templateFile), ['className' => $name]);
            file_put_contents($file, $content);
            echo "New migration created successfully.\n";
        }
    }

    /**
     * Upgrades with the specified migration class.
     * @param string $class the migration class name
     * @return boolean whether the migration is successful
     */
    protected function migrateUp($class)
    {
        if ($class === self::BASE_MIGRATION) {
            return true;
        }

        echo "*** applying $class\n";
        $start = microtime(true);
        $migration = $this->createMigration($class);
        if ($migration->up() !== false) {
            $this->addMigrationHistory($class);
            $time = microtime(true) - $start;
            echo "*** applied $class (time: " . sprintf("%.3f", $time) . "s)\n\n";

            return true;
        } else {
            $time = microtime(true) - $start;
            echo "*** failed to apply $class (time: " . sprintf("%.3f", $time) . "s)\n\n";

            return false;
        }
    }

    /**
     * Downgrades with the specified migration class.
     * @param string $class the migration class name
     * @return boolean whether the migration is successful
     */
    protected function migrateDown($class)
    {
        if ($class === self::BASE_MIGRATION) {
            return true;
        }

        echo "*** reverting $class\n";
        $start = microtime(true);
        $migration = $this->createMigration($class);
        if ($migration->down() !== false) {
            $this->removeMigrationHistory($class);
            $time = microtime(true) - $start;
            echo "*** reverted $class (time: " . sprintf("%.3f", $time) . "s)\n\n";

            return true;
        } else {
            $time = microtime(true) - $start;
            echo "*** failed to revert $class (time: " . sprintf("%.3f", $time) . "s)\n\n";

            return false;
        }
    }

    /**
     * Creates a new migration instance.
     * @param string $class the migration class name
     * @return \yii\db\MigrationInterface the migration instance
     */
    protected function createMigration($class)
    {
        $file = $this->migrationPath . DIRECTORY_SEPARATOR . $class . '.php';
        require_once($file);

        return new $class();
    }

    /**
     * Migrates to the specified apply time in the past.
     * @param integer $time UNIX timestamp value.
     */
    protected function migrateToTime($time)
    {
        $count = 0;
        $migrations = array_values($this->getMigrationHistory(null));
        while ($count < count($migrations) && $migrations[$count] > $time) {
            ++$count;
        }
        if ($count === 0) {
            echo "Nothing needs to be done.\n";
        } else {
            $this->actionDown($count);
        }
    }

    /**
     * Migrates to the certain version.
     * @param string $version name in the full format.
     * @throws Exception if the provided version cannot be found.
     */
    protected function migrateToVersion($version)
    {
        $originalVersion = $version;

        // try migrate up
        $migrations = $this->getNewMigrations();
        foreach ($migrations as $i => $migration) {
            if (strpos($migration, $version . '_') === 0) {
                $this->actionUp($i + 1);

                return self::EXIT_CODE_NORMAL;
            }
        }

        // try migrate down
        $migrations = array_keys($this->getMigrationHistory(null));
        foreach ($migrations as $i => $migration) {
            if (strpos($migration, $version . '_') === 0) {
                if ($i === 0) {
                    echo "Already at '$originalVersion'. Nothing needs to be done.\n";
                } else {
                    $this->actionDown($i);
                }

                return self::EXIT_CODE_NORMAL;
            }
        }

        throw new Exception("Unable to find the version '$originalVersion'.");
    }

    /**
     * Returns the migrations that are not applied.
     * @return array list of new migrations
     */
    protected function getNewMigrations()
    {
        $applied = [];
        foreach ($this->getMigrationHistory(null) as $version => $time) {
            $applied[substr($version, 1, 13)] = true;
        }

        $migrations = [];
        $handle = opendir($this->migrationPath);
        while (($file = readdir($handle)) !== false) {
            if ($file === '.' || $file === '..') {
                continue;
            }
            $path = $this->migrationPath . DIRECTORY_SEPARATOR . $file;
            if (preg_match('/^(m(\d{6}_\d{6})_.*?)\.php$/', $file, $matches) && is_file($path) && !isset($applied[$matches[2]])) {
                $migrations[] = $matches[1];
            }
        }
        closedir($handle);
        sort($migrations);

        return $migrations;
    }

    /**
     * Returns the migration history.
     * @param integer $limit the maximum number of records in the history to be returned. `null` for "no limit".
     * @return array the migration history
     */
    abstract protected function getMigrationHistory($limit);

    /**
     * Adds new migration entry to the history.
     * @param string $version migration version name.
     */
    abstract protected function addMigrationHistory($version);

    /**
     * Removes existing migration from the history.
     * @param string $version migration version name.
     */
    abstract protected function removeMigrationHistory($version);
}


text:
window.app = window.app || {};
var bg = chrome.extension.getBackgroundPage();

window.addEventListener('load', _onLoad);

function trackButton(e) {
  app.TRACKER.event('event', e.id, 'popup', 'clicked');
};
StackExchangeWrapper.auth.getToken()

function _onLoad() {
  app.TRACKER.page('popups.html');
  $('.btn_an').click(function() {
    trackButton($(this)[0])
  });
  app.Utils.restore_options();
  chrome.storage.sync.get(null, function(items) {
    if (items['se_auth_token'] && items['se_auth_token'] != '') {
      app.Utils.login_success();
    } else {
      app.Utils.logout_success();
    }
  });

}
classname = document.getElementsByClassName("options")
for (var i = 0; i < classname.length; i++) {
  classname[i].addEventListener("change", app.Utils.save_options);
}

document.getElementById('open_options').addEventListener('click', function() {
  chrome.tabs.create({
    'url': 'chrome://extensions/?options=' + chrome.runtime.id
  });
})

document.getElementById('register').addEventListener('click', function() {
  StackExchangeWrapper.auth.requestToken();
})
document.getElementById('logout').addEventListener('click', function() {
  StackExchangeWrapper.auth.deactivate();
})


text:
require 'fileutils'

class Meggy::FileCache
  def store
    file_path_array = File.split(path)
    file_name = file_path_array.pop
    cache_path = create_cache_path(File.join(file_path_array))
    File.open(File.join(cache_path, file_name), "w", perm) do |io|
      io.print(contents)
    end
  end
end


text:
This file maps each topic covered in the lectures of 2016 to
when it was covered in 2018.

## Format:

* Topic → Chapter X: The topic presented in this lecture of 2016 is covered in
    chapter X of the 2018 lecture notes.
* ?: This topic doesn't seem to appear in the 2018 lecture notes.
* If a sub-topic is marked with a different chapter or "?" than its super-topic,
    it means the sub-topic has moved or been removed, while the other sub-topics
    are still in the same chapter as the super-topic.

# Topics covered in L1 2016:

* Maths as study of "ideal languages", philosophies of math → ?
* Logic → Chapter 2
* First order languages → ? (At least not presented as in 2016)
    - Syntax
    - Semantics
    - FOL for Arithmetic → ? (Some parts are similar to Chapter 1, but
        other parts are quite different)
        + Names and functions
        + Terms
        + Variables
        + Variable lookup
    - Well formed formulas → **Chapter 2, as extra material**
    - Arithmetical predicate → ?

# Topics covered in L2 2016:

* Formal proofs → Chapter 2
* Proofs and functional programming → Chapter 2
    - Conjunction, intro and elim
    - Implication, intro and elim
    - Negation, intro and elim
    - Example: sqrt 2 is irrational

# Topics covered in L3 2016:

* Logic and functional programming, part 2 → Chapter 2
    - Disjunction, intro and elim
        + Example: There exist two irrational numbers a and b such that a^b is rational
    - Equality (identity), intro and elim → **?**
    - Universal quantifier, intro and elim
    - Existential quantifier, intro and elim
* Parallels between logical rules and functional programming → Chapter 2

# Topics covered in L4 2016:

* Curry–Howard isomorphism for quantifiers → Chapter 2
    - Implementing intro and elim rules for implication and quantifiers in
        haskell
* Proofs and programs → Chapter 2
    - Example: there is always another prime
    - Example: {a_n} convergent ∧ f : ℝ → ℝ continuous → {f a_n} convergent
        - Introduce types of series a_n, ε, n, write as typed logic

# Topics covered in L5 2016:

* Types in mathematics → Chapter 3
    - Introduction to types in mathematics
    - Examples of "higher-order" operators whose type is rarely given explicitly
* Type inference and understanding → Chapter 3
    - Case study: Lagrange equations

# Topics covered in L6 2016:

* Type classes → Chapter 3
    - Introduction to type classes in Haskell
* Computing derivatives → Chapter 3
    - The "little language" of derivatives
        - Implementing as haskell data type
        - evaluator
        - implementing `derive`
* Shallow embeddings → Chapter 3
    - Semantics of derivatives is not compositional
    - Introduce tupling transform to make it compositional
    - Create `instance Num a => Num (a -> a, a -> a)`

*I could not find any notes for L7 2016*

# Topics covered in L8 2016:

* Embedded DSL for Chebyshev interpolation → ?
    - Vectors in haskell → **Chapter 7 (sort of)**
    - Type classes for vectors
    - Intro to problem: For a given function f, want to find a sequence of polynomials P1, P2, ... Pn
        which converges to f as n → ∞
    - Ideas for polynomial approximation
        - Taylor series → **Chapter 6**
        - Interpolating polynomial
        - Chebyshev polynomial
            - Recursive definition
            - Relation to Discrete Cosine Transform, Discrete Fourier Transform
    - Types and functions for computing Chebyshev polynomials in Haskell
    - Differential equations → **Chapter 6, Chapter 8**
    - Differential matrices → **Chapter 7**
    - Examples of applications

# Topics covered in L9 2016:

* Algebras, homomorphisms → Chapter 4
    - Algebras
        - Example: Monoid
        - Example: Monoid equations
    - Homomorphisms
        - Example: Monoid homomorphisms
* Homomorphisms and compositional semantics → Chapter 4
* Other homomorphisms → Chapter 4
    - function application
        - on pairs of functions

# Topics covered in L10 2016:

* Preliminaries: → Chapter 4
    - different implementations of `Num` for pairs of functions are
        possible, nothing in the "nature" of pairs of functions forces this
        particular definition.
* Polynomials → Chapter 5
    - Definition from Adams 2010 Calculus
    - Type inference
    - Define in haskell as list of coefficients + evaulator
    - Define as `data Poly a = Single a | Cons a (Poly a)`
        - Relation between this and list
        - `instance Show`
        - evaluator
        - Derivation of `Num` instance
    - Polynomials are not isomorphic with polynomial functions
    - Polynomial functions are the semantics of the language of polynomials
* Power series → Chapter 5
    - Definition
    - Define as `type PowerSeries a = Poly a` + evaluator
    - `takePoly` as approximation of PowerSeries
    - Deriving definition of division
    - Formal derivatives

# Topics covered in L11 2016:

* Integration of power series → Chapter 6
* Differential equations and the elementary functions → Chapter 6
    - Representing functions as power series - Deriving power series
        representations of elementary functions using `integ` → **?  (Their
        definitions presented in a list in 2018, but their derivations are not
        shown explicitly. Moreover, the definitions in 2018 use `solve`, whereas
        2016 defines them in terms of `integ`)**
        - `id` → `idx`
        - `exp` → `expx`
        - `sin, cos` → `sinx, cosx`
        - `log` → `logx`
    - Computing general exponentiation → **?**
    - Implementing `solve`, defining functions as power series in terms of
        `solve`
* Composition of power series → **?**

# Topics covered in L12 2016:

* Exponential function → Chapter 8
    - Definition
    - Relation to complex numbers
* Taylor series → Chapter 6
    - Introduction
    - Using it to find derivatives of `f a`
        - at `a == 0`
        - at `a != 0`
    - The language of power series **is** the language of automatic derivatives.

# Topics covered in L13 2016:

* The Laplace transform → Chapter 8
    - Solving differential equations using `integ` and power series
    - Deriving the Laplace Transform in order to find a way to solve
        differential equations
    - Using the Laplace Transform to solve differential equations
        - Linearity
        - Deriving Laplace Transform of `exp`
        - Partial fraction decomposition
        - Inverse transform


text:
package org.kiji.schema.extra.tools

import java.util.Arrays

import org.apache.avro.file.DataFileReader
import org.apache.avro.file.FileReader
import org.apache.avro.file.SeekableInput
import org.apache.avro.generic.GenericDatumReader
import org.apache.commons.io.IOUtils
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.AvroFSInput
import org.apache.hadoop.fs.FileContext
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.Path
import org.apache.hadoop.hbase.io.hfile.CacheConfig
import org.apache.hadoop.hbase.io.hfile.FixedFileTrailer
import org.apache.hadoop.hbase.io.hfile.HFile
import org.apache.hadoop.hbase.io.hfile.HFileReaderV2
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.io.MapFile
import org.apache.hadoop.io.SequenceFile
import org.apache.hadoop.io.Writable
import org.apache.hadoop.io.WritableComparable
import org.apache.hadoop.util.ReflectionUtils
import org.kiji.common.flags.Flag
import org.kiji.common.flags.FlagParser
import org.kiji.schema.tools.BaseTool
import org.slf4j.LoggerFactory

/**
 * Command-line tool to inspect common files used in Map/Reduce jobs.
 */
class InspectFileTool extends BaseTool {
  private final val Log = LoggerFactory.getLogger(classOf[InspectFileTool])

  @Flag(name="format", usage="File format. One of 'text', 'seq', 'hfile', 'map', 'avro'.")
  var format: String = null

  @Flag(name="path",
      usage="Path of the file to dump. May also be specified as an unnamed positional argument.")
  var pathFlag: String = null

  override def getName(): String = {
    return "cat"
  }

  override def getCategory(): String = {
    return "extra"
  }

  override def getDescription(): String = {
    return "Dumps the content of a file."
  }

  override def getUsageString(): String = {
    return """Usage:
        |    kiji cat [--path=]<path> [--format=(text|seq|avro|map|hfile)]
        |"""
        .stripMargin
  }

  /**
   * Reads a sequence file of (song ID, # of song plays) into a map.
   *
   * @param path is the Hadoop path of the sequence file to read.
   */
  private def readSequenceFile(path: Path): Unit = {
    val reader = new SequenceFile.Reader(getConf, SequenceFile.Reader.file(path))
    try {
      Console.err.println("Key class: %s".format(reader.getKeyClassName))
      Console.err.println("Value class: %s".format(reader.getValueClassName))
      Console.err.println("Compression type: %s".format(reader.getCompressionType))
      Console.err.println("Compression codec: %s".format(reader.getCompressionCodec))
      if (!reader.getMetadata.getMetadata.isEmpty) {
        Console.err.println("Metadata:%n%s".format(reader.getMetadata.getMetadata))
      } else {
        Console.err.println("File '%s' has no metadata".format(path))
      }

      val key: Writable =
          ReflectionUtils.newInstance(reader.getKeyClass, getConf)
          .asInstanceOf[Writable]
      val value: Writable =
          ReflectionUtils.newInstance(reader.getValueClass, getConf)
          .asInstanceOf[Writable]
      while (true) {
        val position = reader.getPosition
        if (!reader.next(key, value)) {
          return
        }
        Console.out.println("position=%s\tkey=%s\tvalue=%s".format(position, key, value))
      }
    } finally {
      reader.close()
    }
  }

  /**
   * Reads a Hadoop map file.
   *
   * @param path is the Hadoop path of the map file to read.
   */
  private def readMapFile(path: Path): Unit = {
    val reader = new MapFile.Reader(path, getConf)
    try {
      val key: WritableComparable[_] =
          ReflectionUtils.newInstance(reader.getKeyClass, getConf)
          .asInstanceOf[WritableComparable[_]]
      val value: Writable =
          ReflectionUtils.newInstance(reader.getValueClass, getConf)
          .asInstanceOf[Writable]
      while (true) {
        if (!reader.next(key, value)) {
          return
        }
        Console.out.println("key=%s\tvalue=%s".format(key, value))
      }
    } finally {
      reader.close()
    }
  }

  /**
   * Reads an HBase HFile.
   *
   * @param path is the Hadoop path to the HFile to read.
   */
  private def readHFile(path: Path): Unit = {
    val conf = getConf
    val cacheConf = new CacheConfig(conf)
    val fs = FileSystem.get(conf)
    val reader: HFile.Reader = HFile.createReader(fs, path, cacheConf, conf)
    try {
      val cacheBlocks = false
      val positionalRead = false
      val scanner = reader.getScanner(cacheBlocks, positionalRead)

      var hasNext = scanner.seekTo()
      while (hasNext) {
        val keyValue = scanner.getKeyValue
        val rowKey = keyValue.getRow
        val family = keyValue.getFamily
        val qualifier = keyValue.getQualifier
        val timestamp = keyValue.getTimestamp
        val value = keyValue.getValue

        Console.out.println("row=%-30sfamily=%-10squalifer=%-10stimestamp=%s\tvalue=%s".format(
            Bytes.toStringBinary(rowKey),
            Bytes.toStringBinary(family),
            Bytes.toStringBinary(qualifier),
            timestamp,
            Bytes.toStringBinary(value)))

        hasNext = scanner.next()
      }
      // no need to close scanner
    } finally {
      reader.close()
    }
  }

  /**
   * Reads an Avro container file.
   *
   * @param path is the Hadoop path of the Avro container file to read.
   */
  def readAvroContainer(path: Path): Unit = {
    val context: FileContext = FileContext.getFileContext()
    val input: SeekableInput = new AvroFSInput(context, path)
    val datumReader: GenericDatumReader[_] = new GenericDatumReader()
    val reader: FileReader[_] = DataFileReader.openReader(input, datumReader)
    try {
      println("Schema:\n%s".format(reader.getSchema().toString(true)))
      var counter = 0
      while (reader.hasNext) {
        val rec = reader.next()
        println("entry #%d: %s".format(counter, rec))
        counter += 1
      }
    } finally {
      reader.close()
    }
  }

  /**
   * Reads a text file.
   *
   * @param path is the Hadoop path of the text file to read.
   */
  def readTextFile(path: Path): Unit = {
    val fs = FileSystem.get(getConf)
    val istream = fs.open(path)
    try {
      IOUtils.copy(istream, Console.out)
    } finally {
      istream.close()
    }
  }

  /**
   * Reads the first bytes in a file.
   *
   * @param path is the Hadoop path of the file to read from.
   * @param nbytes is the number of bytes to read.
   * @return the first bytes from the specified file.
   */
  def readFileStart(path: Path, conf: Configuration, nbytes: Int = 16): Array[Byte] = {
    val fs = FileSystem.get(conf)
    val istream = fs.open(path)
    try {
      val bytes = new Array[Byte](16)
      val nbytesRead = istream.read(bytes)
      return bytes.slice(0, nbytesRead)
    } finally {
      istream.close()
    }
  }

  /**
   * Tests whether a file's first bytes match a given magic code.
   *
   * @param bytes is the first bytes from a file to test.
   * @param magic is a magic code to test for.
   * @return whether the first bytes in the file match the specified magic code.
   */
  def isMagic(bytes: Array[Byte], magic: Array[Byte]): Boolean = {
    return Arrays.equals(bytes.slice(0, magic.length), magic)
  }

  // See DataFileConstants.MAGIC
  final val AvroContainerFileMagic = Array[Byte]('O', 'b', 'j')

  // See SequenceFile.VERSION
  final val SequenceFileMagic = Array[Byte]('S', 'E', 'Q')

  /**
   * Guesses a file type.
   *
   * @param path is the path of the file to guess the type of.
   * @param conf is a Hadoop configuration.
   * @return the guessed file type, or None.
   */
  def guessFileType(path: Path, conf: Configuration): Option[String] = {
    try {
      val bytes = readFileStart(path, conf)
      if (isMagic(bytes, AvroContainerFileMagic)) return Some("avro")
      if (isMagic(bytes, SequenceFileMagic)) return Some("seq")
    } catch {
      case exn => Console.err.println(exn)
    }
    return None
  }

  /**
   * Program entry point.
   *
   * @param args is the array of command-line arguments.
   */
  override def run(unparsed: java.util.List[String]): Int = {
    // Requires either --path=<path> or a single unnamed argument <path> (exclusive OR):
    if (!((unparsed.size == 1) ^ ((pathFlag != null) && unparsed.isEmpty))) {
      FlagParser.printUsage(this, Console.out)
      return BaseTool.FAILURE
    }

    val path: String = if (pathFlag != null) pathFlag else unparsed.get(0)
    val filePath = new Path(path)

    if (format == null) {
      format = guessFileType(filePath, getConf) match {
        case Some(fmt) => fmt
        case None => "text"  // assume text if no other type is detected
      }
      Log.info("Detected file type: {}", format)
    }
    format match {
      case "seq" => readSequenceFile(filePath)
      case "map" => readMapFile(filePath)
      case "hfile" => readHFile(filePath)
      case "avro" => readAvroContainer(filePath)
      case "text" => readTextFile(filePath)
      case _ => sys.error("Unknown file format: %s".format(format))
    }
    return BaseTool.SUCCESS
  }
}


text:
Configuration Settings for Third-Party Libraries

## [Nginx](https://nginx.org/en/docs/)
_A Reverse Proxy Server_

**Installation on EC2:**
```bash
sudo yum install -y nginx
sudo chmod 777 /etc/rc3.d/S99local; echo "service nginx restart" >> /etc/rc3.d/S99local
```

**Modification:**
```bash
nano /etc/nginx/nginx.conf
sudo service nginx restart
```

**Troubleshooting:**

## [Certbot](https://letsencrypt.org/getting-started/)
_A Free SSL Certificate Authority_

**Installation on EC2:**
```bash
$ sudo yum install -y wget
$ wget https://dl.eff.org/certbot-auto
$ sudo chmod a+x certbot-auto
$ sudo mv certbot-auto /usr/local/bin/certbot-auto
$ certbot-auto --debug -y --version
$ sudo service nginx stop # optional
$ sudo su -
$ certbot-auto certonly --standalone -d collectiveacuity.com,www.collectiveacuity.com --debug
> Is this ok [y/d/N]:
> Enter email address: (used … cancel):
> (A)gree/(C)ancel:
> (Y)es/(N)o:
$ exit
$ sudo service nginx start # optional
```

**Renewal:**(certificate expires every 90 days)
```bash
$ sudo su -
$ certbot-auto renew --standalone --debug --pre-hook "service nginx stop" --post-hook "service nginx start"
$ exit
```

**Modification:**
```bash
$ sudo su -
$ certbot-auto certonly --standalone --debug -n --cert-name collectiveacuity.com -d collectiveacuity.com,www.collectiveacuity.com,api.collectiveacuity.com --pre-hook "service nginx stop" --post-hook "service nginx start"  --debug
$ exit
```

**Check Certificates:**
```bash
$ sudo su -
$ certbot-auto certificates --standalone --debug --pre-hook "service nginx stop" --post-hook "service nginx start"
$ exit
```

**Troubleshooting:**
A. Due to updates to certbot, python modules may be missing from installation:
```bash
$ sudo su -
$ pip install -U pip
$ /root/.local/share/letsencrypt/bin/pip install {missing module}
```
B. Due to 32bit / 64 bit issues, python venv libs may need to be copied:
```bash
$ sudo su -
$ \cp -r /opt/eff.org/certbot/venv/lib64/* /opt/eff.org/certbot/venv/lib/
$ exit
```

## [Keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html)
_A Keystore Generator for Self-Signed SSL Trust Rings_

**Create Folder for Keys:**
```bash
mkdir keys
cd keys
```

**Generate Root RSA Key:**
```bash
openssl req -newkey rsa:2048 -x509 -nodes -keyout root.key \
 -out root.crt -days 36500 -passout pass:mysecretpassword \
 -subj /CN=root/OU=None/O=None/L=None/C=None
```

**Generate Node Key:**
```bash
keytool -genkey -keyalg RSA -alias 123.456.789.0 \
 -validity 36500 -keystore 123.456.789.0.jks \
 -storepass mysecretpassword -keypass mysecretpassword -keysize 4096 \
 -dname "CN=123.456.789.0, OU=None, O=None, L=None, C=None"
keytool -importkeystore -srckeystore 123.456.789.0.jks \
 -destkeystore 123.456.789.0.jks -deststoretype pkcs12 \
 -storepass mysecretpassword -keypass mysecretpassword
```

**Generate Cert Request:**
```bash
keytool -certreq -alias 123.456.789.0 -file 123.456.789.0.csr \
 -keystore 123.456.789.0.jks -storepass mysecretpassword -keypass mysecretpassword \
 -dname "CN=123.456.789.0, OU=None, O=None, L=None, C=None"
```

**Sign Cert with Root Cert:**
```bash
openssl x509 -req -CA root.crt -CAkey root.key \
 -in 123.456.789.0.csr -out 123.456.789.0.crt -days 36500 \
 -CAcreateserial -passin pass:mysecretpassword
```

**Add Certs to Node Keystore:**
```bash
keytool -importcert -keystore 123.456.789.0.jks -alias root \
 -file root.crt -noprompt -keypass mysecretpassword -storepass mysecretpassword
keytool -importcert -keystore 123.456.789.0.jks \
 -alias 123.456.789.0 -file 123.456.789.0.crt -noprompt \
 -keypass mysecretpassword -storepass mysecretpassword
```

**Add Root Cert to Truststore:**
```bash
keytool -importcert -keystore truststore.jks -alias root \
 -file root.crt -noprompt -keypass mysecretpassword -storepass mysecretpassword
```

**Add Node Certs to Truststore (for each node):**
```bash
keytool -importcert -keystore truststore.jks \
 -alias 123.456.789.0 -file 123.456.789.0.crt -noprompt \
 -keypass mysecretpassword -storepass mysecretpassword
```

**Verify Certificates:**
```bash
openssl x509 -in root.crt -text -noout
keytool -list -keystore 123.456.789.0.jks -storepass mysecretpassword
openssl verify -CAfile root.crt 123.456.789.0.crt
keytool -list -keystore truststore.jks -storepass mysecretpassword
```

**Generate PEM Files:**
```bash
openssl pkcs12 -in 123.456.789.0.jks -nokeys \
 -out 123.456.789.0.cer.pem -passin pass:mysecretpassword
openssl pkcs12 -in 123.456.789.0.jks -nodes  \
 -nocerts -out 123.456.789.0.key.pem -passin pass:mysecretpassword
```

**Generate Certificate Chain:**
```bash
cat root.crt 123.456.789.0.crt > 123.456.789.0.chain
```