Updated: 3/7/2017
This document is oriented at users who want a deeper understanding of the Kubernetes API structure, and developers wanting to extend the Kubernetes API. An introduction to using resources with kubectl can be found in the object management overview.
Table of Contents
The conventions of the Kubernetes API (and related APIs in the ecosystem) are intended to ease client development and ensure that configuration mechanisms can be implemented that work across a diverse set of use cases consistently.
The general style of the Kubernetes API is RESTful - clients create, update, delete, or retrieve a description of an object via the standard HTTP verbs (POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return JSON. Kubernetes also exposes additional endpoints for non-standard verbs and allows alternative content types. All of the JSON accepted and returned by the server has a schema, identified by the “kind” and “apiVersion” fields. Where relevant HTTP header fields exist, they should mirror the content of JSON fields, but the information should not be represented only in the HTTP header.
The following terms are defined:
Each resource typically accepts and returns data of a single kind. A kind may be accepted or returned by multiple resources that reflect specific use cases. For instance, the kind “Pod” is exposed as a “pods” resource that allows end users to create, update, and delete pods, while a separate “pod status” resource (that acts on “Pod” kind) allows automated processes to update a subset of the fields in that resource.
Resources are bound together in API groups - each group may have one or more versions that evolve independent of other API groups, and each version within the group has one or more resources. Group names are typically in domain name form - the Kubernetes project reserves use of the empty group, all single word names (“extensions”, “apps”), and any group name ending in “*.k8s.io” for its sole use. When choosing a group name, we recommend selecting a subdomain your group or organization owns, such as “widget.mycompany.com”.
Resource collections should be all lowercase and plural, whereas kinds are CamelCase and singular. Group names must be lower case and be valid DNS subdomains.
Kinds are grouped into three categories:
Creating an API object is a record of intent - once created, the system will work to ensure that resource exists. All API objects have common metadata.
An object may have multiple resources that clients can use to perform specific actions that create, update, delete, or get.
Examples: Pod
, ReplicationController
, Service
, Namespace
, Node
.
The name of a list kind must end with “List”. Lists have a limited set of common metadata. All lists use the required “items” field to contain the array of objects they return. Any kind that has the “items” field must be a list kind.
Most objects defined in the system should have an endpoint that returns the full set of resources, as well as zero or more endpoints that return subsets of the full list. Some objects may be singletons (the current user, the system defaults) and may not have lists.
In addition, all lists that return objects with labels should support label filtering (see the labels documentation), and most lists should support filtering by fields.
Examples: PodLists, ServiceLists, NodeLists
TODO: Describe field filtering below or in a separate doc.
Given their limited scope, they have the same set of limited common metadata as lists.
For instance, the “Status” kind is returned when errors occur and is not persisted in the system.
Many simple resources are “subresources”, which are rooted at API paths of specific resources. When resources wish to expose alternative actions or views that are closely coupled to a single resource, they should do so using new sub-resources. Common subresources include:
/binding
: Used to bind a resource representing a user request (e.g., Pod,
PersistentVolumeClaim) to a cluster infrastructure resource (e.g., Node,
PersistentVolume)./status
: Used to write just the status portion of a resource. For
example, the /pods
endpoint only allows updates to metadata
and spec
,
since those reflect end-user intent. An automated process should be able to
modify status for users to see by sending an updated Pod kind to the server to
the “/pods/<name>/status” endpoint - the alternate endpoint allows
different rules to be applied to the update, and access to be appropriately
restricted./scale
: Used to read and write the count of a resource in a manner that
is independent of the specific resource schema.Two additional subresources, proxy
and portforward
, provide access to
cluster resources as described in
accessing the cluster.
The standard REST verbs (defined below) MUST return singular JSON objects. Some API endpoints may deviate from the strict REST pattern and return resources that are not singular JSON objects, such as streams of JSON objects or unstructured text log data.
A common set of “meta” API objects are used across all API groups and are
thus considered part of the server group named meta.k8s.io
. These types may
evolve independent of the API group that uses them and API servers may allow
them to be addressed in their generic form. Examples are ListOptions
,
DeleteOptions
, List
, Status
, WatchEvent
, and Scale
. For historical
reasons these types are part of each existing API group. Generic tools like
quota, garbage collection, autoscalers, and generic clients like kubectl
leverage these types to define consistent behavior across different resource
types, like the interfaces in programming languages.
The term “kind” is reserved for these “top-level” API types. The term “type” should be used for distinguishing sub-categories within objects or subobjects.
All JSON objects returned by an API MUST have the following fields:
These fields are required for proper decoding of the object. They may be populated by the server by default from the specified URL path, but the client likely needs to know the values in order to construct the URL path.
Every object kind MUST have the following metadata in a nested object field called “metadata”:
Every object SHOULD have the following metadata in a nested object field called “metadata”:
Labels are intended for organizational purposes by end users (select the pods that match this label query). Annotations enable third-party automation and tooling to decorate objects with additional metadata for their own use.
By convention, the Kubernetes API makes a distinction between the specification of the desired state of an object (a nested object field called “spec”) and the status of the object at the current time (a nested object field called “status”). The specification is a complete description of the desired state, including configuration settings provided by the user, default values expanded by the system, and properties initialized or otherwise changed after creation by other ecosystem components (e.g., schedulers, auto-scalers), and is persisted in stable storage with the API object. If the specification is deleted, the object will be purged from the system. The status summarizes the current state of the object in the system, and is usually persisted with the object by an automated processes but may be generated on the fly. At some cost and perhaps some temporary degradation in behavior, the status could be reconstructed by observation if it were lost.
When a new version of an object is POSTed or PUT, the “spec” is updated and available immediately. Over time the system will work to bring the “status” into line with the “spec”. The system will drive toward the most recent “spec” regardless of previous versions of that stanza. In other words, if a value is changed from 2 to 5 in one PUT and then back down to 3 in another PUT the system is not required to ‘touch base’ at 5 before changing the “status” to 3. In other words, the system’s behavior is level-based rather than edge-based. This enables robust behavior in the presence of missed intermediate state changes.
The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. In order to facilitate level-based operation and expression of declarative configuration, fields in the specification should have declarative rather than imperative names and semantics – they represent the desired state, not actions intended to yield the desired state.
The PUT and POST verbs on objects MUST ignore the “status” values, to avoid
accidentally overwriting the status in read-modify-write scenarios. A /status
subresource MUST be provided to enable system components to update statuses of
resources they manage.
Otherwise, PUT expects the whole object to be specified. Therefore, if a field is omitted it is assumed that the client wants to clear that field’s value. The PUT verb does not accept partial updates. Modification of just part of an object may be achieved by GETting the resource, modifying part of the spec, labels, or annotations, and then PUTting it back. See concurrency control, below, regarding read-modify-write consistency when using this pattern. Some objects may expose alternative resource representations that allow mutation of the status, or performing custom actions on the object.
All objects that represent a physical resource whose state may vary from the user’s desired intent SHOULD have a “spec” and a “status”. Objects whose state cannot vary from the user’s desired intent MAY have only “spec”, and MAY rename “spec” to a more appropriate name.
Objects that contain both spec and status should not contain additional top-level fields other than the standard metadata fields.
Some objects which are not persisted in the system - such as SubjectAccessReview
and other webhook style calls - may choose to add spec and status to encapsulate
a “call and response” pattern. The spec is the request (often a request for
information) and the status is the response. For these RPC like objects the only
operation may be POST, but having a consistent schema between submission and
response reduces the complexity of these clients.
Conditions represent the latest available observations of an object’s current state. Objects may report multiple conditions, and new types of conditions may be added in the future. Therefore, conditions are represented using a list/slice, where all have similar structure.
The FooCondition
type for some resource type Foo
may include a subset of the
following fields, but must contain at least type
and status
fields:
Type FooConditionType `json:"type" description:"type of Foo condition"`
Status ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"`
// +optional
LastHeartbeatTime unversioned.Time `json:"lastHeartbeatTime,omitempty" description:"last time we got an update on a given condition"`
// +optional
LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"`
// +optional
Reason string `json:"reason,omitempty" description:"one-word CamelCase reason for the condition's last transition"`
// +optional
Message string `json:"message,omitempty" description:"human-readable message indicating details about last transition"`
Additional fields may be added in the future.
Conditions should be added to explicitly convey properties that users and components care about rather than requiring those properties to be inferred from other observations.
Condition status values may be True
, False
, or Unknown
. The absence of a
condition should be interpreted the same as Unknown
.
In general, condition values may change back and forth, but some condition transitions may be monotonic, depending on the resource and condition type. However, conditions are observations and not, themselves, state machines, nor do we define comprehensive state machines for objects, nor behaviors associated with state transitions. The system is level-based rather than edge-triggered, and should assume an Open World.
A typical oscillating condition type is Ready
, which indicates the object was
believed to be fully operational at the time it was last probed. A possible
monotonic condition could be Succeeded
. A False
status for Succeeded
would
imply failure. An object that was still active would not have a Succeeded
condition, or its status would be Unknown
.
Some resources in the v1 API contain fields called phase
, and associated
message
, reason
, and other status fields. The pattern of using phase
is
deprecated. Newer API types should use conditions instead. Phase was essentially
a state-machine enumeration field, that contradicted
system-design principles and hampered
evolution, since adding new enum values breaks backward
compatibility. Rather than encouraging clients to infer
implicit properties from phases, we intend to explicitly expose the conditions
that clients need to monitor. Conditions also have the benefit that it is
possible to create some conditions with uniform meaning across all resource
types, while still exposing others that are unique to specific resource types.
See #7856 for more details and discussion.
In condition types, and everywhere else they appear in the API, Reason
is
intended to be a one-word, CamelCase representation of the category of cause of
the current status, and Message
is intended to be a human-readable phrase
or sentence, which may contain specific details of the individual occurrence.
Reason
is intended to be used in concise output, such as one-line
kubectl get
output, and in summarizing occurrences of causes, whereas
Message
is intended to be presented to users in detailed status explanations,
such as kubectl describe
output.
Historical information status (e.g., last transition time, failure counts) is only provided with reasonable effort, and is not guaranteed to not be lost.
Status information that may be large (especially proportional in size to collections of other resources, such as lists of references to other objects – see below) and/or rapidly changing, such as resource usage, should be put into separate objects, with possibly a reference from the original object. This helps to ensure that GETs and watch remain reasonably efficient for the majority of clients, which may not need that data.
Some resources report the observedGeneration
, which is the generation
most
recently observed by the component responsible for acting upon changes to the
desired state of the resource. This can be used, for instance, to ensure that
the reported status reflects the most recent desired status.
References to loosely coupled sets of objects, such as pods overseen by a replication controller, are usually best referred to using a label selector. In order to ensure that GETs of individual objects remain bounded in time and space, these sets may be queried via separate API queries, but will not be expanded in the referring object’s status.
References to specific objects, especially specific resource versions and/or
specific fields of those objects, are specified using the ObjectReference
type
(or other types representing strict subsets of it). Unlike partial URLs, the
ObjectReference type facilitates flexible defaulting of fields from the
referring object or other contextual information.
References in the status of the referee to the referrer may be permitted, when the references are one-to-one and do not need to be frequently updated, particularly in an edge-based manner.
Discussed in #2004 and elsewhere. There are no maps of subobjects in any API objects. Instead, the convention is to use a list of subobjects containing name fields.
For example:
ports:
- name: www
containerPort: 80
vs.
ports:
www:
containerPort: 80
This rule maintains the invariant that all JSON/YAML keys are fields in API objects. The only exceptions are pure maps in the API (currently, labels, selectors, annotations, data), as opposed to sets of subobjects.
NodeConditionType
).(u)int32
or Go (u)int64
types,
not (u)int
(which is ambiguous depending on target platform). Internal
types may use (u)int
.bool
fields. Many ideas start as boolean but eventually
trend towards a small set of mutually exclusive options. Plan for future
expansions by describing the policy options explicitly as a string type
alias (e.g. TerminationMessagePolicy
).Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: “ClusterFirst”, “Pending”, “ClientIP”.
Sometimes, at most one of a set of fields can be set. For example, the
[volumes] field of a PodSpec has 17 different volume type-specific fields, such
as nfs
and iscsi
. All fields in the set should be
Optional.
Sometimes, when a new type is created, the api designer may anticipate that a union will be needed in the future, even if only one field is allowed initially. In this case, be sure to make the field Optional optional. In the validation, you may still return an error if the sole field is unset. Do not set a default value for that field.
Every list or simple kind SHOULD have the following metadata in a nested object field called “metadata”:
Every simple kind returned by the server, and any simple kind sent to the server that must support idempotency or optimistic concurrency should return this value. Since simple resources are often used as input alternate actions that modify objects, the resource version of the simple resource should correspond to the resource version of the object.
An API may represent a single entity in different ways for different clients, or transform an object after certain transitions in the system occur. In these cases, one request object may have two representations available as different resources, or different kinds.
An example is a Service, which represents the intent of the user to group a set of pods with common behavior on common ports. When Kubernetes detects a pod matches the service selector, the IP address and port of the pod are added to an Endpoints resource for that Service. The Endpoints resource exists only if the Service exists, but exposes only the IPs and ports of the selected pods. The full service is represented by two distinct resources - under the original Service resource the user created, as well as in the Endpoints resource.
As another example, a “pod status” resource may accept a PUT with the “pod” kind, with different rules about what fields may be changed.
Future versions of Kubernetes may allow alternative encodings of objects beyond JSON.
API resources should use the traditional REST pattern:
The API supports three different PATCH operations, determined by their corresponding Content-Type header:
Content-Type: application/json-patch+json
{"op": "add",
"path": "/a/b/c", "value": [ "foo", "bar" ]}
. For more details on how to use
JSON Patch, see the RFC.Content-Type: application/merge-patch+json
Content-Type: application/strategic-merge-patch+json
Details of Strategic Merge Patch are covered here.
All compatible Kubernetes APIs MUST support “name idempotency” and respond with an HTTP status code 409 when a request is made to POST an object that has the same name as an existing object in the system. See the identifiers docs for details.
Names generated by the system may be requested using metadata.generateName
.
GenerateName indicates that the name should be made unique by the server prior
to persisting it. A non-empty value for the field indicates the name will be
made unique (and the name returned to the client will be different than the name
passed). The value of this field will be combined with a unique suffix on the
server if the Name field has not been provided. The provided value must be valid
within the rules for Name, and may be truncated by the length of the suffix
required to make the value unique on the server. If this field is specified, and
Name is not present, the server will NOT return a 409 if the generated name
exists - instead, it will either return 201 Created or 504 with Reason
ServerTimeout
indicating a unique name could not be found in the time
allotted, and the client should retry (optionally after the time indicated in
the Retry-After header).
Fields must be either optional or required.
Optional fields have the following properties:
+optional
comment tag in Go.bool *awesomeFlag
) or
have a built-in nil
value (e.g. maps and slices).In most cases, optional fields should also have the omitempty
struct tag (the
omitempty
option specifies that the field should be omitted from the json
encoding if the field has an empty value). However, If you want to have
different logic for an optional field which is not provided vs. provided with
empty values, do not use omitempty
(e.g. https://github.com/kubernetes/kubernetes/issues/34641).
Note that for backward compatibility, any field that has the omitempty
struct
tag will considered to be optional but this may change in future and having
the +optional
comment tag is highly recommended.
Required fields have the opposite properties, namely:
+optional
comment tag.omitempty
struct tag.bool otherFlag
).Using the +optional
or the omitempty
tag causes OpenAPI documentation to
reflect that the field is optional.
Using a pointer allows distinguishing unset from the zero value for that type. There are some cases where, in principle, a pointer is not needed for an optional field since the zero value is forbidden, and thus implies unset. There are examples of this in the codebase. However:
Therefore, we ask that pointers always be used with optional fields that do not
have a built-in nil
value.
Default resource values are API version-specific, and they are applied during
the conversion from API-versioned declarative configuration to internal objects
representing the desired state (Spec
) of the resource. Subsequent GETs of the
resource will include the default values explicitly.
Incorporating the default values into the Spec
ensures that Spec
depicts the
full desired state so that it is easier for the system to determine how to
achieve the state, and for the user to know what to anticipate.
API version-specific default values are set by the API server.
Late initialization is when resource fields are set by a system controller after an object is created/updated.
For example, the scheduler sets the pod.spec.nodeName
field after the pod is
created.
Late-initializers should only make the following types of modifications:
- Setting previously unset fields
- Adding keys to maps
- Adding values to arrays which have mergeable semantics
(patchStrategy:"merge"
attribute in the type definition).
These conventions: 1. allow a user (with sufficient privilege) to override any system-default behaviors by setting the fields that would otherwise have been defaulted. 1. enables updates from users to be merged with changes made during late initialization, using strategic merge patch, as opposed to clobbering the change. 1. allow the component which does the late-initialization to use strategic merge patch, which facilitates composition and concurrency of such components.
Although the apiserver Admission Control stage acts prior to object creation, Admission Control plugins should follow the Late Initialization conventions too, to allow their implementation to be later moved to a ‘controller’, or to client libraries.
Kubernetes leverages the concept of resource versions to achieve optimistic concurrency. All Kubernetes resources have a “resourceVersion” field as part of their metadata. This resourceVersion is a string that identifies the internal version of an object that can be used by clients to determine when objects have changed. When a record is about to be updated, it’s version is checked against a pre-saved value, and if it doesn’t match, the update fails with a StatusConflict (HTTP status code 409).
The resourceVersion is changed by the server every time an object is modified. If resourceVersion is included with the PUT operation the system will verify that there have not been other successful mutations to the resource during a read/modify/write cycle, by verifying that the current value of resourceVersion matches the specified value.
The resourceVersion is currently backed by etcd’s modifiedIndex. However, it’s important to note that the application should not rely on the implementation details of the versioning system maintained by Kubernetes. We may change the implementation of resourceVersion in the future, such as to change it to a timestamp or per-object counter.
The only way for a client to know the expected value of resourceVersion is to have received it from the server in response to a prior operation, typically a GET. This value MUST be treated as opaque by clients and passed unmodified back to the server. Clients should not assume that the resource version has meaning across namespaces, different kinds of resources, or different servers. Currently, the value of resourceVersion is set to match etcd’s sequencer. You could think of it as a logical clock the API server can use to order requests. However, we expect the implementation of resourceVersion to change in the future, such as in the case we shard the state by kind and/or namespace, or port to another storage system.
In the case of a conflict, the correct client action at this point is to GET the resource again, apply the changes afresh, and try submitting again. This mechanism can be used to prevent races like the following:
Client #1 Client #2
GET Foo GET Foo
Set Foo.Bar = "one" Set Foo.Baz = "two"
PUT Foo PUT Foo
When these sequences occur in parallel, either the change to Foo.Bar or the change to Foo.Baz can be lost.
On the other hand, when specifying the resourceVersion, one of the PUTs will fail, since whichever write succeeds changes the resourceVersion for Foo.
resourceVersion may be used as a precondition for other operations (e.g., GET, DELETE) in the future, such as for read-after-write consistency in the presence of caching.
“Watch” operations specify resourceVersion using a query parameter. It is used to specify the point at which to begin watching the specified resources. This may be used to ensure that no mutations are missed between a GET of a resource (or list of resources) and a subsequent Watch, even if the current version of the resource is more recent. This is currently the main reason that list operations (GET on a collection) return resourceVersion.
APIs may return alternative representations of any resource in response to an Accept header or under alternative endpoints, but the default serialization for input and output of API responses MUST be JSON.
A protobuf encoding is also accepted for built-in resources. As proto is not self-describing, there is an envelope wrapper which describes the type of the contents.
All dates should be serialized as RFC3339 strings.
Units must either be explicit in the field name (e.g., timeoutSeconds
), or
must be specified as part of the value (e.g., resource.Quantity
). Which
approach is preferred is TBD, though currently we use the fooSeconds
convention for durations.
Duration fields must be represented as integer fields with units being
part of the field name (e.g. leaseDurationSeconds
). We don’t use Duration
in the API since that would require clients to implement go-compatible parsing.
Some APIs may need to identify which field in a JSON object is invalid, or to
reference a value to extract from a separate resource. The current
recommendation is to use standard JavaScript syntax for accessing that field,
assuming the JSON object was transformed into a JavaScript object, without the
leading dot, such as metadata.name
.
Examples:
fields[1].state.current
Object references should either be called fooName
if referring to an object of
kind Foo
by just the name (within the current namespace, if a namespaced
resource), or should be called fooRef
, and should contain a subset of the
fields of the ObjectReference
type.
TODO: Plugins, extensions, nested kinds, headers
The server will respond with HTTP status codes that match the HTTP spec. See the section below for a breakdown of the types of status codes the server will send.
The following HTTP status codes may be returned by the API.
200 StatusOK
201 StatusCreated
204 StatusNoContent
307 StatusTemporaryRedirect
400 StatusBadRequest
401 StatusUnauthorized
403 StatusForbidden
404 StatusNotFound
405 StatusMethodNotAllowed
409 StatusConflict
Conflict
from the status
response section below on how to
retrieve more information about the nature of the conflict.ResourceVersion
).410 StatusGone
422 StatusUnprocessableEntity
429 StatusTooManyRequests
Retry-After
HTTP header from the response, and wait at least
that long before retrying.500 StatusInternalServerError
503 StatusServiceUnavailable
504 StatusServerTimeout
Kubernetes will always return the Status
kind from any API endpoint when an
error occurs. Clients SHOULD handle these types of objects when appropriate.
A Status
kind will be returned by the API in two cases:
* When an operation is not successful (i.e. when the server would return a non
2xx HTTP status code).
* When a HTTP DELETE
call is successful.
The status object is encoded as JSON and provided as the body of the response. The status object contains fields for humans and machine consumers of the API to get more detailed information for the cause of the failure. The information in the status object supplements, but does not override, the HTTP status code’s meaning. When fields in the status object have the same meaning as generally defined HTTP headers and that header is returned with the response, the header should be considered as having higher priority.
Example:
$ curl -v -k -H "Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc" https://<IP_ADDRESS>:443/api/v1/namespaces/default/pods/grafana
> GET /api/v1/namespaces/default/pods/grafana HTTP/1.1
> User-Agent: curl/7.26.0
> Host: <IP_ADDRESS>
> Accept: */*
> Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc
>
< HTTP/1.1 404 Not Found
< Content-Type: application/json
< Date: Wed, 20 May 2015 18:10:42 GMT
< Content-Length: 232
<
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods \"grafana\" not found",
"reason": "NotFound",
"details": {
"name": "grafana",
"kind": "pods"
},
"code": 404
}
status
field contains one of two possible values:
* Success
* Failure
message
may contain human-readable description of the error
reason
may contain a machine-readable, one-word, CamelCase description of why
this operation is in the Failure
status. If this value is empty there is no
information available. The reason
clarifies an HTTP status code but does not
override it.
details
may contain extended data associated with the reason. Each reason may
define its own extended details. This field is optional and the data returned is
not guaranteed to conform to any schema except that defined by the reason type.
Possible values for the reason
and details
fields:
* BadRequest
* Indicates that the request itself was invalid, because the request doesn’t
make any sense, for example deleting a read-only object.
* This is different than status reason
Invalid
above which indicates that
the API call could possibly succeed, but the data was invalid.
* API calls that return BadRequest can never succeed.
* Http status code: 400 StatusBadRequest
Unauthorized
kind string
name string
401 StatusUnauthorized
Forbidden
kind string
name string
403 StatusForbidden
NotFound
kind string
name string
404 StatusNotFound
AlreadyExists
kind string
name string
409 StatusConflict
Conflict
409 StatusConflict
Invalid
kind string
name string
causes
StatusCause
entries indicating the data in the provided
resource that was invalid. The reason
, message
, and field
attributes will
be set.422 StatusUnprocessableEntity
Timeout
429 TooManyRequests
Retry-After
HTTP header and return
retryAfterSeconds
in the details field of the object. A value of 0
is the
default.ServerTimeout
kind string
name string
Retry-After
HTTP header and return
retryAfterSeconds
in the details field of the object. A value of 0
is the
default.504 StatusServerTimeout
MethodNotAllowed
405 StatusMethodNotAllowed
InternalError
causes
500 StatusInternalServerError
code
may contain the suggested HTTP return code for this status.Events are complementary to status information, since they can provide some historical information about status and occurrences in addition to current or previous status. Generate events for situations users or administrators should be alerted about.
Choose a unique, specific, short, CamelCase reason for each event category. For
example, FreeDiskSpaceInvalid
is a good event reason because it is likely to
refer to just one situation, but Started
is not a good reason because it
doesn’t sufficiently indicate what started, even when combined with other event
fields.
Error creating foo
or Error creating foo %s
would be appropriate for an
event message, with the latter being preferable, since it is more informational.
Accumulate repeated events in the client, especially for frequent events, to reduce data volume, load on the system, and noise exposed to users.
Node
where referring to
the node resource in the context of the cluster. Use Host
where referring to
properties of the individual physical/virtual system, such as hostname
,
hostPath
, hostNetwork
, etc.FooController
is a deprecated kind naming convention. Name the kind after
the thing being controlled instead (e.g., Job
rather than JobController
).something
occurs should
be called somethingTime
. Do not use stamp
(e.g., creationTimestamp
).fooSeconds
convention for durations, as discussed in the units
subsection.
fooPeriodSeconds
is preferred for periodic intervals and other waiting
periods (e.g., over fooIntervalSeconds
).fooTimeoutSeconds
is preferred for inactivity/unresponsiveness deadlines.fooDeadlineSeconds
is preferred for activity completion deadlines.Foo
by name should
be called fooName
. The name of a field referring to another resource of kind
Foo
by ObjectReference (or subset thereof) should be called fooRef
.Fooable
, not IsFooable
.kube-
prefix is reserved for Kubernetes system namespaces, e.g. kube-system
and kube-public
.Labels are the domain of users. They are intended to facilitate organization and management of API resources using attributes that are meaningful to users, as opposed to meaningful to the system. Think of them as user-created mp3 or email inbox labels, as opposed to the directory structure used by a program to store its data. The former enables the user to apply an arbitrary ontology, whereas the latter is implementation-centric and inflexible. Users will use labels to select resources to operate on, display label values in CLI/UI columns, etc. Users should always retain full power and flexibility over the label schemas they apply to labels in their namespaces.
However, we should support conveniences for common cases by default. For example, what we now do in ReplicationController is automatically set the RC’s selector and labels to the labels in the pod template by default, if they are not already set. That ensures that the selector will match the template, and that the RC can be managed using the same labels as the pods it creates. Note that once we generalize selectors, it won’t necessarily be possible to unambiguously generate labels that match an arbitrary selector.
If the user wants to apply additional labels to the pods that it doesn’t select upon, such as to facilitate adoption of pods or in the expectation that some label values will change, they can set the selector to a subset of the pod labels. Similarly, the RC’s labels could be initialized to a subset of the pod template’s labels, or could include additional/different labels.
For disciplined users managing resources within their own namespaces, it’s not that hard to consistently apply schemas that ensure uniqueness. One just needs to ensure that at least one value of some label key in common differs compared to all other comparable resources. We could/should provide a verification tool to check that. However, development of conventions similar to the examples in Labels make uniqueness straightforward. Furthermore, relatively narrowly used namespaces (e.g., per environment, per application) can be used to reduce the set of resources that could potentially cause overlap.
In cases where users could be running misc. examples with inconsistent schemas, or where tooling or components need to programmatically generate new objects to be selected, there needs to be a straightforward way to generate unique label sets. A simple way to ensure uniqueness of the set is to ensure uniqueness of a single label value, such as by using a resource name, uid, resource hash, or generation number.
Problems with uids and hashes, however, include that they have no semantic meaning to the user, are not memorable nor readily recognizable, and are not predictable. Lack of predictability obstructs use cases such as creation of a replication controller from a pod, such as people want to do when exploring the system, bootstrapping a self-hosted cluster, or deletion and re-creation of a new RC that adopts the pods of the previous one, such as to rename it. Generation numbers are more predictable and much clearer, assuming there is a logical sequence. Fortunately, for deployments that’s the case. For jobs, use of creation timestamps is common internally. Users should always be able to turn off auto-generation, in order to permit some of the scenarios described above. Note that auto-generated labels will also become one more field that needs to be stripped out when cloning a resource, within a namespace, in a new namespace, in a new cluster, etc., and will need to be ignored around when updating a resource via patch or read-modify-write sequence.
Inclusion of a system prefix in a label key is fairly hostile to UX. A prefix is only necessary in the case that the user cannot choose the label key, in order to avoid collisions with user-defined labels. However, I firmly believe that the user should always be allowed to select the label keys to use on their resources, so it should always be possible to override default label keys.
Therefore, resources supporting auto-generation of unique labels should have a
uniqueLabelKey
field, so that the user could specify the key if they wanted
to, but if unspecified, it could be set by default, such as to the resource
type, like job, deployment, or replicationController. The value would need to be
at least spatially unique, and perhaps temporally unique in the case of job.
Annotations have very different intended usage from labels. We expect them to be primarily generated and consumed by tooling and system extensions. I’m inclined to generalize annotations to permit them to directly store arbitrary json. Rigid names and name prefixes make sense, since they are analogous to API fields.
In fact, in-development API fields, including those used to represent fields of
newer alpha/beta API versions in the older stable storage version, may be
represented as annotations with the form something.alpha.kubernetes.io/name
or
something.beta.kubernetes.io/name
(depending on our confidence in it). For
example net.alpha.kubernetes.io/policy
might represent an experimental network
policy field. The “name” portion of the annotation should follow the below
conventions for annotations. When an annotation gets promoted to a field, the
name transformation should then be mechanical: foo-bar
becomes fooBar
.
Other advice regarding use of labels, annotations, taints, and other generic map keys by
Kubernetes components and tools:
- Key names should be all lowercase, with words separated by dashes instead of camelCase
- For instance, prefer foo.kubernetes.io/foo-bar
over foo.kubernetes.io/fooBar
, prefer
desired-replicas
over DesiredReplicas
- Prefix the key with kubernetes.io/
or foo.kubernetes.io/
, preferably the
latter if the label/annotation is specific to foo
- For instance, prefer service-account.kubernetes.io/name
over
kubernetes.io/service-account.name
- Use annotations to store API extensions that the controller responsible for
the resource doesn’t need to know about, experimental fields that aren’t
intended to be generally used API fields, etc. Beware that annotations aren’t
automatically handled by the API conversion machinery.
Some of the API operations exposed by Kubernetes involve transfer of binary streams between the client and a container, including attach, exec, portforward, and logging. The API therefore exposes certain operations over upgradeable HTTP connections (described in RFC 2817) via the WebSocket and SPDY protocols. These actions are exposed as subresources with their associated verbs (exec, log, attach, and portforward) and are requested via a GET (to support JavaScript in a browser) and POST (semantically accurate).
There are two primary protocols in use today:
Streamed channels
When dealing with multiple independent binary streams of data such as the remote execution of a shell command (writing to STDIN, reading from STDOUT and STDERR) or forwarding multiple ports the streams can be multiplexed onto a single TCP connection. Kubernetes supports a SPDY based framing protocol that leverages SPDY channels and a WebSocket framing protocol that multiplexes multiple channels onto the same stream by prefixing each binary chunk with a byte indicating its channel. The WebSocket protocol supports an optional subprotocol that handles base64-encoded bytes from the client and returns base64-encoded bytes from the server and character based channel prefixes (‘0’, ‘1’, ‘2’) for ease of use from JavaScript in a browser.
Streaming response
The default log output for a channel of streaming data is an HTTP Chunked Transfer-Encoding, which can return an arbitrary stream of binary data from the server. Browser-based JavaScript is limited in its ability to access the raw data from a chunked response, especially when very large amounts of logs are returned, and in future API calls it may be desirable to transfer large files. The streaming API endpoints support an optional WebSocket upgrade that provides a unidirectional channel from the server to the client and chunks data as binary WebSocket frames. An optional WebSocket subprotocol is exposed that base64 encodes the stream before returning it to the client.
Clients should use the SPDY protocols if their clients have native support, or WebSockets as a fallback. Note that WebSockets is susceptible to Head-of-Line blocking and so clients must read and process each message sequentially. In the future, an HTTP/2 implementation will be exposed that deprecates SPDY.
API objects are validated upon receipt by the apiserver. Validation errors are
flagged and returned to the caller in a Failure
status with reason
set to
Invalid
. In order to facilitate consistent error messages, we ask that
validation logic adheres to the following guidelines whenever possible (though
exceptional cases will exist).
name
may be
specified”.request
”.


Dev Bootcamp Learning Blog
Home
About
Contact
Follow me on:
Blog Archive:
January 7, 2016
February
March
April


{% extends "global/Page.html" %} {% load otree %} {% block title %} Introduction {% endblock %} {% block content %}
Thank you for participating in this study. The entire study should take approximately 45 minutes. It will include a few demographic questions and some activities where you will have to write. Please press "Next" to continue.
{% next_button %} {{ form.errors }} {% endblock %}


18 year old lad from Bruton, a little town in the countryside located in Somerset.
Working at Bath Spa Uni as a SITS Apprentice training to become a SITS Developer.
I have a blog post which I am adding to when I complete tasks and milestones throughout the apprenticeship. Feel free to give it a look!
http://softwaredevelopblog.blogspot.co.uk/
Thank you for viewing my webpage and finding out a little about me and who I am.


Take class with us and get your weekly fix of dancing!
We offer all levels and styles of hip-hop choreography taught by our talented choreographers from the crew. Whether you are a seasoned dancer or a complete beginner, you are more than welcome to join in. Classes are offered on a drop-in basis and each week we teach something new so you can join at any time. Everyone is welcome here and we love having new people come to take classes with us.
Most of our classes take place either in Union Dining Hall (UDH), Activity Space 2 or Metric, which are all in the Union building, Beit Quad. (Union map)
Peep at our timetable below to see where and when our classes happen!
No such thing as a fashion faux pas in our classes, wear anything comfortable


AWS::SupportApp::SlackChannelConfiguration
You can use the AWS::SupportApp::SlackChannelConfiguration
resource to
specify your AWS account when you configure the AWS Support App. This resource includes the following information:
-
The Slack channel name and ID
-
The team ID in Slack
-
The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role
-
Whether you want the AWS Support App to notify you when your support cases are created, updated, resolved, or reopened
-
The case severity that you want to get notified for
For more information, see the following topics in the AWS Support User Guide:
Syntax
To declare this entity in your AWS CloudFormation template, use the following syntax:
JSON
{ "Type" : "AWS::SupportApp::SlackChannelConfiguration", "Properties" : { "ChannelId" :
String
, "ChannelName" :String
, "ChannelRoleArn" :String
, "NotifyOnAddCorrespondenceToCase" :Boolean
, "NotifyOnCaseSeverity" :String
, "NotifyOnCreateOrReopenCase" :Boolean
, "NotifyOnResolveCase" :Boolean
, "TeamId" :String
} }
YAML
Type: AWS::SupportApp::SlackChannelConfiguration Properties: ChannelId:
String
ChannelName:String
ChannelRoleArn:String
NotifyOnAddCorrespondenceToCase:Boolean
NotifyOnCaseSeverity:String
NotifyOnCreateOrReopenCase:Boolean
NotifyOnResolveCase:Boolean
TeamId:String
Properties
ChannelId
-
The channel ID in Slack. This ID identifies a channel within a Slack workspace.
Required: Yes
Type: String
Update requires: Replacement
ChannelName
-
The channel name in Slack. This is the channel where you invite the AWS Support App.
Required: No
Type: String
Update requires: No interruption
ChannelRoleArn
-
The Amazon Resource Name (ARN) of the IAM role for this Slack channel configuration. The AWS Support App uses this role to perform AWS Support and Service Quotas actions on your behalf.
Required: Yes
Type: String
Update requires: No interruption
NotifyOnAddCorrespondenceToCase
-
Whether to get notified when a correspondence is added to your support cases.
Required: No
Type: Boolean
Update requires: No interruption
NotifyOnCaseSeverity
-
The case severity for your support cases that you want to receive notifications. You can specify
none
,all
, orhigh
.Required: Yes
Type: String
Update requires: No interruption
NotifyOnCreateOrReopenCase
-
Whether to get notified when your support cases are created or reopened
Required: No
Type: Boolean
Update requires: No interruption
NotifyOnResolveCase
-
Whether to get notified when your support cases are resolved.
Required: No
Type: Boolean
Update requires: No interruption
TeamId
-
The team ID in Slack. This ID uniquely identifies a Slack workspace.
Required: Yes
Type: String
Update requires: Replacement
Examples
The following examples can help you create AWS Support App resources using CloudFormation.
Example
Use this template to create a Slack channel configuration and IAM role for your account or your organization. You must replace the Slack workspace and channel IDs.
JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Example stack to create a Slack channel configuration", "Resources": { "SlackChannelConfiguration": { "Type": "AWS::SupportApp::SlackChannelConfiguration", "Properties": { "TeamId": "T012ABCDEFG", "ChannelId": "C01234A5BCD", "ChannelName": "cloudformationtemplatechannel", "NotifyOnCreateOrReopenCase": true, "NotifyOnAddCorrespondenceToCase": false, "NotifyOnResolveCase": true, "NotifyOnCaseSeverity": "high", "ChannelRoleArn": {"Fn::GetAtt" : ["AWSSupportSlackAppCFNRole", "Arn"] } } }, "AWSSupportSlackAppCFNRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "supportapp.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AWSSupportAppFullAccess" ] } } } }
YAML
AWSTemplateFormatVersion: '2010-09-09' Description: Example stack to create a Slack channel configuration Resources: SlackChannelConfiguration: Type: AWS::SupportApp::SlackChannelConfiguration Properties: TeamId: T012ABCDEFG ChannelId: C01234A5BCD ChannelName: cfntemplatechannel NotifyOnCreateOrReopenCase: true NotifyOnAddCorrespondenceToCase: false NotifyOnResolveCase: true NotifyOnCaseSeverity: high ChannelRoleArn: !GetAtt 'AWSSupportSlackAppCFNRole.Arn' AWSSupportSlackAppCFNRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - supportapp.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSSupportAppFullAccess


--- layout: post status: publish published: true title: Maven / Scala / Vim Setup author: display_name: ian login: ian email<EMAIL_ADDRESS>url: http://iancwill.com/blog author_login: ian author_email<EMAIL_ADDRESS>author_url: http://iancwill.com/blog wordpress_id: 175 wordpress_url: http://iancwill.com/blog/?p=175 date: '2014-06-04 22:47:00 -0600' date_gmt: '2014-06-05 02:47:00 -0600' ---
I'm looking to learn two things at once. Scala and the CMU Sphinx library for speech to text. My maven and vim chops get brushed up along the way.
To generate a scala maven project (nice!):
mvn archetype:generate
This enters interactive mode, the first step is to choose your archetype. I chose org.scala-tools.archetypes:scala-archetype-simple (option 939), then chose version 1.3 and answered some other questions about project name and package. This popped out a folder with a pom and a couple initial scala files / tests. Nice!
Step two is getting scala syntax highlighting on. I have been using maximum awesome to manage my vim profile, so I added
Bundle 'derekwyatt/vim-scala'
to the bottom of my maximum-awesome/vimrc.bundles file and range :BundleInstall from inside of mvim. It took me a little while to realize I needed to Apple-Quit MacVim instead of just closing all windows. When I did that, mvim came back up with scala syntax properly highlighted. Nice!
Now to learn scala. But first, an application....
CMU Sphinx (http://cmusphinx.sourceforge.net/wiki/tutorialsphinx4) has some maven stuff. I'll see if I can hook that into my scala maven project and use the java libraries in a cool new language.
My first attempt I get "peer not authenticated" which later turned into "ava.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty." How lame. Installing some random Apple Java update fixed the issue (http://support.apple.com/kb/DL1572), thanks KiwiMartin from stack overflow! (https://stackoverflow.com/questions/6784463/error-trustanchors-parameter-must-be-non-empty/19680689#19680689). After installing that, mvm compile downloads the jars from sonatype.
Nice! I seem to be able to import classes from edu.cmu.sphinx.api. Now to learn some scala (http://www.scala-lang.org/docu/files/ScalaTutorial.pdf). Here's what I'm rocking so far: https://github.com/iancw/scala-sphinx.


Current and future weather
Search
Look up another city
Look up another city
Look up another city
Look up another city


This is where we sit down, grab a cup of coffee and dial in the details. Understanding the task at hand and ironing out the wrinkles is a key point.
This is where we sit down, grab a cup of coffee and dial in the details. Understanding the task at hand and ironing out the wrinkles is a key point.


13+ years of experience in IT industry with successful track record of implementing innovative solutions to business problems through various stages of Software Development Life Cycle.
Expert in translating business requirements into technical solutions using object oriented design techniques and fanatical about quality & usability. Hands on experience in developing scalable, secure, public facing Internet scale web applications.
Has excellent communication, presentation, interpersonal and leadership skills with experience in direct client interaction. Self-Motivated and consistent High Performer.
C#, JavaScript, Web Architecture, Object Oriented Analysis & Design, .NET, ASP.NET Web Forms, ASP.NET MVC, Web API, WCF, jQuery, Entity Framework, Web Services, OWASP, Knockout JS, Angular JS, Bootstrap
Requirement Analysis, Application Design & Development, Team management
Fx-Cop, Fiddler, Log Parser, YSlow, Page speed, SOAP UI, Fortify, Team Foundation Server (TFS), Git, SVN


--- layout: page title: Portfolio subtitle: A selection of cool stuff I've worked on. description: Project portfolio for Data Science and Software projects I've worked on. ---
A statistical and textual analysis on the Nigerian constitution .
Statistical and acoustic analysis, including visualizations, for the samples from 10 classes of english speakers from the speech accent archive.
Project for The Art and Data Science fellowship.
Analyzing customer spending data using Unsupervised Learning techniques for discovering internal structure, patterns and knowledge.
Cross language information retrieval system (CLIR) which, given a query in German, searches text documents written in English using Natural Language Processing.
Designing and implementing deep learning models to predict the sentiment of a phrase from the Rotten Tomatoes movie review dataset.


{{text}}
It's cold inside. It's freezing inside. In a certain corner of my mind, I found myself curled up on the side of the high way, snow accumulating on the ground and on my body as I sighed my last breath: the bits of warmth turning into cystals of ice.  The windshield of the car is stained with blood, my blood. The eyes were indifferent, because on a cold, grey side of the highway, an injured doe is as good as dead.
The car drove away.
Limbo is the edge, the border, the in-between. Who would have thought heaven and hell, life and death, concious and dream all had such a blurry line of separation? So blurry that one can find an entire world of trapped souls in limbo.
The exit glows green over my head. I open the door but found myself stepping into another room that looks exactly the same I was just in. Except there is a window! I pushed open the window and climbed onto a balcony that apparently only looks over the floor of a bigger room with arched roofs. I complained: "Why is it called an exit when I could only travel from one inside to another inside?" Soon, I'll learn to forget an "outside" with blue skys ever existed. Through these doors I will enter deeper and deeper into the belly of the beast.


Incredible – just today I was asking myself the question: How do you
take the “Blog” out of WordPress! Found a few blank WP themes and
learned a lot about the files in a WP-theme, almost half of the code was
about the Blog and I don’t need it. Also found the new 2012-theme and
read about how they created it; it is imposible for me to strip the
unnecessary features out, or even to redesign the theme to look like my
design. I will give this a try. Thank you.
Incredible – just today I was asking myself the question: How do you take the “Blog” out of WordPress! Found a few blank WP themes and learned a lot about the files in a WP-theme, almost half of the code was about the Blog and I don’t need it. Also found the new 2012-theme and read about how they created it; it is imposible for me to strip the unnecessary features out, or even to redesign the theme to look like my design. I will give this a try. Thank you.


🔊 PODCAST | NiE - When children dream big
by AdminLike every other child has a dream, today we are discussing what inspires children into wishing to become a doctor, pilot, engineer, etc.
Like every other child has a dream, today we are discussing what inspires children into wishing to become a doctor, pilot, engineer, etc.


Protocols
The following protocols are available globally.
-
Defines the protocol which all query components must implement. Each query component should be able to return its representation as a String.
See moreDeclaration
Swift
public protocol Buildable
-
A protocol defining functions database plugins must implement to build a string representation of a Column
See moreDeclaration
Swift
public protocol ColumnCreator
-
Defines the protocol which all database plugins must implement.
See moreDeclaration
Swift
public protocol Connection: AnyObject
-
Defines the protocol which should be used for all filtering clauses. Represents a filter as String value.
Declaration
Swift
public protocol QueryFilterProtocol: Buildable
-
Defines the protocol which should be used for all HAVING clauses. Represents a HAVING clause as String value.
Declaration
Swift
public protocol QueryHavingProtocol: Buildable
-
A protocol for columns used in indices.
See moreDeclaration
Swift
public protocol IndexColumn
-
A protocol for database specific prepared statements to implement.
Declaration
Swift
public protocol PreparedStatement
-
Defines the protocol which should be used for all suffix clauses.
Declaration
Swift
public protocol QuerySuffixProtocol: Buildable
-
A protocol for retrieving query results. All database plugins must implement this protocol.
See moreDeclaration
Swift
public protocol ResultFetcher
-
Defines the protocol for data types to be used as table column types.
See moreDeclaration
Swift
public protocol SQLDataType


800-555-5555
Resources
About Us
Blog
Product 1
Product 2
Product 3
Product 4
Product 5
Product 6
Contact
Home
>
Products
>
Page Title
Location
6 am
7 am
8 am
9 am
10 am
11 am
12 pm
1 pm
2 pm
3 pm
4 pm
5 pm
6 pm
7 pm
8 pm
Total
Add a Location
Store Name ::
Minimum ::
customers per hour
Maximum ::
customers per hour
Average Cookies Bought ::
cookies per customer


In this application, the goal is to assess the risk associated with potentially insuring you as a new health insurance customer. This can be done using a variety of variables, however, we have gathered some in the questions below.
Please answer each question honestly to realistically assess your risk.
Reminder: For the variables chosen, the highest possible score is 235. To be determined as insurable, you must score 75 or below.


Graham Cracker Crust
A simple graham cracker crust, perfect for cheesecakes or tarts.
Ingredients
-
2 cups graham cracker crumbs6 tbs butter (melted)1/3 cup white sugar1 tsp cinnamon
Directions
-
pulse graham cracker in food processor or use muddler to crumb in bowlcombine melted butter, graham cracker crumbs, sugar, and cinnamon in a bowlpress into pan, forming into crust shape


Preparation time
less than 30 mins
Cooking time
10 to 30 mins
Serves
Serves 1
For the chargrilled prawns, rub the prawns in the oil and season well with salt and freshly ground black pepper.
Heat a griddle pan until it is smoking hot. Add the prawns to the pan and fry for three minutes or until coloured and cooked through.
For the crunchy nut dressing. Place the soy sauce, lime juice and sugar into a small saucepan.
Grate the ginger onto the centre of a clean jay cloth or muslin. Wrap the jay cloth or muslin around the ginger and squeeze the juice through the material into the saucepan.
Cook the mixture over a medium heat for five minutes.
Add the cashew nuts, spring onion, mint and coriander to the saucepan and mix well. Then pour the mixture into a clean bowl.
For the egg fried rice, heat the oil in a wok until smoking hot. Add the spring onions to the wok and cook for three minutes. Add the cooked rice and cook for one minute.
Add the egg to the wok and stir quickly.
Add the rest of the egg fried rice ingredients to the wok and mix well.
Place the rice into a lightly oiled, small bowl and press the rice down into the bowl. Turn the rice out onto a clean serving plate.
For the mango salsa, place all the mango salsa ingredients in a small bowl and mix well.
To serve, place the chargrilled prawns on to the plate alongside the rice. Pour the dressing over the rice and prawns and serve with the mango salsa in a bowl on the side for dipping.


Files CCore/inc/crypton/DHExp.h CCore/src/crypton/DHExp.cpp
This tool is designed to perform the Diffie-Hellman key exchange protocol.
The abstract Diffie-Hellman protocol uses some finite group G with efficient octet representation. "Efficient" means that group operations can be performed efficiently from the octet representation of elements. Some group element g with large order is chosen also. Two peers A and B generate secret data x and y, which are long integer numbers. Then A sends gx to B and B sends gy to A. Each side can calculate gxy. This is a common secret. It cannot be figured out from intercepted data, if the task of calculation x from gx is difficult.
The simplest example of G is a multiplicative group of invertible elements of the ring Z/(p), where p is a large prime number. Two particular such numbers are well known as Diffie-Hellman Group I and Diffie-Hellman Group II primes. In both cases g is the class of 2.
template <class DHMod,class Algo=DefaultDHAlgo>
class DHExp : NoCopy
{
public:
static constexpr ulen GLen = DHMod::GLen ;
DHExp();
~DHExp();
void pow(const uint8 a[GLen],const uint8 x[GLen],uint8 ax[GLen]);
void pow(const uint8 x[GLen],uint8 gx[GLen]);
};
This class implements required functionality to use the Diffie-Hellman protocol. The first template parameter gives the group related data. The second is an Algorithm Package with required long integer algorithms.
GLen is the length of group element octet representation.
pow(a,x,ax) calculates the power of the element a in x and returns the result in ax.
pow(x,gx) calculates the power of the g in x and returns the result in gx.
In both methods x represents the unsigned number in the lendian byte order.
struct DHModI { static constexpr ulen GLen = 96 ; static const uint8 G[GLen]; static const uint8 Mod[GLen]; static const uint8 InvMod[GLen]; static const uint8 Lift[GLen]; }; struct DHModII { static constexpr ulen GLen = 128 ; static const uint8 G[GLen]; static const uint8 Mod[GLen]; static const uint8 InvMod[GLen]; static const uint8 Lift[GLen]; };
These two types can be used as the template parameter DHMod and contains all required precalculated data for Diffie-Hellman Groups I and II.
GLen is the length of the octet reprsentation of group elements. A group element is represented by the long unsigned number, using the lendian representation.
Mod is a prime module. This number is normalized, i.e. the most significant bit equals 1. D below is the power of 2, D = 28*GLen.
G is a generator.
InvMod is an inversion of Mod by module D, i.e. InvMod*Mod = 1 (mod D).
Lift is ((D-Mod)*D)/Mod.
struct Algo
{
using Unit = ??? ;
static constexpr unsigned UnitBits = ??? ;
template <ulen Len>
class MulOp : NoCopy
{
public:
MulOp();
~MulOp();
void mul(const Unit A[Len],const Unit B[Len],Unit C[2*Len]); // no overlapp
void mulHi(const Unit A[Len],const Unit B[Len],Unit C[Len]); // no overlapp
void mulLo(const Unit A[Len],const Unit B[Len],Unit C[Len]); // no overlapp
void mulLo1(const Unit A[Len],const Unit B[Len],Unit C[Len+1]); // no overlapp
void sq(const Unit A[Len],Unit B[2*Len]); // no overlapp
};
template <ulen Len>
class AddOp : NoCopy
{
public:
AddOp();
~AddOp();
bool /* borrow */ sub(const Unit A[Len],const Unit B[Len],Unit C[Len]); // no overlapp
bool /* carry */ add(const Unit A[Len],Unit B[Len]); // no overlap
bool /* borrow */ neg(Unit A[Len]);
};
};
Here is the pattern for the template parameter Algo.
Unit is the unsigned integral type, used as the long integer unit. Long integers are represented using the lendian unit order.
UnitBits is the number of bits in the Unit.
Two inner classes MulOp and AddOp are used to perform the required long integer operations. They are parametrized by the long integer length Len.
MulOp operations are:
mul() multiplies A and B and returns the result of the double length in C. No overlap C with A or B is assumed.
mulHi() multiplies A and B and returns the high part of the result in C. No overlap C with A or B is assumed.
mulLo() multiplies A and B and returns the lower part of the result in C. No overlap C with A or B is assumed.
mulLo1() multiplies A and B and returns the lower part of the result of the length Len+1 in C. No overlap C with A or B is assumed.
sq() squares A and returns the result of the double length in B. No overlap B with A is assumed.
AddOp operations are:
sub() subtracts B from A and returns the result in C. Borrow is returned. No overlap C with A or B is assumed.
add() adds A to B and returns the carry. No overlap B with A is assumed.
neg() negates A. Borrow is returned.
struct DefaultDHAlgo
{
using Algo = Math::IntegerFastAlgo;
using Unit = Algo::Unit ;
static constexpr unsigned UnitBits = Algo::UnitBits ;
template <ulen Len>
class MulOp : NoCopy
{
Unit temp[2*Len];
public:
MulOp();
~MulOp();
void mul(const Unit A[Len],const Unit B[Len],Unit C[2*Len]);
void mulHi(const Unit A[Len],const Unit B[Len],Unit C[Len]);
void mulLo(const Unit A[Len],const Unit B[Len],Unit C[Len]);
void mulLo1(const Unit A[Len],const Unit B[Len],Unit C[Len+1]);
void sq(const Unit A[Len],Unit B[2*Len]);
};
template <ulen Len>
class AddOp : NoCopy
{
public:
AddOp();
~AddOp();
bool /* borrow */ sub(const Unit A[Len],const Unit B[Len],Unit C[Len]);
bool /* carry */ add(const Unit A[Len],Unit B[Len]);
bool /* borrow */ neg(Unit A[Len]);
};
};
This is the default implementation of the Algo, based on the Math::IntegerFastAlgo package.
Concept DHExpType covers Diffie-Hellman classes like DHExp<....>.
template <class T>
concept bool DHExpType = .... ;


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/preorder.2Ecomap.html ---
Do we already have the function which given a map X -> Y and a preorder on Y, produces a preorder on X? I searched for preorder.comap and found nothing. Is that what it's supposed to be called?
You'd think this just gets synthesised automatically when preorder
is defined. :grinning:
(More seriously --- how close could we get to that happening? Can we construct derive handlers so a new structure could just be labelled with @[derive comap]
and that definition is added?)
I think it's called preorder.lift
Last updated: Apr 24 2020 at 19:02 UTC


Welcome to the HTML Portfolio Project
Dylan
Breaker of Things
More about me
Here is more information about me.
Learn more about my skills
I enjoy breaking things
HTML
BASH
C++
contact me
reach me by email
github


I can help you with anything from the initial build of a WYSIWYG site to full custom code. I enjoy building with HTML, CSS, and JavaScript, but I'm just as happy to get a WordPress site up and running on your behalf. It's not my primary skillset, but I also know my way around the Adobe suite and their alternatives in the event you'd like some photos edited for your website.
I've spent time working with C++, C#, C, Java, and Python, with most of my experience revolving around C++ and C#. I've built interfaces using WinForms and WPF with C#, QT with C++, and TKinter with Python. In addition, I've started working with MonoGame for C#. While I'm comfortable working in any of the above, I'm always willing to pick up a new language.
I've worked with Oracle and MySQL databases. I can work with an existing database or get a new one up and running. Whether you have Excel sheets that could use an upgrade or everything is kept on paper, I can get it converted into a modern database.


Example webpages using the transcoder (compiled to WASM) to render Basis/KTX2 textures in WebGL. Both demos require WebAssembly and WebGL support.


Repositions the window below the current window (or the top window if the current window is the lowest one on the screen) on the displayed buffer so that the next page of the buffer is visible in the window (where a page is a group of lines 4/5th's the size of the window).
If page-next-window is given a prefix argument, it will flip the buffer backwards a page, rather than forwards.
(parse-error-messages-in-region)
Parses the region between dot and mark for error messages (as the generated by the compile-it command) and sets up for subsequent invocations of next-error.
Passes control back to the parent process that started Emacs subprocess, using the VMS SPAWN/ATTACH commands. Emacs goes to sleep until control is passed back to it by running Emacs again. The optional DCL-command string parameter is passed to DCL and executed after Emacs pauses.
Sets the specified subprocess into VMS state SUSPENDed. This stops the process from executing. Use resume-process to start the process executing again.
This function is provided as part of the pc-keyboard package.
PC-home-key moves the cursor the start of the text on the current line unless it is already there. In which case it moves the cursor to the beginning of the line.
Switches to a buffer whose name is provided and ties that buffer to a newly-created window.
Returns the character immediately preceding dot as an integer. The null character (0) is returned if dot is at the beginning of the buffer.
A command that, when followed by a string of digits, causes that string of digits to be interpreted as a numeric prefix argument which is generally a repetition count for the following command.
For each ^U typed before a command, the current prefix argument is multiplied by 4. So ^U is 4, ^U-^U is 16 and ^U-^U-^U is 64 (and so on).
Note: prefix-argument should never be called from an MLisp function.
(prefix-argument-loop statements)
Executes statements prefix-argument times. Every function invocation is always prefixed by some argument. If no prefix argument has been provided, 1 is assumed.
(prepend-region-to-buffer buffer-name)
Prepends the region to the buffer specified. Neither the original text in the destination buffer nor the text in the region between dot and mark are disturbed.
previous-buffer-name will return the buffer that was current before the Minibuf was entered.
Returns the last command character struck. If you have a function bound to many keys, the function may use previous-command to tell which key was used to invoke it.
Take the previous error message (as returned from the compile-it command), visit the file in which the error occurred and set dot to the line on which that error occurred. The error message is displayed at the top of the window associated with the Error log buffer.
Default binding: none
See also:
(previous-line repeat-count) ^P
Moves dot to the prefix-argument times repeat-count previous line. If repeat-count is omitted 1, is assumed. previous-line attempts to keep dot at the same horizontal position as you move from line to line.
Repositions the current window on the current buffer so that the prefix-argumentth previous page of the buffer is visible in the window (where a page is a group of lines 4/5th's the size of the window). If possible, dot is kept where it is, otherwise it is moved to the middle of the new page.
Switches to the window (and associated buffer) that is above the current window. If there is no window above the current window, then the bottom window is used.
Prints the value of the named variable. Use this command when you want to inquire about the setting of a variable.
Prints the default value of the named variable. Use this command when you want to inquire about the default setting of a variable.
Unix only.
Return the process id of the named process.
Causes a key sequence to be read using the provided keymap, and then executes the selected function. It returns the value returned by the selected function.
Returns the next line of output from the specified subprocess. This function is typically used in an MLisp procedure specified using the set-process-output-procedure command.
Unix only.
Returns the status of the named process:
- -1 - not an active process
- 0 - a stopped process
- 1 - a running process
(progn local-declarations... expression ...)
Evaluates the expressions and returns the value of the last expression evaluated. progn is roughly equivalent to a compound statement (begin-end block) in more conventional programming languages.
(provide-prefix-argument value expression)
Provides the prefix argument value to the expression.
Takes the character or string provided as its argument and causes it to be used as the next character(s) read from the keyboard.
(put-database-entry dbname key)
Takes the current buffer and stores it in the named database under the given key. The key and data are written into the first database file in the specified database search list.
Defines the symbol in the environment with the given value. Any process created by emacs will inherit the variable, so the symbols are available to all new processes you create.


|
Contiki 2.5
|
The ring buffer library implements ring (circular) buffer where bytes can be read and written independently. More...
Data Structures | |
| struct | ringbuf |
| Structure that holds the state of a ring buffer. More... | |
Files | |
| file | ringbuf.h |
Header file for the ring buffer library. | |
Functions | |
| void | ringbuf_init (struct ringbuf *r, uint8_t *a, uint8_t size_power_of_two) |
| Initialize a ring buffer. | |
| int | ringbuf_put (struct ringbuf *r, uint8_t c) |
| Insert a byte into the ring buffer. | |
| int | ringbuf_get (struct ringbuf *r) |
| Get a byte from the ring buffer. | |
| int | ringbuf_size (struct ringbuf *r) |
| Get the size of a ring buffer. | |
| int | ringbuf_elements (struct ringbuf *r) |
| Get the number of elements currently in the ring buffer. |
The ring buffer library implements ring (circular) buffer where bytes can be read and written independently.
A ring buffer is particularly useful in device drivers where data can come in through interrupts.
| int ringbuf_elements | ( | struct ringbuf * | r | ) |
| int ringbuf_get | ( | struct ringbuf * | r | ) |
Get a byte from the ring buffer.
| r | A pointer to a struct ringbuf to hold the state of the ring buffer |
This function removes a byte from the ring buffer. It is safe to call this function from an interrupt handler.
| void ringbuf_init | ( | struct ringbuf * | r, |
| uint8_t * | a, | ||
| uint8_t | size_power_of_two | ||
| ) |
Initialize a ring buffer.
| r | A pointer to a struct ringbuf to hold the state of the ring buffer |
| a | A pointer to an array to hold the data in the buffer |
| size_power_of_two | The size of the ring buffer, which must be a power of two |
This function initiates a ring buffer. The data in the buffer is stored in an external array, to which a pointer must be supplied. The size of the ring buffer must be a power of two and cannot be larger than 128 bytes.
Definition at line 44 of file ringbuf.c.
Referenced by uart1_init().
| int ringbuf_put | ( | struct ringbuf * | r, |
| uint8_t | c | ||
| ) |
Insert a byte into the ring buffer.
| r | A pointer to a struct ringbuf to hold the state of the ring buffer |
| c | The byte to be written to the buffer |
This function inserts a byte into the ring buffer. It is safe to call this function from an interrupt handler.
Definition at line 53 of file ringbuf.c.
Referenced by serial_line_input_byte().


📋 MultiClip
Settings
➛
This Extension requires JavaScript enabled to function properly
ClipBoard is Empty
Copy with Ctrl+C or Cmd+C, or type here
PREVIEW


--- layout: default title: Open Source for Shopify description: A collection of Shopify-related open source projects, developed by third parties. ---
This collection of third-party projects is not officially supported or endorsed by Shopify.
For the list of official Shopify open source projects, go here.


ng-starter says, THANK YOU!!
Please fork on GITHUB. Feel free to post the issues and enhancement request as well.
Let's first test out the things. Type your name below...
If you see a greeting message thrown with your name, you are all set up!!
Welcome, {{user}}.  Start adding your own code to explore it more!!
Let's first test out the things. Type your name below...
If you see a greeting message thrown with your name, you are all set up!!
Welcome, {{user}}.  Start adding your own code to explore it more!!


{% extends './base.html'%} {% block title%}Books{% endblock %} {% block content %}
You have {{ books|length }} books on record


#ify (spelt "hashify") is a way of finding links that people are talking about. Search engines are good for finding information relating to a string of words that articles have included in them. #ify is for finding articles that people are talking about on the topic. Instead of any website that uses the word "iPhone" in it; we look for what people are linking to with the hashtag "#iPhone". This means you see the articles that people are talking about. #ify gets results from Twitter, Google+ and Facebook.
Yes! You can check them all out at http://etheralstudios.com
#ify is currently a free and ad-free service, and we plan to keep it that way. One way you could help out is to register domain names for this website (like http://hashify.org, http://hashify.com, http://hashifysearch.com, etc). If you have a domain you would like to share with us just setup a redirect to this address. It also would be really nice if you could promote the service or contribute to the actual code of the service.
Yes! You can find #ify on GitHub under the MIT license.


With only defining themes, one couldn't get non ngMaterial elements colored with Material colors,
$mdColors
service is used by the md-color directive to convert the 1..n color expressions to RGBA values and will apply
those values to element as CSS property values.
$mdColors.applyThemeColors(element, colorExpression);
Gets a color json object, keys are css properties and values are string of the wanted color Then calculate the rgba() values based on the theme color parts
| Parameter | Type | Description |
|---|---|---|
* element
DOMElement
|
DOMElement |
the element to apply the styles on. |
* colorExpression
object
|
object |
json object, keys are css properties and values are string of the wanted color,
for example: |
$mdColors.getThemeColor(expression);
Get parsed color from expression
| Parameter | Type | Description |
|---|---|---|
* expression
string
|
string |
string of a color expression (for instance |
| Returns | Description |
|---|---|
string |
a css color expression (for instance |


!Iason Heine: Now's not the time, adventurer! Hurry to the Disciple's Necropolis and find the Promise of Mammon!


| Folder | Year | Country | Owner | Created | Changed | Status | Reviews done/assigned | As of now | Potential |
|---|---|---|---|---|---|---|---|---|---|
| {{x.folderName}} | {{x.year}} | {{x.country}} | {{x.ownerName}} | {{x.repositoryDate}} | {{x.importDate}} | {{x.status}} | {{x.nbReviewsDone}} / {{x.nbReviewsAssigned}} | {{x.ar}} | {{x.p}} |


AST_node Attribute Codes
|
Attribute Code |
Description |
|
[list_decl] |
list declaration |
|
addr_expr |
take the address of an object |
|
alshift_assign_expr |
shift left and assignment expression |
|
alshift_expr |
shift left expression |
|
anonymous_class |
anonymous class (Java only) |
|
array_ref |
array reference |
|
arshift_assign_expr |
arithmetic (sign extend) shift right and assignment expression |
|
arshift_expr |
arithmetic (sign extend) shift right expression |
|
asm_stmt |
embedded assembly language statement |
|
assign_expr |
simple assignment expression |
|
ast_block |
body inside braces { } for function, class, enum, if statement, .... For SQL usually points to any body between keywords “BEGIN” and “END” or inside parentheses (). |
|
ast_declspec |
type declaration |
|
ast_root |
node for file |
|
ast_superclass |
class or list of classes from which original class is derived |
|
bit_and_assign_expr |
bitwise AND and assignment expression |
|
bit_and_expr |
bitwise AND expression |
|
bit_field_ref |
field reference (C++ only) |
|
bit_ior_expr |
bitwise inclusive OR expression |
|
bit_xor_assign_expr |
bitwise exclusive OR and assignment expression |
|
bit_ior_assign_expr |
bitwise inclusive OR and assignment expression |
|
bit_xor_expr |
bitwise exclusive OR expression |
|
call_expr |
call expression |
|
case_default |
default case |
|
case_label |
label of case |
|
case_stmt |
case statement |
|
case_value |
value of case |
|
catch |
catch or microsoft finally expressions |
|
class_literal |
reference to the specified class (Java only) |
|
component_ref |
component reference |
|
compound_expr |
sequence (comma) operator |
|
cond_expr |
conditional expression |
|
const_decl or const_id |
constant identifier or declaration (C++ only) |
|
convert_expr |
conversion of value of an operand from one type to another |
|
ctor_init |
constructor initialization |
|
cursor_decl |
(SQL only) |
|
cursor_def |
(SQL only) |
|
dimensions |
array size declaration (Java only) |
|
div_assign_expr or trunc_div_assign_expr |
integer divide and assign |
|
div_expr |
divide expression (SQL only) |
|
dl_expr |
delete expression |
|
do_while_stmt |
do while expression |
|
dynamic_init |
dynamic initialization |
|
easy_new |
create an object of the type_name to which it is applied (Java only) |
|
eq_expr |
equal expression |
|
exit_stmt |
break or continue statement (loop exits) |
|
expr_stmt |
expression statement |
|
field_decl |
field declaration |
|
finally |
finally expression (Java only) |
|
for_expr |
for expression |
|
function_decl |
function declaration |
|
function_def |
function definition |
|
ge_expr |
greater than or equal expression |
|
global_id |
global identifier |
|
goto_stmt |
goto statement |
|
gt_expr |
greater than expression |
|
if_stmt |
if statement |
|
implements |
interfaces that original class implements (Java only) |
|
in_expr |
SQL in |
|
indirect_ref |
indirect reference |
|
initialization_block |
initialization block (Java only) |
|
inner_join_expr |
SQL inner join |
|
instanceof |
instanceof (Java only) |
|
java_component_ref |
component reference for JAVA |
|
java_vec_new |
create vector of the type_name to which it is applied (Java only) |
|
label_decl |
pointer to label declaration |
|
le_expr |
less than or equal expression |
|
left_join_expr |
(SQL only) |
|
local_id |
local identifier |
|
lrshift_assign_expr |
logical (zero pad) right shift and assignment expr. (Java only) |
|
lrshift_expr |
logical (zero pad) right shift expression (Java only) |
|
lt_expr |
less than expression |
|
microsoft_try |
Microsoft-style try block |
|
minus_assign_expr |
subtract and assign expression |
|
minus_expr |
subtract (minus) expression |
|
mod_assign_expr or trunc_mod_assign_expr |
modulo and assignment expression |
|
mult_assign_expr |
multiply and assignment expression |
|
mult_expr |
multiply expression |
|
name_clause |
name for class, enum, ... |
|
namespace_decl |
namespace declaration (C++ only) |
|
ne_expr |
not equal expression |
|
negate_expr |
unary minus expression |
|
no_operand |
placeholder when function has no return type, as in constructors |
|
nw_expr |
call to new |
|
parens |
parentheses (Java only) |
|
parm_decl |
parameter declaration |
|
plus_assign_expr |
add and assign expression |
|
plus_expr |
add (plus) expression |
|
pm_field_ref |
pointer to member implicit field |
|
postdecrement_expr |
post-decrement expression |
|
postincrement_expr |
post-increment expression |
|
predecrement_expr |
pre-decrement expression |
|
preincrement_expr |
pre-increment expression |
|
rdif_expr |
floating point divide expressions |
|
rdiv_assign_expr |
floating point divide and assign |
|
return_stmt |
return statement |
|
super |
reference to the parent class through super (Java only) |
|
template_body |
function or class template body (C++ only) |
|
template_class |
template class |
|
template_fcn |
template function (C++ only) |
|
template_static_data_mbr |
template static data members (C++ only) |
|
template_struct |
template structure (C++ only) |
|
template_union |
template union (C++ only) |
|
this |
use of the this pointer/object reference |
|
throw_expr |
throw exception |
|
throw_spec |
throw exception declaration in the function signature (Java only) |
|
trunc_div_expr |
integer divide expression |
|
trunc_mod_expr |
modulo (remainder) expression |
|
truth_and_expr |
logical AND for SQL |
|
truth_andif_expr |
logical AND for if expression |
|
truth_not_expr |
not expression |
|
truth_or_expr |
logical inclusive OR for SQL source code |
|
truth_orif_expr |
logical inclusive OR for if expression |
|
try_block |
try block |
|
type_decl |
declaration for class, structure enum, ... |
|
type_decl_modified |
class declaration (Java only) |
|
typespec |
type declaration (Java only) |
|
unary_plus |
unary plus expression (appears only in Java) |
|
using_decl |
import class declaration using in the original class (Java only) |
|
var_decl |
variable declaration |
|
vec_dl_expr |
vector delete expression |
|
vec_nw_expr |
create vector of the type_name to which it is applied |
|
where |
(SQL only) |
|
while_expr |
while expression |


steal.build(url, options) -> undefined
{String}
an html page to compress
{Object}
An object literal with the following optional values:
| Name | Description |
|---|---|
| to | The folder to put the production.js and production.css files. |
| all | Concat and compress all scripts and styles. By default, this is set to false, meaning
scripts and styles have to opt into being compress with the compress='true' attribute. |
{undefined}
Builds an html page's JavaScript and CSS files by compressing and concatenating them into a single or several files.
Steal can also build multiple applications at the same time and separate shared dependencies into standalone cache-able scripts.
How it works
Steal.build
opens a page in Envjs to extract all scripts and styles from the page. It compresses the resources into production.js and production.css files.Steal.build works with or without using steal.js, so it could work with other script loaders.
Building with steal.js.
Building with steal is easy, just point the
steal/buildjs
script at your page and give it the name of your application folder:If you generated a steal app or plugin, there's a handy script already ready for you:
Building without steal.js
You can compress and package any page's JavaScript by addingcompress="true"
attributes to your script tag like the following: and then running either: or: This will compress file1.js and file2.js into a file package named production.js an put it in OUTPUT_FOLDER.Common Problems
If you are getting errors building a production build, it's almost certainly because Envjs is close, but not quite a fully featured browser. So, you have to avoid doing things in your page that Envjs doesn't like before onload. The most common problems are:
Malformed HTML or unescaped characters
Steal does not have as tolerant of an HTML parser as Firefox. Make sure your page's tags look good. Also, make sure you escape characters like & to &
DOM manipulations before onload
EnvJS supports most DOM manipulations. But, it's not a graphical browser so it completely punts on styles and dimensional DOM features. It's easy to protect against this, just wait until document ready or onload to do these things.
Unending timeouts or intervals before onload
Envjs won't quit running until all timeouts or intervals have completed. If you have a reoccuring 'process', consider starting it on document ready or onload.
Building With Shared Dependencies
If you are using steal in a setting with multiple pages loading similar functionality, it's typically a good idea to build the shared functionality in its own script. This way when a user switches pages, they don't have to load that functionality again.
To do this, use the buildjs script with the names of your apps:
steal.build function
Takes a url, extracts


TRIANGLE TRACKER
TRIANGLE CHECKER
Please input any 3 sides to check what kind of triangle it is.
SUBMIT


The rules to Rock Paper Scissors Lizard Spock are simple.
Scissors decapitate Lizard, Scissors cuts paper, paper covers rock, rock crushes lizard, lizard poisons Spock, Spock smashes scissors, lizard eats paper, paper disproves Spock, Spock vaporizes rock, and as it always has, rock crushes scissors.
Winner!
Click below to play again!