MaskTools v2
Abstract
Authors : Kurosu, Manao, mg262
Version : 2.0 alpha 48
Download : http://manao4.free.fr/
Category : Misc Plugins
Requirements : YV12 Colorspace
Table of contents
I) Introduction
Masktool's dll contains a set of filters designed to create, manipulate and use masks. Masks,
in video processing, are a way to give a relative importance to each pixels. You can, for example,
create a mask that select only the green parts of the video, and then replace these parts with
another video.
To give the most control over the handling of masks, the filters will use the fact that each
luma and chroma planes can be uncorrelated. That mean that a single video will always be
considered by the filters as 3 independant planes. That applies for masks as well, which means
that a mask clip will in fact contain 3 masks, one for each planes.
The filters have a set of common parameters, that mainly concerns what processing to do on
each planes. They all work only in YV12 ( though with Avisynth 2.6, support for all planar format
will be available ).
There are four DLLs in this package : two win32 DLLS, and two win64 ones. There are two DLLs
for avisynth 2.5, and two for avisynth 2.6
II) Common parameters
As said previously, all the filters - except the helpers - share a common set of parameters. These parameters are used
to tell what processing to do on each plane / channel, and what area of the video to process.
- int "offx" (0), int "offy" (0)
"offx" and offy are the top left coordinates of the box where the actual processing shall occur.
Everything outside that box will be garbage.
- int "w" (-1), int "h" (-1)
w and h are the width and height of the processed box. -1 means that the box extends to the
lower right corner of the video. That also means that default settings are meant to process the
whole picture.
- int "y" (3), int "u" (1), int "v" (1)
These three values describe the actual processing mode that is to be used on each plane / channel.
Here is how the modes are coded :
- x=-255..0 : all the pixels of the plane will be set to -x.
- x=1 : the plane will not be processed. That means the content of the plane after the filter is pure garbage.
- x=2 : the plane of the first input clip will be copied.
- x=3 : the plane will be processed with the processing the filter is designed to do.
- x=4 (when applicable) : the plane of the second input clip will be copied.
- x=5 (when applicable) : the plane of the third input clip will be copied.
As you can see, defaults parameters are chosen to only process the luma, and not to care about the chroma. It's
because most video processing doesn't touch the chroma when handling 4:2:0.
- string "chroma" ("")
When defined, the value contained in this string will overwrite the u & v processing modes. This is a nice
addition proposed by mg262 that makes the filter more user friendly. Allowed values for chroma are :
- "process" : set u = v = 3.
- "copy" or "copy first" : set u = v = 2.
- "copy second" : set u = v = 4.
- "copy third" : set u = v = 5.
- "xxx", where xxx is a number : set u = v = -xxx.
III) Filters list
Here is an exhaustive list of the filters contained in this dll :
- Masks creation :
- Masks operation :
- Mask merging :
- Morphologic operator :
- Lut operator :
- mt_lut : applies an expression to all the pixels of a mask / video.
- mt_lutxy : applies an expression to all the pixels of two masks / videos.
- mt_lutxy : applies an expression to all the pixels of two masks / videos.
- mt_lutxyz : applies an expression to all the pixels of three masks / videos.
- mt_lutf : creates a uniform picture from the collection of computation on pixels of two clips.
- mt_luts : applies an expression taking neighbouring pixels into.
- mt_lutsx : applies an expression taking neighbouring pixels into, in a different way.
- mt_lutspa : computes the value of a pixel according to its spatial position.
- Support operator :
- Convolutions :
- Helpers :
IV) Filters description
mt_edge
mt_edge
: string mode("sobel"), int thY1(10), int thY2(10), int thC1(10), int thC2(10)
- mode choses the 3x3 convolution kernel used for the mask computing. There are three predefined kernel,
"sobel", "roberts" and "laplace", and you can enter also a 3x3 custom kernel. "sobel" uses the
kernel "0 -1 0 -1 0 1 0 1 0", "roberts": "0 0 0 0 2 -1 0 -1 0" and "laplace": "1 1 1 1 -8 1 1 1 1".
The normalization factor of the kernel is automatically computed and ceiled to the closest power of 2,
to allow faster processing. You can specify your own normalization factor by adding it to the list of
coefficients ( "1 1 1 1 -8 1 1 1 1 8" for example ).
- thX1 is the low threshold and thX2 the high threshold. Under thX1, the pixel is set to zero, over thX2,
to 255, and inbetween, left untouched.
- Four new kernels have been introduced lately : "hprewitt", "prewitt", "cartoon" and "min/max". "prewitt" is a more
robust kernel, while "cartoon" behaves like "roberts", but takes only negative edges into account.
Finally, "min/max" computes the local contrast ( local max - local min ).
- More precisely, "hprewitt" is equivalent to : mt_logic(mt_edge("1 2 1 0 0 0 -1 -2 -1 1"), mt_edge("1 0 -1 2 0 -2 1 0 -1 1"), mode = "max"), and
"prewitt" is equivalent to mt_logic(mt_logic(mt_edge("1 1 0 1 0 -1 0 -1 -1 1"), mt_edge("1 1 1 0 0 0 -1 -1 -1 1"), mode = "max"), mt_logic(mt_edge("1 0 -1 1 0 -1 1 0 -1 1"), mt_edge("0 -1 -1 1 0 -1 1 1 0 1"), mode = "max"), mode = "max")
mt_motion
mt_motion
: int thY1(10), int thY2(10), int thC1(10), int thC2(10), int thT(10)
- thT decides whether the frame is a scene change or not. The mask is made blank if a scene change
is detected, else, the mask is computed.
- thX1, thX2 work as for mt_edge.
mt_expand, mt_inpand
mt_xxpand
: int thY(255), int thC(255), string mode("square")
- It replaces the pixel by the local maximum/minimum.
- thX allows to limit the maximum change.
- mode select the local neighbourhood. It can take the values :
- "square" : 3x3 square neighbourhood - isse optimized.
- "horizontal" : 3x1 horizontal neighbourhood.
- "vertical" : 1x3 horizontal neighbourhood.
- "both" : a 3-long cross ( "horizontal" + "vertical" ) neighbourhood.
- a custom mode, where you give a list of coordinates. "0 0 -1 0 1 0" is for example
equivalent to "horizontal".
mt_inflate, mt_deflate
mt_xxflate
: int thY(255), int thC(255)
- It computes a local average by taking into account only the neighbourgh whose value is higher/lower than the pixel.
mt_merge
mt_merge
: clip clip1, clip clip2, clip mask, bool "luma"(false)
- It's the backbone of the framework. It merges two clips according to the mask. The bigger the mask value,
the more the second clip will be taken into account ( the actual formula is y = ((256 - m) * x1 + m * x2 + 128) / 256 )
- luma is a special mode, where only the luma plane of the mask is used to process all three channels.
- u and v are defaulted to 2 (that way, the resulting clip contains the chroma of clip1, and looks right).
mt_lut
mt_lut
: string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x")
- It applies a function defined by expr to all the pixels. The function is written is reverse polish notation.
- If yexpr, uexpr or vexpr isn't defined, expr is used instead.
mt_lutxy
mt_lutxy
: clip clip1, clip clip2, string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x")
- It applies a two-parameters function defined by expr to all the pixels. The function is written is reverse polish notation.
- If yexpr, uexpr or vexpr isn't defined, expr is used instead.
mt_lutxyz
mt_lutxyz
: clip clip1, clip clip2, clip clip3, string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x")
- It applies a three-parameters function defined by expr to all the pixels. The function is written is reverse polish notation.
- If yexpr, uexpr or vexpr isn't defined, expr is used instead.
mt_lutf
mt_lutf
: clip clip1, clip clip2, string mode("avg"), string expr("y"), string yexpr("y", string uexpr("y"), string vexpr("y")
- It computes a value by collecting the values of the pixels of clip1, according to mode. Then it applies the function
defined by the expressions to all the pixels of clip2 ( which are mapped to the y variable, while x is the collected value ).
- mode can be :
- "avg" or "average" : computes the average of the values.
- "std" or "standard deviation" : computes the standard deviation of the values.
- "min" : computes the min of the values.
- "max" : computes the max of the values.
- "range" : computes "max" - "min".
- "med" or "median" : computes the median of the values.
- A possible use is to allow increase the dynamic adaptively :
mt_lutf(c, c, mode = "range", expr = "y 128 - 256 * x / 128 +")
mt_luts
mt_luts
: clip clip1, clip clip2, string mode("avg"), string pixels(""), string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x")
- It computes the mode operation on the result of the function defined by expr, where x is the pixel from clip1, and y
a pixel from the neighbourhood in clip2, defined by pixels.
- mode can take the same values as for
mt_lutf
, but also supports a seventh mode, which will do a sum of the neighbouring, weighted by the serie of weights
given as mode. The sum is normalized by the sum of weights.
- pixels is a coordinates list, relative to the current pixels. It can be created by one of the form helpers.
- Let's see some uses :
mt_luts( c, c, mode = "avg", pixels = mt_square( 1 ), expr = "y" )
does a convolution
by a 3x3 kernel filled with ones.
mt_luts( c, c, mode = "min", pixels = mt_square( 1 ), expr = "y" )
does an inpand.
mt_luts( c, c, mode = "range", pixels = mt_square( 1 ), expr = "y" )
does a mt_edge( mode = "min/max" )
.
mt_luts( c, c, mode = "std", pixels = mt_square( 1 ), expr = "y" )
gives the local standard deviation of the clip.
mt_luts( c, c, mode = "max", pixels = mt_square( 1 ), expr = "x y - abs" )
gives
the maximum difference between the surrounding pixels and the center.
mt_luts( c, c, mode = "med", pixels = mt_square( 1 ), expr = "y" )
gives the median of the pixels of
the surrounding.
mt_luts( c, c, mode = "1 1 1 1 1 1 1 1 1", pixels = mt_square( 1 ), expr = "y" )
is equivalent to mode = "avg".
mt_lutsx
mt_lutsx
: clip clip, clip clip1, clip clip2, string mode("avg"), string mode2("none"), string pixels(""), string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x")
- It computes the mode on the neighbouring pixels in clip1, and mode2 on the neighbouring pixels in clip2,
then it applies the function defines by expr with y = mode and z = mode2.
- mode and mode2 can take the same values as for
mt_luts
.
- pixels works as in
mt_luts
.
- Let's see some examples :
mt_lutsx( c, c, c, mode = "min", mode2 = "max", pixels = mt_square( 1 ), expr = "z y -" )
computes the local max - min value.
mt_lutsx( c, c, c, mode = "min", mode2 = "max", pixels = mt_square( 1 ), expr = "x y - 256 * z y - /" )
change the local luminosity and constrast so that the local minimum is black and local maximum is white.
mt_lutspa
mt_lutspa
: clip clip, string mode("relative"), string expr("x"), string yexpr("x"), string uexpr("x"), string vexpr("x"), bool relative("true"), bool biased("true")
- It computes the value of each pixels according to its coordinates and the given lut. Variable x and y in the lut corresponds
respectively to absciss and ordinate of the pixel. mode controls how the pixels coordinates are transformed into a value. It overrides the legacy parameters,
relative and biased.
- Possible values for mode are :
- "absolute" : x and y go from 0 to width - 1 and height - 1. Equivalent to relative = false.
- "relative", or "relative opened", or "relative exclusive" : x and y go from 0 to 1 (excluded). Equivalent to relative = true, biased = true.
- "relative closed", or "relative inclusive" : x and y go from 0 to 1 (included). Equivalent to relative = true, biased = false.
- Let's see an example :
mt_lutspa( c, mode = "relative", expr = "x y + 256 * 2 /", chroma = "128" )
creates a diagonal gradient.
mt_average
mt_average
: clip clip1, clip clip2
- Equivalent to
mt_lutxy("x y + 2 /")
, but faster.
mt_makediff
mt_makediff
: clip clip1, clip clip2
- Equivalent to
mt_lutxy("x y - 128 +")
, but faster.
mt_adddiff
mt_adddiff
: clip clip1, clip clip2
- Equivalent to
mt_lutxy("x y + 128 -")
, but faster.
mt_clamp
mt_clamp
: clip c, clip bright_limit, clip dark_limit, int overshoot(0), int undershoot(0)
- Forces the value of the first clip to be between bright_limit + overshoot and dark_limit - undershoot.
- Gives unwanted results if bright_limit + overshoot < dark_limit - undershoot.
mt_invert
mt_invert
: clip c
- Inverts the values of the pixels.
- Equivalent to
mt_lut("255 x -")
, but faster.
mt_binarize
mt_binarize
: clip c, int threshold(128), bool upper(false), string mode("lower")
- Does the quivalent of
mt_lut("x t > a b ?")
, where "a b" is derived from mode, and can be either 0, x, t or 255 (t is replaced by threshold)
- Possible values for mode are :
- "0 x"
- "x 0"
- "0 t"
- "t 0"
- "t x"
- "x t"
- "255 0" or "lower"
- "0 255" or "upper"
- "255 x"
- "x 255"
- "255 t"
- "t 255"
- upper parameter is kept for compatibility purposes. When it is defined, it overrides mode.
mt_logic
mt_logic
: clip clip1, clip clip2, string mode("and"), int th1(0), int th2(0)
- Applies the function defined by mode to clip1 and clip2.
- Possible values for mode are :
- "and" : does a binary "and" on each pairs of pixels ( 11 & 5 is computed by converting them to binary, and to and all the bits : 11 = 1011, 5 = 101, 11 & 5 = 1 ).
- "or" : does a binary "or" on each pairs of pixels ( 11 | 5 = 1011 | 101 = 1111 = 15 ).
- "xor" : does a binary "xor" on each pairs of pixels ( 11 ^ 5 = 1011 ^ 101 = 1110 = 14 ).
- "andn" : does a binary "and not" on each pairs of pixels ( 11 & ~5 = 1011 & ~101 = 1011 & 11111010 = 1010 = 10 ).
- "min" : equivalent to
mt_lutxy("x th1 + y th2 + min")
.
- "max" : equivalent to
mt_lutxy("x th1 + y th2 + max")
.
mt_hysteresis
mt_hysteresis
: clip small_mask, clip big_mask
- Grows the small mask into the big mask by connex components. That allows to build more robust edge masks.
mt_convolution
mt_convolution
: clip c, string horizontal("1 1 1"), string vertical("1 1 1"), bool saturate(true), float total(1.0f)
- Applies the convolution defined by the kernel horizontalT x vertical to the video.
- Both horizontal and vertical must have an odd length.
- The default normalization value is the sum of the absolute values of the coefficients of the kernel.
- If saturate is true, the result of the convolution is clipped to [0..255], else the absolute value of the result is clipped to [0..255].
- If total is defined, it overrides the default normalization value.
- Computations occurs in float as soon as one element of horizontal or vertical is a float.
mt_mappedblur
mt_mappedblur
: clip c, clip map, string kernel("1 1 1 1 1 1 1 1 1"), string mode("replace")
- Applies the convolution kernel to the clip, but in a special way, according to mode :
- "replace" : if a pixel differs by more than map from the center pixel of the convolution, it is replaced by the center value.
- "dump" : if a pixel differs by more than map from the center pixel of the convolution, it is not taken into account.
mt_square, mt_circle, mt_diamond
mt_square
: int radius(1), bool zero(true)
mt_circle
: int radius(1), bool zero(true)
mt_diamond
: int radius(1), bool zero(true)
- Creates a relative coordinates list that can be used in
luts
, mt_expand
and mt_inpand
- zero decides whether the center of the form is included or not.
mt_rectangle, mt_ellipse, mt_losange
mt_rectangle
: int hor_radius(1), int ver_radius(1), bool zero(true)
mt_ellipse
: int hor_radius(1), int ver_radius(1), bool zero(true)
mt_losange
: int hor_radius(1), int ver_radius(1), bool zero(true)
- Creates a relative coordinates list that can be used in
luts
, mt_expand
and mt_inpand
- zero decides whether the center of the form is included or not.
mt_freerectangle, mt_freeellipse, mt_freelosange
mt_freerectangle
: int top_x(-1), int top_y(-1), int bottom_x(1), int bottom_y(1), bool zero(true)
mt_freeellipse
: int top_x(-1), int top_y(-1), int bottom_x(1), int bottom_y(1), bool zero(true)
mt_freelosange
: int top_x(-1), int top_y(-1), int bottom_x(1), int bottom_y(1), bool zero(true)
- Creates a relative coordinates list that can be used in
luts
, mt_expand
and mt_inpand
- zero decides whether the (0,0) pixel is included or not.
mt_polish
mt_polish
: string expr("x")
- Creates a reverse polish expression from an infix one.
mt_infix
mt_infix
: string expr("x")
- Creates an infix expression from a reverse polish one.
V) Reverse polish notation.
A lot of filters accept custom functions defined by an expression written in reverse polish
notation. You may not be accustomed to this notation, so here are a few pointers :
- The basic concept behind the notation is to write the operator / function after the arguments.
Hence, "x + y" in infix notation becomes in reverse polish "x y +". "(3 + 5) * x" would become
"3 5 + x *".
- As you noticed in the last example, the great asset of the notation is that it
doesn't need parenthesis. The expresion that would have been enclosed in parenthesis ( "3 + 5" )
is correctly computed, because we read the expression from left to right, and because
when the "+" is encountered, its two operands are unmistakenly known.
- The supported operators are : "+", "-", "*", "/", "%" ( modulo ) and "^" ( power )
- The supported functions are : "sin", "cos", "tan", "asin", "acos", "atan", "exp", "log",
"abs", "round", "clip", "min", "max".
- Making the assumption that a positive float is "true", and a negative one is "false",
we can also define boolean operators : "&", "|", "&!" ( and not ), "°" or "@"( xor ).
- Signed and unsigned unary and binary operators exists : "&u", "|u", "°u" ("@u"), "~u", "<<u", ">>u" round and clip
their operands to the nearest integer in [0..2^64-1], then do a "and", "or", "xor", "complement to 1", "left shift", or "right shift".
Accordingly, "&s", "|s", "°s" (@s), "~s", "<<s", ">>s" do the same operations, but round and clip to the nearest
integer in [-2^63..2^63-1] beforehand. "<<" and ">>" are equivalent to "<<u" and ">>u". The second operand of
shifts is always considered signed : a left shift by a negative value is equivalent to a right shift by the opposite of the value.
- We can create boolean values with the following comparaison operators : "<", ">", "<=",
">=", "!=", "==", "=".
- The variable "x", "y" and "z" ( when applicable ) contains the value of the pixel. It's an
integer that ranges from 0 to 255.
- The constant "pi" can be used.

- All the computation are made on floats, and the final results is rounded to the nearest integer,
in the range [0..255].
- Throughout the whole documentation, you'll be able to found plenty of examples.
VI) Changelog
Alpha 48 :
- added : signed and unsigned binary shifts to LUTs, ceil/floor/trunc float -> int conversions. @ is now equivalent to °
Alpha 47 :
- added : signed and unsigned binary operators to LUTs
Alpha 46 :
- fixed : with mt_lutf, "std" mode wasn't working. Could also affect "std" with mt_luts and mt_lutsx
Alpha 45 :
- fixed : mt_clamp on sse2 platforms with resolution not multiple of 64
- added : mode parameter to mt_lutspa, to clean up biased/relative mess
Alpha 44 :
- added : new mode (weighted sum) for mt_luts and mt_lutsx
Alpha 43 :
- fixed : optimized versions of small horizontal resolutions with mt_edge, mt_xxpand and mt_xxflate
- fixed : avisynth 2.6 support (likely broken since avisynth 2.6 alpha 2 at least)
- added : hprewitt mode to mt_edge
- added : "biased" option to mt_lutspa
- optimized : prewitt and hprewitt mode for mt_edge
Alpha 42 :
- added : specialized modes for mt_binarize
- added : specialized modes for mt_logic
Alpha 41 :
- (re)optimized : mt_edge with custom kernels and divisors that are a power of two
- fixed : mt_edge with custom kernels (has always been broken in C, which became obvious once asm was removed)
- fixed : no more crashes when an input clip isn't YUV planar
Alpha 40 :
- optimized : mt_xxpand vertical/horizontal/both modes are asmized
- optimized : mt_xxflate are asmized
- optimized : mt_motion with sse2
- potential fix : mt_merge with mod8 width
- potential : 64 bits build included
Alpha 39 :
- Failed attempt at 64 bits build
Alpha 38 :
- Failed attempt at 64 bits build
Alpha 37 :
- fixed : mt_polish wasn't handling "z", "min", "max", "clip" and "round"
- added : mt_infix, which convert from polish to infix notation
- changed : built with MSVC 2008
Alpha 36 :
- fixed : "pi" wasn't properly defined for all luts
Alpha 35 :
Alpha 34 :
- added : support for interleaved2planar hack, enabling 422 support
- changed : both avisynth 2.5 and 2.6 version are built
Alpha 32 :
- added : mt_lutxyz
- added : mt_lutsx
- fixed : small memory leak in mt_luts
Alpha 31 :
- fixed : mt_hysteresis was randomly crashing.
- fixed : mt_polish is back.
- added : round, clip, min, max and = for lut.
- adapted : to msvc8 / yasm.
Alpha 30 :
- fixed : luts was crashing if some pixels didn't have any neighbours in the pixels list.
- added : mt_freerectangle, mt_freeellipse and mt_freelosange helpers.
Alpha 29 :
- fixed : intern float to integer conversion that were badly rounding negative number. That resulted in -1.0 been rounded into 0 (!). Most notably affected was mt_convolution. Thanks redfordxx for pointing that out.
Alpha 28 :
- fixed : mt_expand / mt_inpand / mt_convolution / mt_edge optimizations ( were borked
when width-16 was mod 64, and that could be noticed only with avs 2.5.7 )
Alpha 27 :
- fixed : mt_binarize asm optimizations that borked with some thresholds
Alpha 26 :
- fixed : avs closing issue.
Alpha 25 :
- added : new html documentation.
- fixed : wrong frame issue.
- fixed : mt_merge with luma=true.
Alpha 24 :
- fixed : issues with MT.dll ( thanks tsp, Boulder, vanessam and all those who suffered the bug ).
- fixed : check for YV12 colorspace, and report an error if it isn't ( thanks Boulder ).
- speed up : median mode for luts ( once again, thanks to tsp ).
Alpha 23 :
- fix & speed up : median mode, thanks to tsp's insightfull remark. Note to self : think
less like a mathematician, and more like a programmer. Simpler, faster & not bugged.
Alpha 22 :
- added : "med"/"median" mode to luts/lutf.
- changed : luts doesn't necessarily consider the center pixel.
- changed back : forms helpers prepends (0, 0).
- changed : forms helpers now have a bool "zero" parameter, defaulted to true.
- added : bool "luma" parameter to mt_merge, which makes it use the luma mask for
all three planes, and which forces chroma modes to "process" ( u=v=3 ).
Alpha 21 :
- fixed : two & three input clips filters where requesting wrong frames
leading to ghost artefacts.
Alpha 20 :
- fixed : huge bug preventing most filters from working.
Alpha 19 :
- code refactoring.
- fixed : bug with asm and width lower than 64.
- fixed : doesn't prepend (0, 0) pixel to the forms helpers.
- added : "min/max" mode to mt_edge. The edge value is local max - local min ( taken on a
3x3 square ).
- added : mt_lutf : a frame lut, see the description above.
- added : mt_luts : a spatial lut, see the description above.
Alpha 18 :
- added : mt_makediff, mt_adddiff, mt_average and mt_clamp, ported from mg262's
limitedsupport plugin. The asm code is his, though it has been ported to nasm. They
respectively amount to MakeDiff, AddDiff, SimpleAverage and Clamp.
- added : mt_edge : "prewitt" kernel, taken from mg262's Prewitt filter. Unlike mg262's filter,
there's no multiplier ( it's always 1 ), but mt_edge's thresholds still apply. Results,
and speed, are identical except for the borders, which are now filtered.
- added : "chroma" parameter, taken from mg262's excellent idea. It's a string that,
if used, overrides U and V values. It can be either "process", "copy", "copy first",
"copy second" or a number. "copy" and "copy second" work alike.
- added : vmToon-0.74, adapted to masktools 2.0.
- added : LimitedSharpenFaster, with LimitedSupport functions imported into the masktools.
Alpha 17 :
- changed : behavior of mt_edge with a custom kernel : the automatic normalization factor
is now the sum of the absolute value of the coefficients, ceiled to the next power of two
if that power is <= 128 ( else, it isn't ceiled ).
- added : cartoon mode for mt_edge.
- added : modified mfToon script, for masktools v2. mfToonLite's speed goes from 30 fps
to 70 fps, mfToon from 4.5 to 6.5.
Alpha 16 :
- fixed : some asm code used in invert, binarize and memset to a particular value.
Bug made the first 8 pixels of the picture to be incorrect. Also, avoid another nasty issue
that arise when cropping ( not my fault this time, though ).
Alpha 15 :
- fixed : bugs from inflate & deflate ( thx you know you ).
- reversed : inflate and deflate now match their masktools' v1 counterparts' behavior.
( if anybody used the new buggy one, let him speak quickly ).
Alpha 14 :
- fixed : random crashes with some width and asm functions ( thx Didee ).
Alpha 13 :
- fixed : mt_merge order swapped for mask operation ( no comment... ).
Alpha 12 :
- fixed : bug with some width ( mod4 ) for the non processing mode ( != 1 or 3 ).
- changed : mt_merge order swapped for mask operation.
Alpha 11 :
- fixed : mt_convolution's multiple instanciation bug.
Alpha 10 :
- fixed : offY was always set to offX.
- fixed : offset quirk.
- fixed : mt_convolution was crashing with floats.
- changed : luts' equal operator is now equivalent to abs(x-y) < 0.000001.
- added : bool saturate(true) parameter to mt_convolution.
- added : float total(1.0) parameter to mt_convolution.
Alpha 9 :
- fixed : mt_lut, mt_lutxy : even faster loading.
- fixed : mt_convolution : negative coefficients were offseted by 1.
- fixed : mt_convolution : division by zero if the sum of the coefficients was 0.
Alpha 8 :
- fixed : mt_edge in custom mode wasn't working properly.
- fixed : mt_edge in custom mode, optimized wasn't working properly either.
- fixed : mt_lutxy was slow to load, it's better now.
Alpha 7 :
- fixed : forgot to add functions to the parser. Thanks Didee for pointing that out.
Alpha 6 :
- fixed : mt_polish was having some trouble with functions.
Alpha 5 :
- added : helpers for creating string for inpand / expand custom modes :
- mt_circle
- mt_square
- mt_diamond
- mt_ellipse
- mt_rectangle
- mt_losange
- added : helper for lut : consersion from infix to reverse polish notation :
Alpha 4 :
- added : custom modes for inpand / expand.
Alpha 3 :
- Fixed : mt_invert, mt_binarize, mt_lutxy, which weren't working properly anymore.
- Fixed : offset created by incorrect rounding in mt_convolution.
- Fixed : mmx version of edges filters ( soft thresholding, and roberts ).
- Fixed : mmx version of motion edge ( soft thresholding ).
- added : mt_mappedblur.
Alpha 2 :
- added functions to luts : sin, abs, cos, tan, exp, log, acos, atan, asin.
- added "vertical", "horizontal" and "both" mode to mt_inpand / mt_expand.
- added mt_convolution.
- fixed mt_merge behavior for y, u, v = 2.
- added y, u, v = 4, for masked merge : copy the second clip channel. It's worth for any two clips input filters.
- internal changes ( code reorganization ).
Alpha 1 :


Set debug for this testcase
Document description
Developer
Secret key
Encrypt scenarios to file .yaml.encrypt which help to uploading scenario to unsecure server then load them then decrypt
Keep playing when got somethings error
Result after run all of test
Total APIs
Servers test which for each of environments
Examples: servers: dev: http://localhost prod: http://prod.com
Output style
Document title
Global variables which can be overided by ENV variables
Document version
Testcase which includes meta data to help to generate doc


Warehouse Chief Croop:
Haven't found him yet? Don't waste any more time, okay? You've got to find wee Jacob!
If you do, I promise you will be richly rewarded. Now hurry! There's nae a minute to waste!


Dear Users,
we are the Lab of New Generation Network Technology and Application
It is Tingwu Wang, and this is my bachelor project. The website uses free templates from purecss
If you have any questions, please contact the lab via the website given above.
Regards,Control Center


| DOSE: |
2 bowls |
smoked |
Cannabis |
(plant material) |
Hello, I decided to write my experiences with cannabis not because I want to add another experience, but because I want to tell you people how some people (like me) react to cannabis differently. I consider myself an intelligent person, however I have problems with my mind. I get depressed easily, and in the past few years i noticed changes in my behavior. There is also history of mentall illnesses in my family.
Okay, I first smoked cannabis when I was 16, and nothing happened. After that I never smoked again for about more than three years. In the meantime, I was really against all drugs. Everything changed when I went to college. My roommate at the beginning wanted to smoke with me, however I said no. Then somehow I smoked my first joint with him, and nothing happened, and I smoked a few more times and nothing happened as well. Everything was about to change when I bought my first supply. It may sound funny but it only worked for me until I bought my own cannabis. At that time I had no clue how much you get for a certain price. So I told my friend to buy me 20 dollars worth of cannabis. I was really happy when I got my supply, and couldn't wait to smoke it.
 So me and my friend, and this another friend went to a nearby 'place' which was in the woods, next to a creek. It was only a 10 minnute walk from our dorm. As we got there, I was rather paranoid because we had to go through someone's driveway and parking lot. However I took a few deep breaths, and realized that everything will be fine. Then we lighted our first bowl. My first hit was rather bad. But later on I took big hits and kept it in my lungs for at least 20 seconds each hit. After our first bowl I started to cough really bad. I coughed for at least 5 minutes. We took a brake and looked around at the quiet woods.
I started to notice that something is happening. I felt like everything is registering in my memory. Whenever I looked at something, it felt like my brain is scanning it. I felt fine, I wouldnt call that a high or anything. Then we decided to pack another bowl. This bowl was bigger, and I got at least 5 good hits off of it. And again, I started to cough really bad, and my friend told me that it's finally working on me. After we smoked that bowl, we waited about 5 minutes while listening to the sound of the creek. As we started to walk slowly out of the woods, I started to feel different in my legs and arms.
With each step, and each little physical activity I started to feel completely different. It took us a few good minutes to get out of the woods, even though it was only about 40 feet. In the last few yards to go, as I had to lift my leg to step over a branch, I finally realized I was high because how I lifted my leg. As I got out of the woods, and into the parking lot. I looked at the lights, and even though I didn't have any hallucinations, I saw them in a pattern. I'd never seen lights in a pattern, I could clearly see the lights forming a line. Midway in the parking lot, A weird feeling went through my body, it felt like a million ants were walking on me, and they were biting me, eating my body. A few moments later I thought they ate my legs, and the only way I was moving was by hovering in mid air.
I got a sudden extreme euphoria, my voice changed and I was almost crying that I was feeling so extremely good. A moment later I got a sudden rush of energy, I literally ran as fast as I could to my dorm, even though it was really cold, about 20 degrees. As I ran through the campus I saw people looking at me, and all I cared is to run faster and faster. When I got to the dorm, I wasn't even tired. I went into my room, but my roommate was gone. I really wanted him to see me like this. So I played some music and sat down and waited. A few minutes later my body felt normal, I could feel my limbs again. And strangely I didn't feel high anymore. I was really dissappointed at this time.
However as I was sitting, I started feeling like before. I could still feel my body, but my brain was getting messed up. My mind transformed and I started thinking really weird. I could notice how objects are different, how they relate to one another, I could see their history. I looked at the clock and saw that it was 2 hours after I left my room. I went to my buddy with whom I smoked with. He wasn't there, but his roomate was there and I chilled there. As my buddy came back, he started telling his roommate about me, and how I acted at the smoke session. At this time I couldn't understand their words. What they said after that was all gibberish. About 2 hours past by since I smoked.
I looked at the door and finally realized that there is another world behind it. I tried to open the door but I was extremely scared to go into that world. I finally opened the door and saw the blue hallway of our dorm. And then my friend who lives right by my room spotted me and I started dancing in the hallway. As he approached ne, I started to hallucinate. I took a pencil and started wrting calculus on their bored and he was saying something but I couldn't understand him. Then I saw 3 of them. It was realy weird because I saw 3 people who were the same. I dropped my pencil and dropped to the floor with an enourmous laugh because seeing the same person at 3 places at the same time was really funny to me.
About an hour later I was still really high. I got the munchies and decided to go downstairs to the dining hall to fix myself a bagel. It took me about 20 minutes to make it. I was so scared because I totally forgot how to make a bagel. Then as I finished making a totally shitty bagel, I took it to the register, without a tray. Then I sat down by the window and looked at the campus while I ate it. I went back to their room and stayed there for about another good 2 hours. The whole experience lasted at least 6 hours.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


|
|
| dual (T re=T(), T du=T()) |
| |
|
dual< T > | operator- () const |
| |
|
dual< T > | operator+ (const dual< T > &rhs) const |
| |
|
dual< T > | operator- (const dual< T > &rhs) const |
| |
|
dual< T > | operator* (const dual< T > &rhs) const |
| |
|
dual< T > | operator/ (const dual< T > &rhs) const |
| |
|
dual< T > & | operator+= (const dual< T > &rhs) |
| |
|
dual< T > & | operator-= (const dual< T > &rhs) |
| |
|
dual< T > & | operator*= (const dual< T > &rhs) |
| |
|
dual< T > & | operator/= (const dual< T > &rhs) |
| |
|
dual< T > & | operator= (T rhs) |
| |
|
dual< T > | operator+ (T rhs) const |
| |
|
dual< T > | operator- (T rhs) const |
| |
|
dual< T > | operator* (T rhs) const |
| |
|
dual< T > | operator/ (T rhs) const |
| |
|
dual< T > & | operator+= (T rhs) |
| |
|
dual< T > & | operator-= (T rhs) |
| |
|
dual< T > & | operator*= (T rhs) |
| |
|
dual< T > & | operator/= (T rhs) |
| |
|
T | real () const |
| |
|
T | dual_part () const |
| |
|
void | real (T re) |
| |
|
void | dual_part (T du) |
| |
|
bool | operator== (const dual< T > &rhs) const |
| |
|
bool | operator!= (const dual< T > &rhs) const |
| |
The documentation for this struct was generated from the following file:


UI HTML KIT
Daily
Welcome to Daily UI HTML kit project! It's a design challenge of mine. New designed elements adding daily. Come back tomorrow, grab something new
and implement whatever you want FREE
Hi, I'm Roman
3
DESIGN
IS AWERSOME
Storytelling
What we doing?
Prototyping
High fidelity?
The research
What user wants?
Implement
Can you do basic front end?
3
DESIGN
IS AWERSOME
Storytelling
Prototyping
The research
Implement
DESIGN
BETTER
LAYOUTS
Thanks for download
Hope to see you tomorrow at
www.dailyuikit.com


3. Supervised learning¶
- 3.1. Generalized Linear Models
- 3.2. Support Vector Machines
- 3.3. Stochastic Gradient Descent
- 3.4. Nearest Neighbors
- 3.5. Gaussian Processes
- 3.6. Partial Least Squares
- 3.7. Naive Bayes
- 3.8. Decision Trees
- 3.9. Ensemble methods
- 3.10. Multiclass and multilabel algorithms
- 3.11. Feature selection
- 3.12. Semi-Supervised
- 3.13. Linear and Quadratic Discriminant Analysis


Inkscape is a what you see is what you get Scalable Vector Graphics editor. It is useful for creating, viewing and changing SVG images.
This package is known to build and work properly using an LFS-7.6 platform.
Download (HTTP): http://downloads.sourceforge.net/inkscape/inkscape-0.48.5.tar.bz2
Download MD5 sum: 431cda5cd40cd4fdf2b89db1bdcce61f
Download size: 19 MB
Estimated disk space required: 1.4 GB
Estimated build time: 12 SBU
Boost-1.56.0, GC-7.4.2, Gsl-1.16, Gtkmm-2.24.4 and libxslt-1.1.28
Aspell-<IP_ADDRESS>, Doxygen-1.8.8, ImageMagick-6.8.9-7, libwpg, Poppler-0.26.4 and popt-1.16
XML::XQL and python-lxml
User Notes: http://wiki.linuxfromscratch.org/blfs/wiki/inkscape
Install Inkscape by running the following commands:
patch -Np1 -i ../inkscape-0.48.5-gc-1.patch && ./configure --prefix=/usr && make
Now, as the root
user:
make install
This package installs icon files into the /usr/share/icons/hicolor
hierarchy and desktop
files into the /usr/share/applications
hierarchy. You can
improve system performance and memory usage by updating
/usr/share/icons/hicolor/index.theme
and
/usr/share/applications/mimeinfo.cache
. To
perform the update you must have GTK+-2.24.24 or
GTK+-3.12.2 installed (for the icon cache) and
desktop-file-utils-0.22 (for the
desktop cache) and issue the following commands as the
root
user:
gtk-update-icon-cache && update-desktop-database
Last updated on 2014-09-14 13:18:45 -0700


The canvas:
Are canvases not enabled in your browser?
History goes here:
Commands:
pen_on
pen_off
move PIXELS
rotate DEGREES
Your bidding:
Angle:
0


Below is the latest novel coronavirus data for India.
- This is based on data provided by the Ministry of Health &
Family Welfare as on {{ stats_as_on_date }}.
Total number of confirmed cases in India : {{
total_cases }}.
Total number of casualties : {{
total_casualties }}.
Number of people who have been cured/discharged : {{ num_people_cured }}.
{{ state_with_max_cases }} has the maximum number of confirmed COVID-19
cases, i.e. {{ max }}.
{{ state_with_max_casualties }} has the maximum number of deaths,
i.e. {{ max_casualties
}} due to COVID-19.
- This is based on data provided by the Ministry of Health & Family Welfare as on {{ stats_as_on_date }}.


Using online encryption, this os one of the best best encryption algorithms (AES).
Completely free service to encrypt and decrypt your text message, use without any of your sensitive information being sent to our servers.
AES 128
AES (Advanced Encryption Standard), a most popular encryption, approved by the US NSA for internal usage. See Tech Details
No Software Installation
Encrypting in web browser, using Javascript implementation. Doesn't require any installation. All data stays on your computer, nothing transferred to our servers
Most of our communication channels can be easily accessed by third-parties, not only government and your internet provider, but by your friends and family (if we're talking about social networks or your personal computer). By using this tool you could encrypt sensitive information with secure AES cipher, so nobody will get access to it without knowing original password.
this is a service for securing text messages in an easy way. It could encrypt your message using strong encryption algorithms, so it will be more secure to send or store, than in plain text. Anyone who will get access to the encrypted message, will be unable to read original message without knowing your password.
Text to encrypt (or encrypted code to decrypt):
FAQ
What encryption algorithm is used for encryption?
AES 128, with a random Initialization Vector and PBKDF2 for key. Result is encoded in Base64. See details
Is it safe?
No effective cryptanalysis of AES cipher is known to date, it's officially recommended by many security agencies (including NSA). It's more than enough, it could take billions of years for a Brute Force attack to find a password to decrypt original message.
What 'Browser encryption' means?
If you have a modern browser all encryption/description will be done in browser, on your computer. No data going to be sent to the server. Of course Javascript shouldn't be disabled.
Do you store a copy of my message or password?
No, I don't. Also, as you're using client-side encryption (Browser encryption), it's safe, it doesn't send any data to our servers. You even can disconnect from the internet after opening this page, and encrypt being completely offline. So you'll be sure that I don't have a copy of your data or password.
I forgot my password. Can you restore my message for me?
No, I can't.
I really need it. I'll pay for restoring lost password
Sorry, I really cannot help with it. I don't have your password or your data. I'm unable to decrypt it if you lost your password. Sorry.


--- layout: default ---
Welcome to my little site!
College projects I feel like sharing.
Here's some homebrew content I made for D&D 5e:


|
MOTS Finder
Find non-star-shaped MOTSs
|
Helper class to apply an offset to a specific derivative of a function. More...
Public Member Functions | |
| def | __init__ (self, f, diff, eps=0) |
| Create a callable and modify one derivative order. More... | |
| def | __call__ (self, x) |
| Evaluate the function at a point. More... | |
| def | diff (self, x, n=1) |
| Evaluate the n'the derivaative of the function at a point. More... | |
Public Attributes | |
| eps | |
| The value to add to the specified derivative order. More... | |
Private Attributes | |
| _f | |
| The function to wrap. More... | |
| _diff | |
The derivative order of the function to add eps to. More... | |
Helper class to apply an offset to a specific derivative of a function.
Given a function f
, an offset eps
is applied to the n'th derivative of the function. Here n
is given by the diff
parameter.
This is used to compute the finite difference approximation of the derivative of the expansion w.r.t. , , and .
| def __init__ | ( | self, | |
| f, | |||
| diff, | |||
eps = 0 |
|||
| ) |
Create a callable and modify one derivative order.
| f | Callable that should also implement f.diff() , e.g. an evaluator of the motsfinder.exprs system. |
| diff | Derivative order of f to modify. 0 means that eps will be added to any function value computed by f but not to derivatives. A value of n>0 means that f and all its derivatives are returned "as is", except for the n'th derivative to which the value of eps will be added. |
| eps | Value to add to the results of computing the diff 'th derivative of f . |
| def __call__ | ( | self, | |
| x | |||
| ) |
Evaluate the function at a point.
In case diff==0
, the eps
will be added.
| def diff | ( | self, | |
| x, | |||
n = 1 |
|||
| ) |
Evaluate the n'the derivaative of the function at a point.
In case diff==n
, the eps
will be added.
|
private |
The derivative order of the function to add eps
to.
|
private |
The function to wrap.
| eps |
The value to add to the specified derivative order.


The MediaEval Multimedia Evaluation benchmark offers tasks that are related to multimedia retrieval, analysis, and exploration. Participation is open to interested researchers who register. MediaEval focuses specifically on the human and social aspects of multimedia, and on multimedia systems that serve users. They offer the opportunity for researchers to tackle challenges that bring together multiple modalities (visual, text, music, sensor data).
The MediaEval 2020 Workshop took place 14-15 December 2020 fully online.
Workshop group photo:
MediaEval is made possible by the efforts of a larger number of task organizers, who each are responsible for organizing their own tasks. Please see the individual task pages for their name. The over all coordination is carried out by the MediaEval Logistics Committe and guided by the Community Council.
MediaEval is grateful for the support of ACM Special Interest Group on Multimedia
For more information, contact m.larson (at) ru.cs.nl. You can also follow us on Twitter @multimediaeval
The Emotional Mario task explores the use of human emotion to improve the performance of AI-based agents playing Super Mario Bros. We provide a multimodal dataset consisting of video and sensor data to be used to complete two different subtasks.
Read more.We invite the participants to try their skills in building a classifier to predict the emotions and themes conveyed in a music recording, using our dataset of music audio, pre-computed audio features, and tag annotations (e.g., happy, sad, melancholic). All data we provide comes from Jamendo, an online platform for music under Creative Commons licenses.
Read more.Spontaneous and intentional digital Fake News wildfires over on-line social media can be as dangerous as natural fires. A new generation of data mining and analysis algorithms is required for early detection and tracking of information waves. This task focuses on the analysis of tweets around Coronavirus and 5G conspiracy theories in order to detect misinformation spreaders.
Read more.Floods are one of the most common natural disasters that occur on our planet, and the destruction they cause is enormous. In this task, the participants receive a set of Twitter posts (tweets), including text, images, and other metadata, and are asked to automatically identify which posts are truly relevant to flooding incidents in the specific area of Northeastern Italy. The ground truth labels have been created by experts in flood risk management. The ultimate aim of this task is to develop technology that will support experts in flood disaster management.
Read more.The quality of the air that we breathe as individuals as we go about our daily lives is important for health and wellbeing, However, measuring personal air quality remains a challenge. This task investigates the prediction of personal air quality using open data or data from lifelogs. The data includes images, tags, physiological data, and sensor readings.
Read more.The fight against colorectal cancer requires better diagnosis tools. Computer-aided diagnosis systems can reduce the chance that diagnosticians overlook a polyp during a colonoscopy. This task focuses on robust and efficient algorithms for polyp segmentation. The data consists of a large number of endoscopic images of the colon.
Read more.Images play an important role in online news articles and news consumption patterns. This task aims to achieve additional insight about this role. Participants are supplied with a large set of articles (including text body, and headlines) and the accompanying images. The task requires participants to predict which image was used to accompany each article and also predict frequently clicked articles on the basis of accompanying images.
Read more.Participants receive videos (top view) and sensor readings (acceleration and proximity) of people having conversations in a natural social setting and are required to detect speaking turns. No audio signal is available for use. The task encourages research on better privacy preservation during recordings made to study social interactions, and has the potential to scale to settings where recording audio may be impractical.
Read more.In this task, participants develop adversarial approaches that camouflage the quality of images. A camouflaged image appears to be unchanged, or even enhanced, to the human eye. At the same time, the image will fool a Blind Image Quality Assessment algorithm into predicting that its quality is low. Quality camouflage will help to ensure that personal photos, e.g., vacation photos depicting people, are less easily findable via image search engines.
Read more.The task requires participants to automatically predict memorability scores for videos, that reflect the probability for a video to be remembered. Participants will be provided with an extensive data set of videos with memorability annotations, related information, and pre-extracted state-of-the-art visual features.
Read more.Tourist photography is due for a makeover, as people increasingly avoid travel due to environmental or safety concerns. In this task, participants create image composites: given a photo of a person, they must change the background to a popular tourist site. The special twist: a Scene Change photo must be fun without being deceptive. In other words, the photo fools you at first, but is identifiable as a composite upon closer inspection.
Read more.Participants are provided with a set of videos of table tennis games and are required to build a classification system that automatically labels video segments with the strokes that players can be seen using in those segments. The ultimate goal of this research is to produce automatic annotation tools for sport faculties, local clubs and associations to help coaches to better assess and advise athletes during training.
Read more.


This sequence of operations demonstrates the use of Backbone Relational Views. The rendered output is displayed on the left, and the operations executed on the right. See the Javascript
source code for the model and view definitions that are used in this demo.


{% load admin_urls %} There are {{ user_count }} users awaiting approval for the BRCA Exchange community pages. You can approve them by logging in to the admin site.


--- layout: default title: Encore Search | Glynnis Ritchie ---
Rackspace, the largest managed cloud provider, counts fanatical support as its leading differentiator. Customers can call in 24/7/365 and expect to reach someone—no pressing zero for an agent, no decision trees. The Phone Team’s methodology for routing customer calls required weeks of training, antiquated manual systems, and a lot of tribal knowledge.
With different portals for different account types, the Phone Team searched several legacy systems to locate a customer’s account information just to identify which specialist to connect with the customer.
The Phone Team’s original request: to improve integration of Rackspace’s phone system with multiple customer relationship management systems. “Oh,” they said, “we also need improved search capabilities so that we assist customers more quickly.”
It’s often the “Oh, and…” requests from clients that expose the real problems that need to be addressed. It takes careful listening to hear beyond the client’s proposed solutions and uncover the real problem at hand.
It’s often the “Oh, and…” requests from clients that expose the real problems that need to be addressed.
The challenge:
Following an expansive research effort to illuminate pain points and areas of inefficiency on Rackspace’s support floor, The Encore Search project brought several high-performing teams together. Few team members had engaged in cross-disciplinary work to the extent that the Encore Search project demanded or worked on a team so big.
At such a large company, designers and developers had grown accustomed to working in silos to make incremental improvements to legacy applications. Few were prepared to collaborate with coworkers who didn’t share their expertise and were unaccustomed to the level of interdisciplinary collaboration the project demanded. As someone with both a design and development background, I worked to “grease the wheels” between software developers and designers.
As someone with both a design and development background, I worked to “grease the wheels” between software developers and designers.
I participated in the design process, wrote CSS, sped up design revisions, and improved handoff between design and development.
In the months leading up to the project, I participated in multiple research sessions led by Rackspace’s UX Research Team. Using the framework and rubric they defined, I conducted extensive interviews with Rackers across the Support Floor. I presented findings to the development team to provide them valuable context they needed for collaboration during the sprint.
I uncovered assumptions during the initial sprint and worked with the customer and the UI, API, and design teams to gather requirements. I communicated across teams to understand the underlying systems, vet technical feasibility, and create a shared understanding of the problems we needed to solve to deliver a useful tool to the customer in the time available.
I uncovered assumptions during the initial sprint and worked with the customer and the UI, API, and design teams to gather requirements. I communicated across teams to understand the underlying systems, vet technical feasibility, and create a shared understanding of the problems we needed to solve to deliver a useful tool to the customer in the time available.
I wrote LESS and HTML to implement designs created by the visual design team, and collaborated to adjust font sizes, color, animations, etc. in the browser to match their intent. I reviewed front-end code written by other software developers to ensure consistency. In cases where visual designers had overlooked interactive states (loading, error, hover, etc.), I defined what was needed and served as facilitator between the development and design teams.
I facilitated discussion and led collaboration between product management and the UI, API, and design teams during the initial sprint and throughout the life cycle of the project. I presented work to gain buy-in from stakeholders and senior executives at the highest levels of the company.
Despite leveraging legacy systems, we’d be starting from scratch to imagine a new tool. Our customer, the Phone Team, had never used software custom-built for their workflow, and instead were forced to use existing ineffecient tools and manual workflows to accomplish tasks.
Particularly stunning was Research’s finding that the Phone Team relied on monthly email distribution of a 20-slide deck detailing names and phone numbers of key people and departments within the company where they may need to route customer calls. Often the slide deck was printed so Rackers could shuffle through the pages at their desks while on a call. All this to connect a call after they had searched up to four legacy systems to locate the customer’s account.
We had a hard deadline that required us to deliver something to the customer before the end of the year, giving us roughly four months from kick-off to release, with a few weeks at the tail end for user acceptance testing and bug squashing before closing out business for the year.
Armed with research findings and the Phone Team’s request to focus on improving search, the team assembled to kick off the project with a five-day sprint. We arrived on Monday morning and the project began with no design, no interface, no back end, no UI, no API, very few requirements, and only a high-level request from the customer.
Following the framework outlined in Jake Knapp’s book Sprint: Solve Big Problems and Test New Ideas in Just Five Days, we mapped the problem, sketched detailed solutions, vetted technical feasibility, created prototypes, and demonstrated our work to senior leadership in just five days.
We mapped the problem, sketched detailed solutions, vetted technical feasibility, created prototypes, and demonstrated our work to senior leadership in just five days.
With all hands on deck for the sprint, we found ourselves all in one room surrounded by whiteboards, ready to work but not quite sure where to begin. Product management, API developers, UI developers, interns, designers—we had all assembled to solve the Phone Team’s search problem, but initially struggled in fits and starts to focus with so many disciplines present. As the only team member with both design and development expertise, I led the effort to uncover requirements for the project and kickstarted collaboration.
After introductions and some false starts, I walked to the white board with a marker in hand and drew a high-level user journey to illustrate the steps the Phone Team might take in their work flow if we provided them with a search-centric application. The flow, with revisions and contributions from the team, became a touchstone we returned to throughout the project.
Throughout the one-week sprint, we found a natural cadence of splitting to work as independent disciplines (design, UI, API dev, etc.) and coming back together to make sure we were still in sync. In this way, we quickly made major decisions about the structure of the API, the look and feel of the interface, and the search algorithm while maintaining unity of vision and shared momentum. Tight feedback loops and collaboration across disciplines made Encore Search a strong tool from the very beginning.
Tight feedback loops and collaboration across disciplines made Encore Search a strong tool from the very beginning.
Throughout the sprint, the leader and key members of the Phone Team would join us for half an hour to answer questions about their workflow, validate sketches and design ideas, and verify assumptions the team made about their needs. We also referred back to the study completed earlier in the year and the findings associated with the Phone Team.
The vision for Encore Search: to help the Phone Team find accounts, verify customers, and transfer calls to the right specialist who could help them with whatever they were calling about.
We didn’t want to provide yet another tool in the arsenal of portals, legacy systems, and shadow IT the Phone Team needed to access with every customer call. Rather, we wanted to provide a single tool that simplified their workflow, anticipated their needs, and made it easy and fast to help customers.
We wanted to provide a single tool that simplified their workflow, anticipated their needs, and made it easy and fast to help customers.
Encore Search serves as an elastic search portal for cloud, managed, and hybrid customer accounts, which previously were not searchable within the same interface. With search suggestions and a multi-paneled interface, users can easily find customer information even with scanty search terms and confirm they’ve located the correct account. With a unified, global search and a snappy API and interface, the Phone Team can help connect customers to account specialists more quickly than ever before.
Search suggestions display as the user types in the search box, helping them find the correct customer account quickly, regardless of type.
The progressive disclosure of the paneled interface makes it easy for the Phone Team to locate related accounts and confirm they’ve found the correct result.
An overview of just the right amount of information provides enough context to the Phone Team. If more detail is needed, it’s easy to jump to other portals and legacy tools to find a specific support ticket or invoice.
The Phone Team uses Encore Search all day every day to do their jobs. They’re tech savvy experts who love shortcuts and expect a high degree of control. Encore Search is easy and intuitive to use, but provides shortcuts and jumps in workflows for expert users.
Once we secured buy-in from senior leadership following our kick-off sprint, I worked closely with product management and the engineering teams to continue collaboration and transparent communication. The API, UI, and design teams shared agile sprint cycles with the same product manager. We followed agile methodology with short, iterative release cycles, two-week sprints, and regular demos to management and the larger team.
We began prototyping in the browser as soon as possible, first with dummy API responses until the real thing was available. Tight feedback loops between development and design made pivots due to technical hurdles or scope adjustment quick and easy.
As the sole member of the team with a strong understanding of both the development and design disciplines, I translated requests and responses between teams. I often interpreted design intent to developers struggling to implement interactive features designers hadn’t anticipated, or translated technical limitations to designers so they could adjust their mock-ups.
I often interpreted design intent to developers struggling to implement interactive features designers hadn’t anticipated, or translated technical limitations to designers so they could adjust their mock-ups.
My involvement aligned development, product, design, and customer on an aggressive timeline.
Few examples of search across such a large, specific data set existed. Though commercial sites and search engines offered some ideas, most search interactions accommodate users who are browsing and refining rather than trying to locate a single, specific result among a mountain of data. Designing Encore Search brought the differences in commerical and retail design vs. enterprise design of internal tools into stark relief.
Most search interactions accommodated users who were browsing and refining rather than trying to locate a single, specific result among a mountain of data.
I knew we needed a powerful yet intuitive search tool. I turned to other data-rich search experiences: email clients, chat applications, advanced search for libraries and search engines, and filtering and refinement sidebars for large retail sites. These search applications served as inspiration for the Encore Search interaction and flow, coupled with progressive disclosure and Rackspace-specific creative adjustments.
During the kick-off sprint, I led discussion to nail down the details of what information the Phone Team needed to access in order to transfer customers to the right people. After speaking with members of the Phone Team to verify our assumptions and understand their needs, I led designers and developers to work together—what information could the API provide, where should the information be displayed, and were certain ideas designers had for interaction possible to build on our aggressive timeline?
By collaborating closely with the API and UI teams, we were able to vet sketches early and understand the limitations of what was achievable on the project’s aggressive timeline. White board sketches laid the foundation for what the team presented to senior leadership at the end of the week.
By collaborating closely with the API and UI teams, we were able to vet sketches early and understand the limitations of what was achievable on the project’s aggressive timeline.
Using low-fidelity wireframes and animations in Keynote, we showcased our vision for the experience and interaction of Encore Search to senior leadership at the end of that first sprint week. Though there were certainly changes and refinements, it was easy to see, even at that early stage, the skeleton of the final experience we delivered to the Phone Team four months later.
After the kick-off sprint and buy-in from leadership, the team got to work. With knowledge of what the UI team needed returned from the API, the API team worked to leverage legacy systems and existing API teams to return the data needed more quickly than existing tools. With the vision provided by rough wireframes produced during the sprint, the UI team began developing the paneled interface and animations required that had no precedent in the existing ecosystem of internal tools. The design team got to work refining the wireframes with user feedback and began to apply color and font choices to create high-fidelity mock-ups and specs for the UI team.
Though teams worked concurrently and independently, we shared scrum meetings and held regular demos of progress to keep communication clear. During this phase of the project, I vetted visual designs and offered critiques. I helped visual designers understand what specifications needed to be communicated to developers, and which ideas for interaction might increase level of effort or affect project scope.
The panel interaction, while a creative solution for progressive disclosure and way-finding through search results, presented challenges from a user experience perspective. We had found a solution that helped the Phone Team zero in on the correct search result, but panels had certain ramifications as an interface choice. For instance, if a user found a result and opened several subsequent panels to see more detail, what should happen when they close the initial result panel? Would they expect the subsequent panels to remain open?
The design team spent time testing this interaction thoroughly with users to gauge their expectations. I facilitated conversations with the UI team to understand what options were fastest to implement that would still match user expectations. Through negotiation, early prototypes in the browser, and productive compromise, we arrived at a solution.
Encore Search shipped on time. The Phone Team was delighted with the experience, which gave them a single tool to replace multiple legacy systems. The user flow of locating customer data to route a call was reduced from four tools and 16 screens to one tool and one screen. Call time was decreased by 75%, saving the company $220k per year and saving customers 3,507 hours. With the time saved, the Phone Team was able to accept more calls than ever before.
Following launch, word spread quickly about a fast new search tool, and within weeks Rackers across the support floor—not just the Phone Team—began using Encore Search as part of their daily work flow. Its successful release kicked off plans to retire legacy systems and phase out clunky, expensive interfaces.
The highest levels of senior leadership recognized Encore Search as a tremendous success. The designers and developers on the project received a Rackem Award for Service Delivery Innovation from the senior leadership team for work on a critical and high-impact project.
Josh Schairbaum, a Director of Software Development in Racker Tools who worked with the team, wrote, “We’ve taken a significant problem leading to poor customer experience inside Rackspace and used our particular set of skills to provide a solution that is performant, maintainable, and extensible. It’s going to be the foundation for many of the things we do in the coming months and will be a day-to-day fixture for almost every Racker.”
[The new tool] is going to be the foundation for many of the things we do in the coming months and will be a day-to-day fixture for almost every Racker.
To share our success and highlight the processes and ways of working, I gave a talk at RAX.io, Rackspace’s internal conference. Though the majority of attendees and talks have a development focus, our talk “The Secret Sauce: Bridging the Gap Between Development and Design,” focused on design processes and cross-team collaboration. With Eric Weidner, Encore Search’s visual designer, I shared how we worked from the outside in, what processes we used, and how others could use the same approach on their teams.
As Schairbaum hinted following release, Encore Search went on to become a powerful tool used daily on the support floor, and inspired subsequent projects to tailor the experience for users beyond the Phone Team. The Encore Search interface became the foundation for several other tools, including Dispatch, a tool for logging interactions with customers outside of support tickets, and Origin, an extendable application frame and platform to unite legacy tools in a single interface until they could be redesigned or retired.


Copyright © 2007 Mochi Media, Inc.
Authors: Bob Ippolito (bob@mochimedia.com).
abstract datatype: headers()
key() = atom() | binary() | string()
value() = atom() | binary() | string() | integer()
| default/3 | Insert the pair into the headers if it does not already exist. |
| default_from_list/2 | Insert pairs into the headers for keys that do not already exist. |
| empty/0 | Create an empty headers structure. |
| enter/3 | Insert the pair into the headers, replacing any pre-existing key. |
| enter_from_list/2 | Insert pairs into the headers, replace any values for existing keys. |
| from_list/1 | Construct a headers() from the given list. |
| get_primary_value/2 | Return the value of the given header up to the first semicolon using a case insensitive search. |
| get_value/2 | Return the value of the given header using a case insensitive search. |
| insert/3 | Insert the pair into the headers, merging with any pre-existing key. |
| lookup/2 | Return the case preserved key and value for the given header using a case insensitive search. |
| make/1 | Construct a headers() from the given list. |
| test/0 | Run tests for this module. |
| to_list/1 | Return the contents of the headers. |
Insert the pair into the headers if it does not already exist.
Insert pairs into the headers for keys that do not already exist.
empty() -> headers()
Create an empty headers structure.
Insert the pair into the headers, replacing any pre-existing key.
Insert pairs into the headers, replace any values for existing keys.
Construct a headers() from the given list.
Return the value of the given header up to the first semicolon using a case insensitive search. undefined will be returned for keys that are not present.
Return the value of the given header using a case insensitive search. undefined will be returned for keys that are not present.
Insert the pair into the headers, merging with any pre-existing key. A merge is done with Value = V0 ++ ", " ++ V1.
Return the case preserved key and value for the given header using a case insensitive search. none will be returned for keys that are not present.
Construct a headers() from the given list.
test() -> ok
Run tests for this module.
Return the contents of the headers. The keys will be the exact key that was first inserted (e.g. may be an atom or binary, case is preserved).
Generated by EDoc, Sep 8 2009, 13:22:29.


Primer defines a pattern for template extension that relies on convention. The following variables get passed into the template context. They are part of the request.primer
dict and can be modified in any view before they ever hit the templates.
| Template Var | Template Paths | Description |
|---|---|---|
| skeleton_template | ['skeleton.html', 'primer/skeleton.html'] | This is the HTML skeleton for a site. It includes block tags for injecting things into the head of your document and includes all of Primers css and scripts. You can override Primer's by creating your own 'skeleton.html' file. |
| base_template | ['base.html', 'primer/base.html'] | This is a layout for your site. In a typical example, it would possibly include a header, content area, and footer, but it could be anything. It should extend skeleton_template. There is a default layout in primer for you to use if you don't define your own. This needs to contain an empty block called app_content .
This template path will be automatically switched to Django's default login template if authentication is required registration/login.html . |
| site_template | [current_site_name + '/site.html', 'site.html', base_template] | This is an optional but extremely useful template to include. This is a good place to add global site specific css and javascript files that all of your app_templates will extend. If you are using Primer's default base_template this is a great place to define your nav, navbar header, etc. |
| app_template | [appname + '/base.html', base_template] | This template should extend base_template. This wil be a template that is located in a template directory that has the same name as your current app. This is a framing for your app. For instance, if you have an message style app for your site, this might represent the outside nav and menu, while the content of the individual sections is handled by the view_template. If not present, it defaults to whatever base_template is. This needs to contain a block called app_content which will include all of the contents of your apps html as well as an empty block called content . |
| view_template | [appname + '/view_name.html', view_name + '.html'] | This is the first point of contact from your view. It should extend app_template. It represents the content of your current view. In the example of the message app, this could be your actual inbox, or a sent messages area. This needs to include a block called content . |
If you want to dynamically swap out or override a template, you can do so anywhere you have access to Django's request variable.
# in some view request.primer['app_template'] = 'base/app_layout.html' request.primer['base_template'] = 'alt_base.html'