Gateway
BOT
07-Oct-18 03:53 PM
[telegram] <krisninakos> komodo wallet agama
[telegram] <krisninakos> but i have one connection only and needs maybe 10000000 hours
[telegram] <krisninakos> 0.2.42
[telegram] <krisninakos> i am using the last one but only one connection should i do something add something to conf file?
[telegram] <PTYX11> The full sync usually takes 7-48 hours days depending on how fast your connection is.
[telegram] <PTYX11> How long have you been syncing?
[telegram] <krisninakos> every day 1% about
[telegram] <krisninakos> max
[telegram] <krisninakos> two days now 2%
[telegram] <krisninakos> 2.2
[telegram] <krisninakos> there is nothing you can do you have to wait 48days
[telegram] <krisninakos> ?
[telegram] <krisninakos> this is normal?
[telegram] <krisninakos> there is not bootstrap?
[telegram] <krisninakos> there is not bootstrap?
[telegram] <PTYX11> which version of the wallet are you using?
Desktop App for SuperNET DAPPs. Contribute to KomodoPlatform/Agama development by creating an account on GitHub.
Desktop App for SuperNET DAPPs. Contribute to KomodoPlatform/Agama development by creating an account on GitHub.
[telegram] <PTYX11> make sure youare on the latest version
[telegram] <Danish> Hello
[telegram] <PTYX11> and backup your wallet.dat
[telegram] <PTYX11> There is no official bootstrap. There was one but i see that it's offline.
[telegram] <krisninakos> i am on my latest i didnt send anything because never synced
[telegram] <krisninakos> i told you the latest :D
[telegram] <krisninakos> 0 2 42 c
[telegram] <PTYX11> if you have backed up your wallet.dat. remove all the files except the Komodo.conf and wallet.dat from the komodo directory
(edited)
[telegram] <PTYX11> then restart the wallet.
[telegram] <krisninakos> i dont need to backup i have zero inside so what i am doing
[telegram] <krisninakos> i am doing what you said delete everything inside except komod.conf?
[telegram] <krisninakos> i am doing what you said delete everything inside except komod.conf?
[telegram] <PTYX11> komodo.conf and wallet.dat
[telegram] <krisninakos> i have nothing is zero teh wallet.dat :P
[telegram] <PTYX11> keep those. everything else you can remove
[telegram] <krisninakos> so only komodo.conf i should keep right?
[telegram] <krisninakos> ok i am doing and restart
[telegram] <krisninakos> ok i am doing and restart
[telegram] <krisninakos> you mean komodod file
[telegram] <krisninakos> right?
[telegram] <PTYX11> i mean the directory where your wallet.dat sits.
[telegram] <threeridges> What is future of komodo? Any hope
[telegram] <krisninakos> omg
[telegram] <krisninakos> yeah i know
[telegram] <krisninakos> ok let it forget it
[telegram] <threeridges> I hv 3000
[telegram] <krisninakos> i kept conf file only there wasnot wallet because i never fill it with komodo
[telegram] <krisninakos> and now stop working absolutely
[telegram] <krisninakos> ok now starts it was stacked
[telegram] <krisninakos> ok now starts it was stucked
[telegram] <PTYX11> question: why don't you use the light wallet if you are having such a hard time with the native mode?
[telegram] <krisninakos> because someone from the team yesterday here
[telegram] <PTYX11> you dont need to sync anything with the litewallet. create the seed, login, and vioala. you're good to go.
[telegram] <krisninakos> told me only the native
[telegram] <krisninakos> really
[telegram] <krisninakos> what the difference with native
[telegram] <PTYX11> if you dont have any funds in the wallet.dat I dont see the point of using native unless you want to run a full node
[telegram] <kingsking612> Can Komodo swap names with Pirate?
[telegram] <krisninakos> he told me that he will give me his peers
[telegram] <krisninakos> full node how many kmd are
[telegram] <kingsking612>
[telegram] <krisninakos> ?
[telegram] <PTYX11> Full node means download the full blockchain
[telegram] <krisninakos> there is masternode in komodo?
[telegram] <PTYX11> it has nothing to do with masternodes
[telegram] <krisninakos> ok
[telegram] <kingsking612> Komodo is the best name in Blockchain
[telegram] <krisninakos> better to download the full blockchain for more protection
[telegram] <PTYX11> that is a misconception (re @krisninakos: better to download the full blockchain for more protection)
[telegram] <krisninakos> lokomodo (re @kingsking612: Komodo is the best name in Blockchain)
[telegram] <PTYX11> I see you are struggling with native. I suggest you use the light wallet.
[telegram] <krisninakos> ok i can also deposit and stake there
[telegram] <krisninakos> my komodo
[telegram] <krisninakos> ?or not
[telegram] <kingsking612> Lokomodo better name for pirate (re @krisninakos: lokomodo)
[telegram] <PTYX11> yes, you will accrue rewards on light mode
[telegram] <kingsking612> The light wallet works like a charm kris (re @PTYX11: I see you are struggling with native. I suggest you use the light wallet.)
[telegram] <krisninakos> you have also the light (re @kingsking612: The light wallet works like a charm kris)
[telegram] <krisninakos> but what the meaning having native if nobody can download it xoaxoa lol
[telegram] <PTYX11> native depends on connections. it also depends on your system settings. you might have an antivirus blocking the daemon. This happens often on Windows (re @krisninakos: but what the meaning having native if nobody can download it xoaxoa lol)
[telegram] <krisninakos> i dont use antivirus just the widnws defender nothing block the connection all the other wallets working perfectly
[telegram] <PTYX11> Native mode is made for those people who want to download the full bockchain. Some people choose native becuase they think it's more secure than electrumx (light mode) but that is not the case. You would help the network by running native and leaving it online forever. but most users only use the wallet for a few minutes and disconnect. hence, there is no reason for them to run a native wallet.
[telegram] <PTYX11> i'll check native mode on windows today and check if i have any isues. i haven't tested the latest wallet on native yet. (re @krisninakos: i dont use antivirus just the widnws defender nothing block the connection all the other wallets working perfectly)
[telegram] <krisninakos> ok if someone can give me peers file without hack inside please :P from the team so i can connect
[telegram] <yorklab> You only really need native if using Z-Transactions, otherwise lite is the way to go.
[telegram] <yorklab> easier to use with no fuss.
[telegram] <krisninakos> its the same amount of % staking native and light?
[telegram] <yorklab> yes, the same
[telegram] <yorklab> And you don't neet to leave it open.
[telegram] <krisninakos> how much every month 0.5%?
[telegram] <krisninakos> about
[telegram] <yorklab> I think it's 5.1% a year.
[telegram] <krisninakos> lol only?
[telegram] <krisninakos> lol only?
[telegram] <yorklab> but a little more if you claim more than once a month.
[telegram] <PTYX11> what would you prefer? 30% a year? lol (re @krisninakos: lol only?)
[telegram] <yorklab> It adds up. You claim, then accrue on the new amount.
[telegram] <krisninakos> what?
if i claim more than once a month what?
[telegram] <krisninakos> nope 30 but 10% is enough good for such a coin with power (re @PTYX11: what would you prefer? 30% a year? lol)


{% extends "socialaccount/base.html" %} {% block nav_style %} {% endblock nav_style %} {% block content %} There has been an error We've had a problem logging you in with your social account. Please go back to the log in page and try again. If you're still having problems logging in then get in touch with support. {% endblock content %}
We've had a problem logging you in with your social account. Please go back to the log in page and try again.
If you're still having problems logging in then get in touch with support.


h1
h2
h3
h4
h5
h6
p
Form
First name
Enter just “a”
Nope, read the instruction, dummy
Last name
Phone number
Select gender
Male
Female
Other
Apache
Select all that apply
Male
Female
Other
Select all that apply
Male
Female
Other
Volvo
Saab
Mercedes
Audi
Other
Select only one
SUBMIT


ATTENTION!
We are happy to inform you that next week we are launching our first magazine "ANNUSOL". Follow our news and updates.
Sincerely, your team "ANNUSOL".
ATTENTION!
We are happy to inform you that next week we are launching our first magazine "ANNUSOL". Follow our news and updates.
Sincerely, your team "ANNUSOL".


Before Change
random_state: an object of numpy.random.RandomState
"""
assert high > low, "Upper bound must be larger than lower bound"
return randint(np.floor((high-low)/q)+1, random_state) * q + low
def loguniform(low, high, random_state):
"""
After Change
q: sample step
random_state: an object of numpy.random.RandomState
"""
return np.clip(np.round(uniform(low, high, random_state) / q) * q, low, high)
def loguniform(low, high, random_state):
"""


{% load i18n %}
{% trans "Well, this is embarrassing..." %}
{% blocktrans %} It seems our servers are having issues processing new accounts right now. {% endblocktrans %}
{% blocktrans %} It's most definitely our fault, and we sincerely apologize. Our best developers are already on the case, don't worry. {% endblocktrans %}
{% blocktrans %} Please try back in an hour and hopefully everything will be fixed. We are very sorry for the inconvenience. {% endblocktrans %}


Hello there human, I'm Tyler! Nice to meet you.
If Just Took My Quiz Now You Know...
- I studied modern herbew while living in Israel.
- I currently do not have a pet but I'm gearing up to get a cat soon and name it Peeve :)
- I'm still unsure about what I want to do with my impending coding skills.
- I just got an Instapot at a White Elephant gift exchange and I can't wait to use it!
- The top item on my bucket list is going to outer space.
I'm Also An Inventor of Smile Inducing Products!
Below is a list of the top 10 things I've invented. Enjoy!
- Wiper Wave
- Bubble Alarm Clock
- Walking Desk
- Mugnet
- Bumper Lips
- Slingshot Integrated iPhone Case
- Catnip iPhone Case
- Pound It - Fist Pound iPhone App
- Bluetooth Enabled Sweet Potato Phone
- Venus Fly Trap Beer Koozie
- Toilet Bowl Night Light


MultibandCompressor → Tone
A compressor with seperate controls over low/mid/high dynamics
new
Tone.MultibandCompressor
(options)
options
{Object}
The low/mid/high compressor settings.
code
var multiband = new Tone.MultibandCompressor({
"lowFrequency" : 200,
"highFrequency" : 1300
"low" : {
"threshold" : -12
}
})
default values
low:Tone.Compressor.defaults
mid:Tone.Compressor.defaults
high:Tone.Compressor.defaults
lowFrequency:250
highFrequency:2000
members
methods


You can select which page will be displayed (dom-if do NOT restamp)
page 1
page 2
page 3
page 4
page 5
Page 0
Page 1
Page 2
Page 3
Page 4
Page 5
You can select which page will be displayed (dom-if DO restamp)
page 1
page 2
page 3
page 4
page 5
Page 0
Page 1
Page 2
Page 3
Page 4
Page 5
You can select (with attr-for-selected and fallback-selection) which page will be displayed (dom-if do NOT restamp)
page 1
page 2
page 3
page 4
page 5
Page 0
Page 1
Page 2
Page 3
Page 4
Page 5
You can select (with attr-for-selected and fallback-selection) which page will be displayed (dom-if DO restamp)
page 1
page 2
page 3
page 4
page 5
Page 0
Page 1
Page 2
Page 3
Page 4
Page 5


Your code / Environment :
Command Script
COPY
CLEAR
Windows command
|
Office command
Note: With
@echo off
you need create
.bat/.cmd
file and run it with
Administrator Privileges


PHP is a server scripting language, and a powerful tool for making dynamic and interactive Web pages. PHP is a widely-used, free, and efficient alternative to competitors such as Microsoft's ASP.
- PHP is an acronym for "PHP: Hypertext codeprocessor".
- PHP is a widely-used, open source scripting language.
- PHP files have extension ".php"
- PHP can send and receive cookies. Add, delete, modify data in your database. PHP can also be used to control user-access and encrypt data.
A PHP script can be placed anywhere in the document. A PHP script starts with <?php
and
ends with ?>
A comment in PHP code is a line that is not read/executed as part of the program. Its only purpose is to be read by someone who is looking at the code.
// This is a single-line comment.
# This is also a single-line comment.
/* This is a multiple-lines comment block
that spans over multiple
lines.
*/
In PHP, all keywords (e.g. if, else, while, echo, etc.), classes, functions, and user-defined functions are NOT case-sensitive. However; all variable names are case-sensitive.
echo "Hello World!";
Note: PHP statements end with a semicolon (;).
In PHP, a variable starts with the $
sign, followed by the name of the variable
$txt = "Hello world!";
$x = 5;
$y = 10.5;
- A variable starts with the $ sign, followed by the name of the variable
- A variable name must start with a letter or the underscore character
- A variable name cannot start with a number
- A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )
- Variable names are case-sensitive ($age and $AGE are two different variables)
if (condition) {
code to be executed if condition is true;
}
if (condition) {
code to be executed if condition is true;
} else {
code to be executed if condition is false;
}
if (condition) {
code to be executed if this condition is true;
} elseif (condition) {
code to be executed if this condition is true;
} else {
code to be executed if all conditions are false;
}
switch (n) {
case label1: code to be executed if n=label1;
break;
case label2: code to be executed if n=label2;
break;
...
default: code to be executed if n is different from all labels;
}
This is how it works: First we have a single excodession n (most often a variable), that is evaluated
once. The value of the excodession is then compared with the values for each case in the structure. If
there is a match, the block of code associated with that case is executed. Use break
to
codevent the code from running into the next case automatically. The default
statement is
used if no match is found.
The while
loop executes a block of code as long as the specified condition is true.
while (condition is true) {
code to be executed;
}
The do while
loop will always execute the block of code once, it will then check the
condition, and repeat the loop while the specified condition is true.
do {
code to be executed;
} while (condition is true);
The for
loop is used when you know in advance how many times the script should run.
for (init counter; test counter; increment counter) {
code to be executed;
}
The foreach
loop works only on arrays, and is used to loop through each key/value pair in an
array.
foreach ($array as $value) {
code to be executed;
}
Besides the built-in PHP functions, we can create our own functions. A function is a block of statements that can be used repeatedly in a program. A function will not execute immediately when a page loads. A function will be executed by a call to the function.
function functionName() {
code to be executed;
}
An array is a special variable, which can hold more than one value at a time.
In PHP, the array();
function is used to create an array
$cars = array("Volvo", "BMW", "Toyota");
The count();
function is used to return the length (the number of elements) of an array


@* * Copyright 2021 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @import forms.PreferenceForm.yesNo @import views.html.helper._ @this() @(field: Field, choices: Seq[(String, String)], question: String, inline: Boolean = false, hiddenContent: Html, legendAsHeader: Boolean = true, subtext: Option[String] = None, additionalContent: Option[Html] = None, hiddenContentError: Boolean = false )(implicit messages: Messages) @elements = @{ FieldElements(field.id, field, null, Map(), messages) }


Below are links to additional resource for LBBD Digital Insight
News Articles
The MJ.co.uk: October 2018 - Chris Naylor discusses the benefits of LBBD's Ward Level Social Progress Index and Borough Data Explorer
On London, For the Good City: October 2018 - Dave Hill shares his thoughts of Barking and Dagenham's Social Progress Index and Borough Data Explorer
Links to Barking and Dagenham Tools
Borough Data Explorer: Explore the Social Progress and Borough manifesto indicators in this interactive map created by our partners, Emu Analytics
Ward Level Social Progress Index: Explore the world's first Ward level SPI created by Barking and Dagenham's Insight Team and the Social Progress Imperative
Partners
Social Progress Imperative: Visit the home page of our partner behind the SPI. Explore the Country level Social Progress Index for the world
Emu Analytics: Visit the home page of our partner who helped to build the Borough Data Explorer. Explore some of the other projects that they are working on


Booker scores 35 as short-handed Suns beat Wolves 100-98
by BRIAN HALLMINNEAPOLIS (AP) - Devin Booker had 35 points, 12 rebounds and nine assists, and the Phoenix Suns beat the Minnesota Timberwolves 100-98 on Saturday in a matchup of short-handed teams.
Kelly Oubre Jr. added 25 points and 10 rebounds for the Suns, who had lost three in a row.
Phoenix was clinging to a 98-95 lead when Minnesota star Karl-Anthony Towns missed a 3-pointer with 9.2 seconds left from just inside the half-court line. Booker went to the line and iced the game with a pair of free throws.
Phoenix shot a season-low 34.4% from the field but tied a season low with seven turnovers. It also made 24 of 26 foul shots, outscoring Minnesota by 14 from the line.
Playing without starting point guard Ricky Rubio and center Aron Baynes, the Suns led by as many as 12 before the Timberwolves rallied.
Towns had 31 points and 17 rebounds for Minnesota, which has lost four of five. Keita Bates-Diop scored a career-high 22 points, and Andrew Wiggins added 21.
Booker just missed his first career triple-double but he answered every Minnesota challenge.
Booker’s 17 points in the third quarter helped Phoenix regain control after Minnesota tied the game. Towns hit a pair of 3s and had nine points as the Wolves went on a 15-4 run. With the game tied 65-all, the Suns finished the third on a 17-8 run as Booker scored six and Oubre had five during the stretch.
When the Wolves closed within two in the final minutes, Booker hit a teardrop jump shot in the lane over Towns. Wiggins answered but Booker was there on the other end for a pair of free throws.
TIP-INS
Suns: Rubio was out of the lineup for the third time in four games with back spasms. Baynes, who has been starting in place of the suspended Deandre Ayton, missed his third straight game with a right hip flexor strain. … Phoenix had 17 assists on 19 made field goals in the first half. The Suns finished with 22 assists on 33 makes. … Oubre is averaging 23.0 points on 45.7% shooting over his last five games. … Phoenix is in a stretch of playing five games in seven days.
Timberwolves: Minnesota was without Robert Covington (personal reasons), Josh Okogie (left knee soreness), Jake Layman (left toe sprain) and Shabazz Napier (right hamstring strain). It was the second time in four games Okogie has been out with the injury. Layman missed his second straight game. … G Treveon Graham was listed as available for the Wolves with a left arm contusion but didn’t play. … Towns has made at least three 3-pointers in eight consecutive games, the longest such streak in NBA history by a player listed as a center. He entered the day third in the league in made 3s.
UP NEXT
Suns: Finish a back-to-back set Sunday in Denver.
Timberwolves: Travel to play Atlanta on Monday.
More AP NBA: https://apnews.com/NBA and https://twitter.com/AP_Sports
Sign up for Daily Newsletters
Copyright © 2019 The Washington Times, LLC.
Please read our comment policy before commenting.


the version of the catalog to use
the type of the element
the code to search for
Get all versions supported by the catalog in the specified language
the language to get the supported versions for
Initializes the service with catalog specific parameters. Must be called before the first call to the service.
the configuration of the catalog to configure
the service with
Searches in a specific version of the catalog for the specified query.
Returns an array of search results or an empty array if no results matching the query are found.
the version of the catalog to use
the query to search for
Send information about how the user found the selected code to the eonum API.
the version of the catalog to use
the type of the element to send analytics for
the code of the element to send analytics for
the query which was used before retrieving this element
Generated using TypeDoc
Find an element in the SwissDRG catalog by its code.
Returns the element with the specified code or throws an error if the element doesn't exist.


Note: There is currently no finalized API for the charts package. The files and classes used to create this example are temporary JavaScript wrappers used to display and test the functionality of the current state of the charts package. The draft API will be announced when the first beta of the Charts component is released.
In this example, we will change the SimpleChart's default data keys and customize multiple styles. Let's start by creating a data source. We will change the item and value keys to "day" and "hours", respectively. We will need to specify these keys in our SimpleChart constructor later in the code.
var myData = { id:"myData", data: [ {day:"Monday", hours:37}, {day:"Tuesday", hours:91}, {day:"Wednesday", hours:11}, {day:"Thursday", hours:19}, {day:"Friday", hours:70} ] };
Next, we'll create a style hash that we will use to customize the following chart styles:
var myStyles = { background:{fillColor:0x22327A,borderColor:0x000000, borderWidth:5}, chart:{ padding:{bottom:25, left:25, right:25, top:25} }, graphstyles:{ color:0x7ECAFF, weight:"4" }, xaxisstyles:{ line:{color:0x7ECAFF}, majorTicks:{color:0x7ECAFF}, label:{ color:0x7ECAFF, fontName:"lucida grande", fontSize:15, rotation:-45, margin:{top:4} }, }, yaxisstyles:{ line:{color:0x7ECAFF}, majorTicks:{color:0x7ECAFF}, label:{ color:0x7ECAFF, fontName:"lucida grande", fontSize:15, margin:{right:4} }, } }
Most styles are self-explanatory; it is important to note, however, that the label margin style is used to create a space between labels and their axis.
Finally, let's construct our simple chart instance, defining the axis data keys and the styles in the optional configuration parameter of the constructor. We will also pass the key ids when setting the data source for the chart.
var mychart = new Y.SimpleChart("#testdiv", "line", {swfurl:"../build/chart/assets/cartesiancanvas.swf", xaxisprops:{key:"day"}, yaxisprops:{key:"hours"}, styles:myStyles}); mychart.setData(myData.data, "day", "hours");


Generate the base64 of the whole file is problematic and might crash your browser if the file is too big. It would be find if you generate it part by part.


GitHub Activity Checker
search
close
comment
Name
Message
Email
Must be a valid email address
Thanks for submitting your response!
mood
arrow_upward


The purpose of this website is to help the weakest part of population find a person who wants to perform the services they need
© Untitled. All rights reserved. | Photos by Fotogrph | Design by TEMPLATED.


Customer Information
First name
Last name
Address
Apt, suite, etc.
City
Country
Canada
---
Australia
Brazil
Canada
China
France
Germany
India
United Kingdom
United States
Province
Postal code
Phone
Submit


Testing streams
Verifying behaviour of Akka Stream sources, flows and sinks can be done using various code patterns and libraries. Here we will discuss testing these elements using:
- simple sources, sinks and flows;
- sources and sinks in combination with TestProbe from the akka-testkit module;
- sources and sinks specifically crafted for writing tests from the akka-stream-testkit module.
It is important to keep your data processing pipeline as separate sources, flows and sinks. This makes them easily testable by wiring them up to other sources or sinks, or some test harnesses that akka-testkit or akka-stream-testkit provide.
Built in sources, sinks and combinators
Testing a custom sink can be as simple as attaching a source that emits elements from a predefined collection, running a constructed test flow and asserting on the results that sink produced. Here is an example of a test for a sink:
val sinkUnderTest = Flow[Int].map(_ * 2).toMat(Sink.fold(0)(_ + _))(Keep.right)
val future = Source(1 to 4).runWith(sinkUnderTest)
val result = Await.result(future, 3.seconds)
assert(result == 20)
The same strategy can be applied for sources as well. In the next example we have a source that produces an infinite stream of elements. Such source can be tested by asserting that first arbitrary number of elements hold some condition. Here the take combinator and Sink.seq are very useful.
import system.dispatcher
import akka.pattern.pipe
val sourceUnderTest = Source.repeat(1).map(_ * 2)
val future = sourceUnderTest.take(10).runWith(Sink.seq)
val result = Await.result(future, 3.seconds)
assert(result == Seq.fill(10)(2))
When testing a flow we need to attach a source and a sink. As both stream ends are under our control, we can choose sources that tests various edge cases of the flow and sinks that ease assertions.
val flowUnderTest = Flow[Int].takeWhile(_ < 5)
val future = Source(1 to 10).via(flowUnderTest).runWith(Sink.fold(Seq.empty[Int])(_ :+ _))
val result = Await.result(future, 3.seconds)
assert(result == (1 to 4))
TestKit
Akka Stream offers integration with Actors out of the box. This support can be used for writing stream tests that use familiar TestProbe from the akka-testkit API.
One of the more straightforward tests would be to materialize stream to a Future and then use pipe pattern to pipe the result of that future to the probe.
import system.dispatcher
import akka.pattern.pipe
val sourceUnderTest = Source(1 to 4).grouped(2)
val probe = TestProbe()
sourceUnderTest.runWith(Sink.seq).pipeTo(probe.ref)
probe.expectMsg(3.seconds, Seq(Seq(1, 2), Seq(3, 4)))
Instead of materializing to a future, we can use a Sink.actorRef that sends all incoming elements to the given ActorRef. Now we can use assertion methods on TestProbe and expect elements one by one as they arrive. We can also assert stream completion by expecting for onCompleteMessage which was given to Sink.actorRef.
case object Tick
val sourceUnderTest = Source.tick(0.seconds, 200.millis, Tick)
val probe = TestProbe()
val cancellable = sourceUnderTest.to(Sink.actorRef(probe.ref, "completed")).run()
probe.expectMsg(1.second, Tick)
probe.expectNoMsg(100.millis)
probe.expectMsg(3.seconds, Tick)
cancellable.cancel()
probe.expectMsg(3.seconds, "completed")
Similarly to Sink.actorRef that provides control over received elements, we can use Source.actorRef and have full control over elements to be sent.
val sinkUnderTest = Flow[Int].map(_.toString).toMat(Sink.fold("")(_ + _))(Keep.right)
val (ref, future) = Source.actorRef(8, OverflowStrategy.fail)
.toMat(sinkUnderTest)(Keep.both).run()
ref ! 1
ref ! 2
ref ! 3
ref ! akka.actor.Status.Success("done")
val result = Await.result(future, 3.seconds)
assert(result == "123")
Streams TestKit
You may have noticed various code patterns that emerge when testing stream pipelines. Akka Stream has a separate akka-stream-testkit module that provides tools specifically for writing stream tests. This module comes with two main components that are TestSource and TestSink which provide sources and sinks that materialize to probes that allow fluent API.
Note
Be sure to add the module akka-stream-testkit to your dependencies.
A sink returned by TestSink.probe allows manual control over demand and assertions over elements coming downstream.
val sourceUnderTest = Source(1 to 4).filter(_ % 2 == 0).map(_ * 2)
sourceUnderTest
.runWith(TestSink.probe[Int])
.request(2)
.expectNext(4, 8)
.expectComplete()
A source returned by TestSource.probe can be used for asserting demand or controlling when stream is completed or ended with an error.
val sinkUnderTest = Sink.cancelled
TestSource.probe[Int]
.toMat(sinkUnderTest)(Keep.left)
.run()
.expectCancellation()
You can also inject exceptions and test sink behaviour on error conditions.
val sinkUnderTest = Sink.head[Int]
val (probe, future) = TestSource.probe[Int]
.toMat(sinkUnderTest)(Keep.both)
.run()
probe.sendError(new Exception("boom"))
Await.ready(future, 3.seconds)
val Failure(exception) = future.value.get
assert(exception.getMessage == "boom")
Test source and sink can be used together in combination when testing flows.
val flowUnderTest = Flow[Int].mapAsyncUnordered(2) { sleep =>
pattern.after(10.millis * sleep, using = system.scheduler)(Future.successful(sleep))
}
val (pub, sub) = TestSource.probe[Int]
.via(flowUnderTest)
.toMat(TestSink.probe[Int])(Keep.both)
.run()
sub.request(n = 3)
pub.sendNext(3)
pub.sendNext(2)
pub.sendNext(1)
sub.expectNextUnordered(1, 2, 3)
pub.sendError(new Exception("Power surge in the linear subroutine C-47!"))
val ex = sub.expectError()
assert(ex.getMessage.contains("C-47"))
Fuzzing Mode
For testing, it is possible to enable a special stream execution mode that exercises concurrent execution paths more aggressively (at the cost of reduced performance) and therefore helps exposing race conditions in tests. To enable this setting add the following line to your configuration:
akka.stream.materializer.debug.fuzzing-mode = on
Warning
Never use this setting in production or benchmarks. This is a testing tool to provide more coverage of your code during tests, but it reduces the throughput of streams. A warning message will be logged if you have this setting enabled.
Contents


We have won numerous awards and participated in many major projects. Click below to see all of our awards and projects.
Awards and projectsWe offer elevator service for corporate buildings.
READ MOREHere at Rocket Elevators, we provide only the highest standard of service.
Krista Sheely CEO of Rocket ElevatorsSafety is our number one priority among anything else.
Clayton Steinocher Employee of the Month.Address: 418-725 Boulevard Lebourgneuf, Québec, QC G2J 0C4, Canada Phone:<PHONE_NUMBER> Email: info@codeboxx.biz


Tari Protocol Discussion 38
On Thursday, the Tari community discussed the initial draft of RFC-0322. Below is the TL;DR on Thursday’s conversation (full transcript included below):
- General draft looks good
- Draft will be merged in with minor tweaks done via additional PR’s
Join us for our next discussion on Freenode in #tari-dev.
Discussion times proposed by the Tari community:
Mondays: 6pm CAT (12pm EST)
Thursdays: 11am CAT (5am EST)
To keep up with the latest Tari developments, you can follow the project on Twitter.
Transcript of Thursday’s discussion
11:09 <@CjS77> I've gathered Monday's thoughts together into an RFC draft: https://github.com/tari-project/tari/pull/315
Initial draft of RFC-0322 by CjS77 · Pull Request #315 · tari-project/tari
A rough initial draft of the Validator registration process. Description Motivation and Context How Has This Been Tested? Types of changes Bug fix (non-breaking change which fixes an issu...
11:11 <simian_za> Looking good, failing some tests though. Impressive for an RFC doc
11:12 <neonknight64> I like that the VN registration can be renewed without it resulting in a NodeID change
11:13 <Blackwolfsa> Yeah I think it's an important required feature
11:13 <Hansie> I like the `A counter indicating that this is the n-th consecutive renewal.` part
11:14 <Hansie> Would be really valuable for the Tari eco system, AIs as well as users.
11:14 <simian_za> So we are going to create a chain of kernels that keep track of how many times a given VN registration has been renewed?
11:15 <@CjS77> I'd like to invite folks to think of attacks that could exploit the registration process as currently described
11:15 <Hansie> Yip, that is really cool
11:16 <Hansie> Would `VN_Deposit` be market driven?
11:18 <@CjS77> You may notice, a pro of this approach: Changes in the registration deposit are elegantly handled
11:19 <@CjS77> I don't think there's that much of a supply-demand dynamic to make the deposit market driven.
11:20 <@CjS77> One of its key goals is Sybil resistance -- so the value (in Tari) may need to be adjusted from time to time (during a network upgrade) to account for any fluctuation in Tari's price
11:20 <Blackwolfsa> We should just "update" the values somehow to keep it expensive enough to be sybil resistant
11:21 <Hansie> W.r.t approach, yes, it would stay valid for the current term and if the value changed it could be adapted with the next registration.
11:24 <neonknight64> Keeping track of the number of registration renewals of a VN is a nice mechanism that Asset Issuers can use to find more "reliable" VNs
11:25 <Blackwolfsa> But it could also be seen along the lines of the rich get riches...
11:45 <neonknight64> or longer running VNs preferred over new VNs.
13:54 <@CjS77> Are we're happy to merge the draft in as is? There may be minor tweaks in future, but unless you can post comments now, I'd rather not have this sitting as a PR for too long


Bootcards is an open source project created by @markleusink, @sives and @jackherbert and sponsored by Teamstudio.
It was originally released on Monday April 14th 2014. It was created to meet Teamstudio's need for a modular user interface framework that could be used to build enterprise mobile apps very quickly. By building on top of Bootstrap, Bootcards takes advantage of Bootstrap's great capabilities, whilst adding support for the Cards design pattern.


Team7
Inventory Management
Product Name
Price
Quantity
Actions
No Inventory Items available
Product Name
Price
Quantity
Edit Product
Quantity
Quantity
+


A bundle that includes cache reads should include cache writes with the same keys.
Cache strategies that rely on external cache population can be problematic and lead to run time errors.


What is your data worth to you? Think about the files on your computer right now. Do you have a file with valuable corporate secrets? Probably not, and a hacker probably assumes that. A hacker also knows that your data has value to you. How much would you pay to get back that folder of vacation pictures? What about that semester-long project? How much would you pay someone to get back your fifteen-page paper due tomorrow? Cyber criminals know that if the price is right, you would probably pay something to get this chunk of your life back. But why wouldn't they attack some large corporation that would pay millions in ransom? Massive organizations have a lot to lose, so they hire security professionals to construct complex systems that deter attacks and mitigate damage. You, however, probably don’t have more than a simple antivirus software installed (if any). More importantly, a hacker probably doesn’t know who they’re attacking. Attacks are frequently just automated processes moving throughout the web, infecting machines as they are discovered. An automated process that attacks machines is known as a bot, and the collection of infected machines is called a botnet.
A hacked computer can provide multiple kinds of worth to cyber criminals. They could encrypt all of the computer’s data and hope the user pays a ransom, or they could pool the resources of a botnet to complete larger tasks. Malicious cryptomining, more frequently called “cryptojacking,” is any mining operation happening without the machine owner’s consent. Though we typically think that cryptomining requires massive computing rigs, it can easily be distributed among many smaller machines working in unison. A DDoS attack works best with many machines working in unison, but more importantly, the machines must be spread out across a large geographic area and connected to multiple higher-tier network services. A botnet’s power to launch a DDoS attack lies in the bandwidth of each device’s internet connection, not the speed of the device’s CPU.
The solution to this misconception is to view everything connected to the internet as a “hackable” specimen. Always change default passwords on IoT devices, and remember to regularly install security updates. For maximum protection against ransomware, keep backups of your data on flash drives or other media that is not connected to your computer. Hackers want control of your devices, no matter how small and unexciting they may seem.
On October 21, 2016, the internet went down in most of the east coast of the US. It was later revealed that someone was performing a DDoS attack against a large internet provider [1]. To perform a DDoS attack, a hacker needs control of many, many machines that are spread out over a wide area of the web. The hacker then directs their army of machines to send massive amounts of traffic to a server, overwhelming it and preventing it from sending outbound communication. All the machines in this army were IoT devices, which frequently have minimal security. Some mischievous teenagers coded a program that automatically scanned the web for IoT devices, then tested common default usernames and passwords for those devices.  Though the attack against Dyn gained the most press, the Mirai botnet executed multiple attacks over its lifetime, including attacks against Runescape, Minecraft servers in Brazil, a West African telecom company, and a Russian cooking blog [3].
In 2017, the internet service Coinhive was created as a way to mine the cryptocurrency Monero in the background of a web browser using Javascript. If this sounds sketchy, it’s because it’s very sketchy. Unlike Bitcoin, Monero transactions are kept private, making it even more attractive for cyber criminals [4]. Coinhive was a way for cyber criminals to generate dark money from the beginning; there’s no need to launder currency when it was generated in the dark. Ad blockers learned to detect and halt cryptojacking code, dealing a serious blow to Coinhive. Eventually, the value of Monero plummeted, and in 2019, Coinhive officially shut down [5].
A ransomware also known as Wanna Crypt or Decrypt0r 2.0, WannaCry began attacking Windows machines worldwide in May 2017. This ransomware gained access to machines with an exploit named EternalBlue, discovered by the National Security Agency and leaked to a malicious hacker group called the Shadow Brokers [9]. Once it had access, it installed and executed using DoublePulsar, another exploit created by NSA. Microsoft had actually already released patches for EternalBlue months earlier, meaning all victims were people who hadn't installed security updates or were running versions of Windows beyond their end-of-life. Because of the severity of this attack, Microsoft quickly released patches for out-of-date products, including Windows XP and Windows Server 2003 [10].
Among the victims was the NHS in the United Kingdom, which paid more than $100 million to recover. But this computer worm didn't just attack large organizations; many people had their personal computers compromised, any many paid the ransom. By mid June 2017, victims paid more than $130,000 in ransom [11]. Economists estimate the total economic impact of WannaCry to be more than $4 billion [12].
The year 2020 saw a milestone in ransomware history: your data could now be auctioned off! A malicious hacker group called Sodinokibi has set up an auction site on the dark web, where they now publicly auction off victims' decrypted data. In the first known auction, the bidding started at $50,000, and anyone could stop the auction early by paying $100,000. This new tactic may have been a reaction to the economic downturn of early 2020, when ransomware payments plummeted [13]. Besides increasing the potential payout, auctions provide and easy way to publicly shame people who never pay the ransom. To any mischievous readers who would consider buying someone else's stolen data: beware. Don't be surprised if a gang of criminals tries to double-cross you!
In this activity, you will learn how much power a hacker wields with a botnet. Select the type of internet device, the number of devices connected, and see what your botnet will be capable of doing.
Real-world device numbers are provided by Shodan.
Icons made by Freepik from
www.flaticon.com


You want the player to respond to pressing action (X or SPACEBAR)? It's super easy.
Edit[ Action Player | Sheep ] -> [ Action Player | > Sheep ]
[ > Sheep | Sheep ] -> [ blood | > Sheep ]
You must feel so powerful now that you know how to ACTION.
It's treated like a directional input, merely one that has no effect during the movement phase and is removed (so if you search for a moving player, it will detect someone doing an action. If you want to detect someone moving who is not doing an action, you can use the word ORTHOGONAL (which just means up/down/left/right).
Action markers are discarded during the movement phase.
TIP: If you are using action in your games, you often will want to use norepeat_action to prevent the player from repeatedly triggering the action even just by holding down action (this is especially useful when action toggles between two states - when toggling a button, say, you will probably want "one press" = "one toggle").
So, what are you going to use the action button for? For pushing crates? For swapping between characters? for pressing buttons? There are many possibilities!


MORGAN MCCRORY
PROJECTS
/
BLOG
/
ABOUT
/
CONTACT
This site is currently under construction. Please check back soon!


Ex-Arsenal boss Wenger joins Fifa as global development chief
NOVEMBER 13 — Former Arsenal manager Arsene Wenger has been appointed as Fifa’s new chief of global football development, with the Frenchman set to oversee the growth of the sport plus technical matters, soccer’s world governing body said today.
The 70-year-old was recently linked with the Bayern Munich job following the sacking of Niko Kovac but said that while he was approached he was never a candidate for the job.
Wenger will be the leading authority on technical matters on Fifa’s Football and Technical Advisory Panels involved in the International Football Association Board (IFAB) review and decision-making process on potential changes to the game’s laws.
He will also be the chair of a technical study group.
“I look forward to taking on this important challenge, not only because I have always been interested in analysing football from a broader perspective but also because Fifa’s mission... is truly global,” Wenger said in the Fifa statement.
“I believe that the new Fifa we have seen emerging in recent years has the sport itself at the heart of its objectives and is determined to develop the game in its many different components. I know I can contribute to this objective and will put all my energy into this.”
Wenger will also focus on educating coaches and contribute to the development of an executive programme that will help former professionals enter management.
Wenger left Arsenal in May last year after a reign of 22 years during which he redefined the Premier League club and became their most successful manager.
He led the Gunners to three Premier League titles — including in 2003-04 when his ‘Invincibles’ team went unbeaten for an entire season — as well as seven FA Cups and took Arsenal into the Champions League for 20 years in a row. — Reuters


{% extends "_layouts/base.html" %} {% import 'macros.html' as macros %} {% block title %}Group {{ group.name }} | {{ config.EVE.auth_name }}{% endblock %} {% block content %}
| Name | Corporation | Alliance | Application text | Applied on | Actions |
|---|---|---|---|---|---|
| {{ application.user.main_character.name }} | {{ application.user.main_character.corporation_name }} | {{ application.user.main_character.alliance_name }} | Hover for application text | {{ application.joined_on|humanize }} |
|
| No applications received. |
Because this group is hidden, you need to invite people you want in. Please start to type the first characters of their Character Name to search.
| Name | Corporation | Alliance | Invited on | Invited by | Actions |
|---|---|---|---|---|---|
| {{ invite.recipient.name }} | {{ invite.recipient.main_character.corporation_name }} | {{ invite.recipient.main_character.alliance_name }} | {{ invite.created_on|humanize }} | {{ invite.sender.name }} | |
| No invites yet... |
| Name | Corporation | Alliance | Joined on | {% if membership.is_admin or current_user.is_admin() %}Actions | {% endif %}
|---|---|---|---|---|
| {{ member.user.main_character.name }} | {{ member.user.main_character.corporation_name }} | {{ member.user.main_character.alliance_name }} | {{ member.joined_on|humanize }} | {% if membership.is_admin or current_user.is_admin() %}
{% if member.is_admin %}
{% else %}
{% endif %}
{% if member.can_ping %}
{% else %}
{% endif %}
|
{% endif %}
| No members |
This group has not made his member list public.


R% - G% - Diagram, Manual Data Input
The degree of preferred orientation and the cylindricity are written in their fields. For each pair of data you have to choose the symbol which shall be plotted from the scroll list 'symbol'. Confirm with 'ok'. The input is shown in the list field on the right side. The maximum number of data can be changed in the file Fabric7.ini.
The button 'finish input' activates the menus 'save data' and 'print'.
The button 'plot' opens the plot area.


Constructor
new cl( )
- Mixes In:
Methods
{SplitAxis} all( function callback )
Calls a callback onto each chunk axes. The callback receives two parameters: 1) the ```axis``` itself and 2) the ```index``` of the axis in the stack
Parameters:
| Name | Type | Description |
|---|---|---|
callback |
function | The callback to be applied to each axes |
Returns:
{
SplitAxis
}
The current axis instance
{SplitAxis} fixGridIntervalBasedOnAxis( Number axisIndex )
Fixes the major tick interval of all axes based on the one provided as a parameter
Parameters:
| Name | Type | Description |
|---|---|---|
axisIndex |
Number | The index of the reference axis (starting at 0) |
Returns:
{
SplitAxis
}
The current axis instance
{SplitAxis} splitAxis( )
Splits the axis into chunks at the positions defined as a list of parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
...splits |
function | The positions of axis splitting |
Returns:
{
SplitAxis
}
The current axis instance
Example
{SplitAxis} splitSpread( Boolean bln )
Spreads the chunks of the axis based on the relative interval of each one of them, so that the unit / px is constant for each chunk
Parameters:
| Name | Type | Description |
|---|---|---|
bln |
Boolean | ```true``` to enable the spread, ```false``` otherwise |
Returns:
{
SplitAxis
}
The current axis instance
{SplitAxis} setChunkBoundaries( Array.<(Array|Number)> values )
Defines the boundaries of each chunk in axis unit.
Parameters:
| Name | Type | Description |
|---|---|---|
values |
Array.<(Array|Number)> | An array of either 2-component arrays (from-to) or number (mean) |
Returns:
{
SplitAxis
}
The current axis instance


Proprietary and Confidential.
Please do not distribute.
© 2012–2013 Declarativ Inc.
HTML5 Logo by W3C


actor
The basic unit of action and presentation within a title.
actor group
See cast.
actor property
A C++ or Java member variable that is exposed to the title development team
via the authoring tools.
assets
The code and data used to build and run a Magic Lantern title. Assets include
the title executable and
dynamic software modules as well as the media (that is, 3D models and textures,
audio, images, and video).
behavior
Any procedural element that makes an actor move or otherwise change state. Although
behaviors can be
cyclic and predictable, such as pre-scripted animations, in Magic Lantern the
term is typically used to
describe more lifelike and complex actions by actors.
behavior package
A modular component for adding behaviors to an actor.
camera
A view into a 3D set.
camera actor
An actor used to vary the camera view of the 3D set.
cast
A collection of actors that are loaded into memory
at the same time.
Digital Playprint (DPP)
A runtime translation of a Digital Workprint. The Digital Playprint
is consumed by a Runtime Player.
Digital Workprint (DWP)
A repository for saved information about the development of a title
and which specifies all the resources that
accompany a title.
DLL
Acronym for Dynamic Linkable Library
DPP
See Digial Playprint.
DSO
Acronym for Dynamic Shared Object.
DWP
See Digial Workprint.
media reference
An object used to reference the representation of media across multiple platforms.
It is a pointer to an
outside media file, such as a graphics image or an audio file.
package
A Magic Lantern component used to add functionality to an actor
class.
player
A Rehearsal Player or a targeted Runtime
Player.
pull method
A method of communicating between an actor and its
role where the role explicitly
asks the actor for any
changes.
push method
A method of communicating between an actor and its
role where the actor pushes
its results to the role.
Rehearsal Player
A Magic Lantern program that plays a title on a PC or UNIX workstation. The
Rehearsal Player plays the
title using dynamic data structures and allows for
midstream property changes from the outside, such as
from an actor editor. From an interface perspective, the Rehearsal Player has
a protocol that other programs
can use to start, stop, pause, and change properties. The Rehearsal Player can
be activated from the Scene
Editor.
Runtime Player
A Magic Lantern program that plays the title using static, mastered data structures.
The Runtime Player has
no extensions for allowing an outside agent to modify or control anything happening
within the title. The
Runtime Player loads media groups and actor definitions from a Digital Playprint.
A Runtime Player refers
to a player that runs on a specific target, such as a PC, mobile device, game console,
or interactive TV set-top box.
role
The software module that handles the actors' platform-dependent
presentation on a stage.
scene
The groups (or cast) of actors that are loaded into
the title at any given time.
set
An abstract view of a collection of actors that are
presented on a stage. A set is used to manage a
presentation, such as a 3D scene-graph or 2D windowing environment.
stage
The set of services on the target platform, such as rendering, input, sound,
physical modeling, proximity and
collision detection, and event handling.
targeting process
The Magic Lantern process that generates an interactive title for its distribution
media. The targeting process
takes the Digital Workprint and its associated media
assets as input and creates three output products: the
Digital Playprint, the translated media, and the executable.
title
The application created with the Magic Lantern authoring tools.


Development
Updating the documentation
Getting the development environment up
- Fork the gh-pages branch in the the mermaid repository
- Do npm install
Working with the documentation
The html files are generated from the source and the markdown files in the docs folder. The site generation is done
using the docker.js framework with the command below.
docker -i ../mermaid/ -x "*git*|*travis*|*bin*|*dist*|*node_modules*|*gulp*|*lib*|*editor*|*conf*|*scripts*|*test*|*htmlDocs*" --extras mermaid -w -o htmlDocs
Thus ... One important thing to remember. Do not edit the html files directly! Those changes will be overwritten
when the site is re-generated.
Committing the changes
Do a pull request to merge the changes to the site.
Things to be done in order to add a new diagram type
Step 1: Grammar & Parsing
Grammar
This would be to define a jison grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
For instance:
- the flowchart starts with the keyword graph.
- the sequence diagram starts with the keyword sequenceDiagram
Store data found during parsing
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call a object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
statement
: 'participant' actor { $$='actor'; }
| signal { $$='signal'; }
| note_statement { $$='note'; }
| 'title' message { yy.setTitle($2); }
;
In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered.
Note: Make sure that the parseError function for the parser is defined and calling mermaidPAI.parseError this way a common way of detecting parse errors is provided for the end-user.
For more info look in the example diagram type:
The yy object has the following function:
exports.parseError = function(err,hash){
mermaidAPI.parseError(err,hash);
};
when parsing the yy object is initialized as per below:
var parser;
parser = exampleParser.parser;
parser.yy = db;
Step 2: Rendering
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequendeRenderer.js rather then the flowchart renderer as this is a more generic example.
Place the renderer in the diagram folder.
Step 3: Detection of the new diagram type
The second thing to do is to add the capability to detect the new new diagram to type to the detectType in utils.js. The detection should return a key for the new diagram type.
Step 4: The final piece - triggering the rendering
At this point when mermaid is trying to render the diagram, it will detect it as being of the new type but there will be no match when trying to render the diagram. To fix this add a new case in the switch statement in main.js:init this should match the diagram type returned from step number 2. The code in this new case statement should call the renderer for the diagram type with the data found by the parser as an argument.
Usage of the parser as a separate module
Setup
var graph = require('./graphDb');
var flow = require('./parser/flow');
flow.parser.yy = graph;
Parsing
flow.parser.parse(text);
Data extraction
// Javascript example
graph.getDirection();
graph.getVertices();
graph.getEdges();
The parser is also exposed in the mermaid api by calling:
var parser = mermaid.getParser();
Note that the parse needs a graph object to store the data as per:
flow.parser.yy = graph;
Look at graphDb.js for more details on that object.


Deadline Management App
Better Professor is an easy-to-use deadline management app that allows you to set custom reminders for yourself and your students.


Air quality concern at TAJ's Oxford Road offices
Staff at Tax Administration Jamaica's (TAJ) Oxford Road offices were earlier this week sent home after a number of them reported feeling ill.
Yesterday, TAJ's Chief Corporate Communications Officer Meris Haughton confirmed that the 6th and 9th floors, where TAJ offices are located, were evacuated over concerns about poor air quality.
“We have had some reports of some air quality issues at our location on the Oxford Road NCB South Towers. We have two floors on that building and based on the reports that we had gotten from persons we have, out of an abundance of caution and as a precautionary measure, asked the staff to stay home,” Haughton told the Jamaica Observer in a telephone interview.
Haughton said the issue has been a recurring one, noting that complaints have surfaced in the immediate past. As a result, she said a company has been called in to test air quality in the offices and that a report is expected to be ready today.
“I can't say much more until we get back that report from that company that we invited in to do the checks. It's because persons started feeling ill that the decision was taken. Persons were having some ill effects from whatever was in the air but we're not sure exactly what it is, so that's why we actually had the company come in to do some checks,” said Haughton.
“We have been having some issues on and off for the past week or so. So based on the occurrence, because it's not consistent... we invited the company in to do some tests,” she added.
— Kimone Francis


The following table describes the FileFormat
enumeration members:
| Member | Value | Description |
|---|---|---|
| Csv | 0 | Comma separated values (0) |
| Binary | 1 | Binary file data (1) |
| ZipEntryName | 2 | Only the zip entry names are read in as symbols (2) |
| UnfoldingCollection | 3 | Reader returns a BaseDataCollection object (3) Lean will unfold the collection and consume it as individual data points |
| Index | 4 | Data stored using an intermediate index source (4) |
| FoldingCollection | 5 | Data type inherits from BaseDataCollection. Reader method can return a non BaseDataCollection type which will be folded, based on unique time, into an instance of the data type (5) |


This example pulls three sets of data: the top 10 pages for the last thirty days on mobile, tablet, and desktop. This is, essentially, an extension of the Simple Dynamic Segment - v4 example except it uses a function to pull the data so that a list of values (“Mobile,” “Tablet”, and “Desktop”) can be processed to dynamically change the segment used to pull the data.
With the v4 API, dynamic segments are more powerful than v3, but (alas!) pretty basic segments can feel pretty convoluted. This example could also be built for v3, but we want to go forward! And, v4 is the future! Or, as an alternative, you can use the ganalytics
package, which aims to simplify this sort of work. See the Advanced Dynamic Segments with ganalytics example for an example of using ganalytics
to create dynamic segments.
Be sure you’ve completed the steps on the Initial Setup page before running this code.
For the setup, we’re going to load a few libraries, load our specific Google Analytics credentials, and then authorize with Google.
# Load the necessary libraries. These libraries aren't all necessarily required for every
# example, but, for simplicity's sake, we're going ahead and including them in every example.
# The "typical" way to load these is simply with "library([package name])." But, the handy
# thing about using the approach below -- which uses the pacman package -- is that it will
# check that each package exists and actually install any that are missing before loading
# the package.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(googleAnalyticsR, # How we actually get the Google Analytics data
tidyverse, # Includes dplyr, ggplot2, and others; very key!
devtools, # Generally handy
googleVis, # Useful for some of the visualizations
scales) # Useful for some number formatting in the visualizations
# Authorize GA. Depending on if you've done this already and a .ga-httr-oauth file has
# been saved or not, this may pop you over to a browser to authenticate.
ga_auth(token = ".ga-httr-oauth")
# Set the view ID and the date range. If you want to, you can swap out the Sys.getenv()
# call and just replace that with a hardcoded value for the view ID. And, the start
# and end date are currently set to choose the last 30 days, but those can be
# hardcoded as well.
view_id <- Sys.getenv("GA_VIEW_ID")
start_date <- Sys.Date() - 31 # 30 days back from yesterday
end_date <- Sys.Date() - 1 # Yesterday
If that all runs with just some messages but no errors, then you’re set for the next chunk of code: pulling the data.
There are two main aspects of the data pulling:
deviceCategory
value as an argument and then constructs the segment accordinglymap()
Both of these aspects are embodied in the code below, but we’re going to do a bit of exposition before we get to that.
This all gets built up in what can feel very cumbersome. Check out ?segment_ga4()
for the documentation of how the segment gets built. Correctly, it describes this as a “hierarchy.” In practical terms, though, we build from the bottom up:
segment_element()
. This is just a single conditional statement.segment_vector_simple()
. There are a few options here, but we’re going to stick with the simple approach. And, it’s still going to feel redundant, because we’re only including a single segment element.segment_define()
. This may feel like it’s the same as the previous step, but, if you think about the segment builder in the web interface, it will start to make sense – there are two levels at which can combine multiple “things” together to define a segment. Alas! Here, again, we’re just including a single segment vector, so it all feels really cumbersome.In addition to the “hierarchy” messiness for a simple segment, there is also some list()
messiness. Note, for instance, how my_segment_vector
in the example code includes a list within a list. Use this example (and other examples on this site) as well as the ?segment_ga4()
documentation to troubleshoot.
As Mark Edmondson says, “If you’re going to use R effectively, you’re going to have to learn to love lists.” There are a couple of things to note about how we’re using lists in this code:
deviceCategory
values. To get even more advanced, we could actually have one query that pulls all of the values for deviceCategory
(or some other dimension) and then use the results of that category to get the list of values we actually want to process. Minds start to get blown at that point (but it’s a very practical application!).map()
(which is from the purrr
package in the Tidyverse) to call our function for each of those values. This will return a list of data frames – one data frame for each device category. We’ll then process that list for our data visualization(s)!Now…onto the code!
#############
# Create a function that takes in a device category value, builds a dynamic segment using that
# value, and then queries the data.
#############
get_data <- function(device_category){
# Build the segment name
my_segment_name <- paste(device_category,"Sessions")
# Create a segment element object. See ?segment_element() for details.
my_segment_element <- segment_element("deviceCategory",
operator = "EXACT",
type = "DIMENSION",
expressions = device_category) # The value passed to the function
# Create a segment vector that has just one element. See ?segment_vector_simple() for details. Note
# that the element is wrapped in a list(). This is how you would include multiple elements in the
# definition.
my_segment_vector <- segment_vector_simple(list(list(my_segment_element)))
# Define the segment with just the one segment vector in it. See ?segment_define() for details.
my_segment_definition <- segment_define(list(my_segment_vector))
# Create the actual segment object that we're going to use in the query. See ?segment_ga4()
# for details.
my_segment <- segment_ga4(my_segment_name, # We built this at the beginning of the function
session_segment = my_segment_definition)
# <whew>!!!
# We're only going to return the top 10 values, so we need to order the results in descending order.
# This *could* be defined outside the function, but, for readability, we're putting it here.
results_order <- order_type("pageviews",
sort_order = "DESCENDING",
orderType = "VALUE")
# Pull the data. See ?google_analytics_4() for additional parameters.
ga_data <- google_analytics(viewId = view_id,
date_range = c(start_date, end_date),
metrics = "pageviews",
dimensions = "pagePath",
order = results_order,
segments = my_segment,
max = 10)
# Go ahead and print to the console that this step has been completed. This is useful both
# for debugging, as well as to be able to track progress as the script is running.
cat("Completed pulling data for:", device_category, "\n")
# The function will return the last value set, so repeat ga_data to ensure that happens
ga_data
}
#############
# Put that function to use!
#############
# Define the list of values to be processed
device_categories <- c("Mobile", "Tablet", "Desktop")
# And then process it! It's an innocuous little line of code, but it's where the magic happens!
page_data <- map(device_categories, get_data)
# The above returns a list of three data frames -- one for each device category. For our data
# check, we'll just peek at the Mobile values
head(page_data$Mobile)
We’re actually going to need to convert the pagePath
values to factors so that each bar chart comes out in descending order. But, to save ourselves from too many list-processing functions, we’re going to do that at part of the data visualization.
This won’t be the prettiest bar chart, but let’s make three horizontal bar charts – one each for each of our three segments. We’re going to do some list work again. This time, we’ll write a function to perform the data visualization and then run that function for each element (data frame) in our our page_data
list.
#########
# The function to do some moderate data munging and generate a visualization
#########
plot_data <- function(df){
# Convert the pagePath to be a factor so the bars will be ordered descending by pageviews
df$pagePath <- factor(df$pagePath,
levels = rev(df$pagePath))
# Grab the segment name to use as the title. It's the same value for every row, so just
# use the first row.
chart_title <- df$segment[1]
# Create the plot. Note the stat="identity"" (because the data is already aggregated) and
# the coord_flip(). And, I just can't stand it... added on the additional theme stuff to
# clean up the plot a bit more.
gg <- ggplot(df, mapping = aes(x = pagePath, y = pageviews)) +
geom_bar(stat = "identity") +
ggtitle(chart_title) +
coord_flip() +
theme_light() +
theme(panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.border = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank())
# Output the plot. You *could* just remove the "gg <-" in the code above, but it's
# generally a best practice to create a plot object and then output it, rather than
# outputting it on the fly.
gg
}
#########
# Call the function for each element in page_data
#########
# The second round of magic!
final_charts <- map(page_data, plot_data)
# And then output the results. We could jump through a few more hoops to not have the ## stuff
# show up, but I think we've done enough for now. Don't you?
final_charts
## [[1]]
##
## [[2]]
##
## [[3]]
There you have it! The magic of lists and functions applied to dynamic segments!
This site is a sub-site to dartistics.com


IFU - Indonesia Biosensors
User to provide
User to provide description
BMX_Alpha_IFU
User to provide description
Product
User to provide description
Product
User to provide description
Product
User to provide description


12 killed as violence flares after Israeli strikes target Gaza militants
Israeli air strikes killed two Islamic Jihad militants in Gaza as rocket fire towards Israel resumed after a brief overnight lull, raising the death toll in the territory to 12 Palestinians in the heaviest round of fighting in months.
The Israeli military said more than 250 rockets have been fired at communities in Israel since the violence erupted after an Israeli air strike killed a senior Islamic Jihad commander accused of being the mastermind of recent attacks.
Schools remained closed in communities near the Gaza border as rockets continued to rain down, although it was less intense than a relentless barrage the previous day.
But in a sign that the current round could be brief, Gaza’s Hamas rulers have yet to enter the fray.
Although larger and more powerful than the Iranian-backed Islamic Jihad, Hamas is also more pragmatic. With Gaza’s economy in tatters, it appears to have little desire for another round of fighting with Israel.
Egypt, which frequently mediates between Israel and Gaza militants, has been working to de-escalate tensions, according to officials in Cairo.
Seeking to keep the outburst under control, the Israeli military has restricted its operations to Islamic Jihad, and nearly all the casualties so far are members of the militant group.
The initial pre-dawn Israeli strike on Gaza came as another strike attributed to Israel targeted a senior Islamic Jihad commander based in Syria. The strikes appeared to be a new surge in the open warfare between Israel and Iranian proxies in the region.
Iran has forces based in Syria, Israel’s northern neighbour, and supports Hezbollah militants in Lebanon. In Gaza, it supplies Islamic Jihad with cash, weapons and expertise.
Israeli prime minister Benjamin Netanyahu claims Iran is using Iraq and far-off Yemen – where Tehran supports Shiite Houthi rebels at war with a Saudi-led coalition backing the government – to plan attacks against Israel. Hamas also receives some support from Iran.
Israel frequently strikes Iranian interests in Syria but Tuesday’s attack in Damascus appeared to be a rare assassination attempt of a Palestinian militant in the Syrian capital.


Hello,
It must be a little surprising for you . My name is MUSA EYADEMA, a son of YASSINGBE EYADEMA President of Togo and one of the coffee/cocoa merchant and also a contractor, my father died because of political situation in Togo .
Now the reason of my introduction to you, is to assist me to transfer my inheritance that my father left for me into a suspend account before he died, the sum of 8.500.000 Dollars in one of the International bank here in my country CITIZEN BANK. Please sir, I need your financial assistance for legal process so that the bank can transfer the money into your personal account for you to help me invest the money into a profitable business investment in your country. You have to forward me your full name, address and telephone number immediately so that I will forwarded to the bank for them to transfer the fund.
For your financial assistance, I have decide to give you 25% after the successful transfer. Kindly contact me trough my private email address for more information<EMAIL_ADDRESS>TEL : 00225 05 28 95 17MUSA EYADEMA.
Sell on Yahoo! Auctions - No fees. Bid on great items.


--- layout: post status: publish published: true title: Codekana author: display_name: Tomas Restrepo login: tomasr email<EMAIL_ADDRESS>url: http://winterdom.com/ author_login: tomasr author_email<EMAIL_ADDRESS>author_url: http://winterdom.com/ wordpress_id: 247 wordpress_url: http://winterdom.com/2007/07/codekana date: '2007-07-24 05:48:58 +0000' date_gmt: '2007-07-24 05:48:58 +0000' categories: - Tools tags: [] comments: [] ---
I just noticed that Jon, the guy behind ViEmu, is talking a bit about an upcoming product: CodeKana. I haven't downloaded or installed it yet, but it looks like it might be a useful tool for Visual Studio. That said, certainly at least part of what it does is already done by CodeRush.
Update: Looks like v1.0 was released.


Example 10
{{ isQuerying ? 'Loading...' : 'Query' }}
Random Height
Overview
Source Code on Github
Shows how to implement a simple SlimGrid in Angular.js
Note:
This obviously isn't a pure Angular.js implementation and can be greatly improved upon in the future.


Home
Images
Contact
Gigs
FOR BOOKINGS CONTACT DANNY RYAN AT<PHONE_NUMBER>8
OR CLICK HERE FOR FACEBOOK LINK


--- title: Show doc keywords: fastai sidebar: home_sidebar summary: "Functions to show the doc cells in notebooks" ---
All the automatic documentation of functions and classes are generated with the show_doc
function. It displays the name, arguments, docstring along with a link to the source code on GitHub.
The inspect module lets us know quickly if an object is a function or a class but it doesn't distinguish classes and enums.
e = enum.Enum('e', 'a b')
assert is_enum(e)
assert not is_enum(int)
mod = importlib.import_module("torch")
for m in glob.glob(mod.__path__): print(m)
dir(mod)
assert is_lib_module('export')
assert not is_lib_module('transform')
This function will only work for other packages built with nbdev
.
#fastai2
test_eq(try_external_doc_link('TfmdDL', ['fastai2']), 'https://dev.fast.ai/data.core#TfmdDL')
#Only works for packages built with nbdev right now
assert try_external_doc_link('Tensor', ['torch']) is None
This function will generate link for a module (pointing to the html conversion of the notebook that created it) and functions (pointing to the hmtl conversion of the notebook they were defined, with the first anchor found before). If the function/module is not part of the library you are writing, it will call the function custom_doc_links
generated in _nbdev
(you can customize it to your needs) and just return the name between backsticks if that function returns None
.
For instance, fastai2 has the following custom_doc_links
that tries to find a doc link for name
in fastcore then nbdev (in this order):
def custom_doc_links(name):
from nbdev.showdoc import try_external_doc_link
return try_external_doc_link(name, ['fastcore', 'nbdev'])
test_eq(doc_link('export'), f'[`export`](/export)')
test_eq(doc_link('DocsTestClass'), f'[`DocsTestClass`](/export#DocsTestClass)')
test_eq(doc_link('DocsTestClass.test'), f'[`DocsTestClass.test`](/export#DocsTestClass.test)')
test_eq(doc_link('Tenso'),'`Tenso`')
test_eq(doc_link('_nbdev'), f'`_nbdev`')
test_eq(doc_link('__main__'), f'`__main__`')
This function not only add links to backstick keywords, it also update the links that are already in the text (in case they have changed).
tst = add_doc_links('This is an example of `DocsTestClass`')
test_eq(tst, "This is an example of [`DocsTestClass`](/export#DocsTestClass)")
tst = add_doc_links('This is an example of [`DocsTestClass`](old_link.html)')
test_eq(tst, "This is an example of [`DocsTestClass`](/export#DocsTestClass)")
Be sure to properly set the git_url
in setting.ini (derived from lib_name
and branch
on top of the prefix you will need to adapt) so that those links are correct.
As important as the source code, we want to quickly jump to where the function is defined when we are in a development notebook.
test_eq(get_nb_source_link(DocsTestClass.test), get_nb_source_link(DocsTestClass))
test_eq(get_nb_source_link('DocsTestClass'), get_nb_source_link(DocsTestClass))
NB_SOURCE_URL = Config().git_url.replace('github.com', 'nbviewer.jupyter.org/github')+ Config().nbs_path.name+'/'
test_eq(get_nb_source_link(check_re), f'{NB_SOURCE_URL}00_export.ipynb#Finding-patterns')
test_eq(get_nb_source_link(check_re, local=True), f'00_export.ipynb#Finding-patterns')
You can either pass an object or its name (by default is_name
will look if func
is a string or not to decide if it's True
or False
, but you can override if there is some inconsistent behavior). local
will return a local link, otherwise it will point to a the notebook on github wrapped in nbviewer.
This function assumes you are in one notebook in the development folder, otherwise you can use disp=False
to get the relative link. You can either pass an object or its name (by default is_name
will look if func
is a string or not to decide if it's True
or False
, but you can override if there is some inconsistent behavior).
test_eq(nb_source_link(check_re, disp=False), f'00_export.ipynb#Finding-patterns')
test_eq(nb_source_link('check_re', disp=False), f'00_export.ipynb#Finding-patterns')
The representation tries to find doc links if possible.
tst = type_repr(Optional[DocsTestClass])
test_eq(tst, '`Optional`\\[[`DocsTestClass`](/export#DocsTestClass)\\]')
tst = type_repr(Union[int, float])
test_eq(tst, '`Union`\\[`int`, `float`\\]')
test_eq(type_repr(Param("description")), '"description"')
sig = inspect.signature(notebook2script)
params = [format_param(p) for _,p in sig.parameters.items()]
test_eq(params, ['**`fname`**=*`None`*', '**`silent`**=*`False`*', '**`to_dict`**=*`False`*'])
doc_string
determines if we show the docstring of the function or not. name
can be used to provide an alternative to the name automatically found. title_level
determines the level of the anchor (default 3 for classes and 4 for functions). If disp
is False
, the function returns the markdown code instead of displaying it.
For instance
show_doc(notebook2script)
will display
notebook2script
[source]
notebook2script
(fname
=None
,silent
=False
,to_pkl
=False
)
Convert fname
or all the notebook satisfying all_fs
.
from fastai2.data.core import TfmdDL
def get_doc_link(func):
mod = inspect.getmodule(func)
module = mod.__name__.replace('.', '/') + '.py'
try:
nbdev_mod = importlib.import_module(mod.__package__.split('.')[0] + '._nbdev')
try_pack = source_nb(func, mod=nbdev_mod)
if try_pack:
page = '.'.join(try_pack.split('_')[1:]).replace('.ipynb', '')
return f'{nbdev_mod.doc_url}{page}#{qual_name(func)}'
except: return None
test_eq(get_doc_link(notebook2script), 'https://nbdev.fast.ai/export#notebook2script')
#fastai2
from fastai2.data.core import TfmdDL
test_eq(get_doc_link(TfmdDL), 'https://dev.fast.ai/data.core#TfmdDL')


Classes
ChartTime
Time axis creation/manipulation for charts
Features
- Generate the values for time series chart axis
- Allows for custom granularities like release/iteration/iteration_day
- Knockout weekends and holidays (ChartTimeIterator)
- Knockout non-work hours (ChartTimeIterator)
- Drill up and down granularity
- Work with precision around timezone differences
- Month is 1-indexed instead of 0-indexed like Javascript's Date object
- Date/Time math (add 3 months, subtract 2 weeks, etc.)
- Tested
- Documented
Granularity
Each ChartTime object has a granularity. This means that you never have to worry about any bits lower than your specified granularity. A day has only year, month, and day segments. You are never tempted to specify 11:59pm to specify the end of a day-long timebox.
ChartTime supports the following granularities:
year
month
day
hour
minute
second
millisecond
quarter
(but not quarter_month, day, etc.)week
(ISO-8601 style week numbering)week_day
(Monday = 1, Sunday = 7)
Also, you can define your own custom hierarchical granularities, for example...
release
iteration
iteration_day
Timezone precision
It's very hard to do filtering and grouping of time-series data with timezone precision.
For instance, 11pm in California on December 25 (Christmas holiday) is 2am December 26 (not a holiday) in New York. This also happens to be 7am December 26 GMT. If you have an event that occurs at 2011-12-26T07:00:00.000Z, then you need to decide what timezone to use as your context before you decide if that event occured on Christmas day or not. It's not just holidays where this can burn you. Deciding if a piece of work finished in one iteration versus another can make a difference for you iteration metrics. The iteration metrics for a distributed team should look the same regardless of whether those metrics were generated in New York versus Los Angeles... versus Bangalore.
The javascript Date object lets you work in either the local time or Zulu (GMT/UTC) time but it doesn't let you control the timezone. Do you know the correct way to apply the timezone shift to a JavaScript Date Object? Do you know when Daylight Savings Time kicks in and New York is 4 hours shifted from GMT instead of 5? Will you remember to do it perfectly every time it's needed in your code?
If you need this precision, ChartTime helps by clearly delineating the moment when you need to do timezone manipulation... the moment you need to compare two or more dates. You can do all of your holiday/weekend knockout manipulation without regard to timezone and only consider the timezone upon comparison.
Month is 1-indexed as you would expect
Javascript's date object uses 0 for January and 11 for December. ChartTime uses 1 for January and 12 for December... which is what ISO-8601 uses and what humans expect. Everyone who works with the javascript Date Object at one point or another gets burned by this.
Week support
ChartTime follows ISO-8601 where ever it makes sense. Implications of using this ISO format (paraphrased info from wikipedia):
- All weeks have 7 days (i.e. there are no fractional weeks).
- Any given day falls into a single week which means that incrementing across the year boundary in week granularity is without gaps or repeats.
- Weeks are contained within a single year. (i.e. weeks are never spit over two years).
- The above two implications also mean that we have to warp the boundaries of the year to accomplish this. In week granularity dates may appear in a different year than you would expect and some years have 53 weeks.
- The date directly tells the weekday.
- All years start with a Monday and end with a Sunday.
- Dates represented as yyyyWww-d can be sorted as strings.
In general, it just greatly simplifies the use of week granularity in a chart situation.
The only real downside to this approach is that USA folks expect the week to start on Sunday. However, the ISO-8601 spec starts each week on Monday. Following ISO-8601, ChartTime uses 1 for Monday and 7 for Sunday which aligns with the US standard for every day except Sunday. The US standard is to use 0 for Sunday.
Basic usage
{ChartTimeIterator, ChartTimeRange, ChartTime} = require('../')
d1 = new ChartTime({granularity: 'day', year: 2011, month: 2, day: 28})
console.log(d1.toString())
# 2011-02-28
You can use the string short-hand rather than spell out the segments seperately. The granularity is automatically inferred from how many segments you provide.
d2 = new ChartTime('2011-03-01')
console.log(d2.toString())
# 2011-03-01
Increment/decrement and compare ChartTimes without regard to timezone
console.log(d1.$gte(d2))
d1.increment()
console.log(d1.$eq(d2))
# false
# true
Do math on them.
d3 = d1.add(5)
console.log(d3.toString())
# 2011-03-06
Get the day of the week.
console.log(d3.dowString())
# Sunday
Subtraction is just addition with negative numbers.
d3.addInPlace(-6)
console.log(d3.toString())
# 2011-02-28
If you start on the last day of a month, adding a month takes you to the last day of the next month, even if the number of days are different.
d3.addInPlace(1, 'month')
console.log(d3.toString())
# 2011-03-31
Deals well with year-granularity math and leap year complexity.
d4 = new ChartTime('2004-02-29') # leap day
d4.addInPlace(1, 'year') # adding a year takes us to a non-leap year
console.log(d4.toString())
# 2005-02-28
Week granularity correctly wraps and deals with 53-week years.
w1 = new ChartTime('2004W53-6')
console.log(w1.inGranularity('day').toString())
# 2005-01-01
Convert between any of the standard granularities. Also converts custom granularities (not shown) to
standard granularities if you provide a rataDieNumber()
function with your custom granularities.
d5 = new ChartTime('2005-01-01') # goes the other direction also
console.log(d5.inGranularity('week_day').toString())
# 2004W53-6
q1 = new ChartTime('2011Q3')
console.log(q1.inGranularity('millisecond').toString())
# 2011-07-01T00:00:00.000
Timezones
ChartTime does timezone sensitive conversions. You must set the path to the tz files before doing any timezone sensitive comparisons.
ChartTime.setTZPath('../vendor/tz')
console.log(new ChartTime('2011-01-01').getJSDate('America/New_York'))
# Sat, 01 Jan 2011 05:00:00 GMT
Static Methods
ChartTime.setTZPath(tzPath)
Allows you to set the path (can be relative) to the tz files. Must be called prior to doing timezone sensitive comparisons.
ChartTime.getZuluString(jsDate)
Given a JavaScript Date() Object, this will return the canonical ISO-8601 form.
If you don't provide any parameters, it will return now, like new Date()
except this is a zulu string.
ChartTime.addGranularity(granularitySpec)
addGranularity allows you to add your own hierarchical granularities to ChartTime. Once you add a granularity to ChartTime you can then instantiate ChartTime objects in your newly specified granularity. You specify new granularities with granularitySpec object like this:
granularitySpec = {
release: {
segments: ['release'],
mask: 'R##',
lowest: 1,
dayPastEnd: new ChartTime('2011-07-01')
pastHighest: (ct) ->
return ChartTime.granularitySpecs.iteration.timeBoxes.length + 1 # Yes, it's correct to use the length of iteration.timeBoxes
rataDieNumber: (ct) ->
return ChartTime.granularitySpecs.iteration.timeBoxes[ct.release-1][1-1].start.rataDieNumber()
},
iteration: {
segments: ['release', 'iteration'],
mask: 'R##I##',
lowest: 1,
dayPastEnd: new ChartTime('2011-07-01')
timeBoxes: [
[
{start: new ChartTime('2011-01-01'), label: 'R1 Iteration 1'},
{start: new ChartTime('2011-02-01'), label: 'R1 Iteration 2'},
{start: new ChartTime('2011-03-01'), label: 'R1 Iteration 3'},
],
[
{start: new ChartTime('2011-04-01'), label: 'R2 Iteration 1'},
{start: new ChartTime('2011-05-01'), label: 'R2 Iteration 2'},
{start: new ChartTime('2011-06-01'), label: 'R2 Iteration 3'},
]
]
pastHighest: (ct) ->
temp = ChartTime.granularitySpecs.iteration.timeBoxes[ct.release-1]?.length + 1
if temp? and not isNaN(temp) and ct.beforePastFlag != 'PAST_LAST'
return temp
else
numberOfReleases = ChartTime.granularitySpecs.iteration.timeBoxes.length
return ChartTime.granularitySpecs.iteration.timeBoxes[numberOfReleases-1].length + 1
rataDieNumber: (ct) ->
return ChartTime.granularitySpecs.iteration.timeBoxes[ct.release-1][ct.iteration-1].start.rataDieNumber()
},
iteration_day: { # By convention, it knows to use day functions on it. This is the lowest allowed custom granularity
segments: ['release', 'iteration', 'iteration_day'],
mask: 'R##I##-##',
lowest: 1,
dayPastEnd: new ChartTime('2011-07-01'),
pastHighest: (ct) ->
iterationTimeBox = ChartTime.granularitySpecs.iteration.timeBoxes[ct.release-1]?[ct.iteration-1]
if !iterationTimeBox? or ct.beforePastFlag == 'PAST_LAST'
numberOfReleases = ChartTime.granularitySpecs.iteration.timeBoxes.length
numberOfIterationsInLastRelease = ChartTime.granularitySpecs.iteration.timeBoxes[numberOfReleases-1].length
iterationTimeBox = ChartTime.granularitySpecs.iteration.timeBoxes[numberOfReleases-1][numberOfIterationsInLastRelease-1]
thisIteration = iterationTimeBox.start.inGranularity('iteration')
nextIteration = thisIteration.add(1)
if nextIteration.beforePastFlag == 'PAST_LAST'
return ChartTime.granularitySpecs.iteration_day.dayPastEnd.rataDieNumber() - iterationTimeBox.start.rataDieNumber() + 1
else
return nextIteration.rataDieNumber() - iterationTimeBox.start.rataDieNumber() + 1
rataDieNumber: (ct) ->
return ChartTime.granularitySpecs.iteration.timeBoxes[ct.release-1][ct.iteration-1].start.rataDieNumber() + ct.iteration_day - 1
}
}
ChartTime.addGranularity(granularitySpec)
The mask
must cover all of the segments to get down to the granularity being specified. The digits of the granularity segments
are represented with #
. Any other characters can be used as a delimeter, but it should always be one character to comply with
the expectations of the Lumenize hierarchy visualizations. All of the standard granularities start with a 4-digit year to
distinguish your custom granularity, your highest level must start with some number of digits other than 4 or a prefix letter
(R
in the example above).
In order for the ChartTimeIterator to work, you must provide pastHighest
and rataDieNumber
callback functions. You should
be able to mimic (or use as-is) the example above for most use cases. Notice how the rataDieNumber
function simply leverages
rataDieNumber
functions for the standard granularities.
In order to convert into this granularity from some other granularity, you must provide an inGranularity
callback [NOT YET IMPLEMENTED].
But ChartTime will convert to any of the standard granularities from even custom granularities as long as a rataDieNumber()
function
is provided.
The timeBoxes
propoerty in the granularitySpec
Object above has no special meaning to ChartTime or ChartTimeIterator. It's simply used
by the pastHighest
and rataDieNumber
functions. The boundaries could come from where ever you want and even have been encoded as
literals in the pastHighest
and rataDieNumber
callback functions.
The convention of naming the lowest order granularity with _day
at the end IS signficant. ChartTime knows to treat that as a day-level
granularity. If there is a use-case for it, ChartTime could be upgraded to allow you to drill down into hours, minutes, etc. from any
_day
granularity but right now those lower order time granularities are only supported for the canonical ISO-6801 form.
Instance Methods
constructor(spec_RDN_Date_Or_String, granularity, tz)
The constructor for ChartTime supports the passing in of a String, a rata die number (RDN), or a spec Object
String
When you pass in a String, ChartTime uses the masks that are defined for each granularity to figure out the granularity...
unless you explicitly provide a granularity. This parser does not work on all valid ISO-8601 forms. Ordinal dates are not
supported at all but week number form ("2009W52-7"
) is supported. The canonical form ("2009-01-01T12:34:56.789"
) will work
as will any shortened subset of it ("2009-01-01"
, "2009-01-01T12:34"
, etc.). We've added a form for Quarter
granularity ("2009Q4"
). Plus it will even parse strings in whatever custom granularity you provide based
upon the mask that you provide for that granularity.
If the granularity is specified but not all of the segments are provided, ChartTime will fill in the missing value
with the lowest
value from granularitySpecs.
The Lumenize hierarchy tools rely upon the property that a single character is used between segments so the ISO forms that omit the delimeters are not supported.
If the string has a timezone indicator on the end (...+05:00
or ...Z
), ChartTime will ignore it. Timezone information
is intended to only be used for comparison (see examples for timezone comparison).
There are two special Strings that are recognized: BEFORE_FIRST
and PAST_LAST
. You must provide a granularity if you
are instantiating a ChartTime with these values. They are primarily used for custom granularities where your users
may mistakenly request charts for iterations and releases that have not yet been defined. They are particularly useful when
you want to iterate to the last defined iteration/release.
Rata Die Number
The rata die number (RDN) for a date is the number of days since 0001-01-01. You will probably never work
directly with this number but it's what ChartTime uses to convert between granularities. When you are instantiating
a ChartTime from an RDN, you must provide a granularity. Using RDN will work even for the granularities finer than day.
ChartTime will populate the finer grained segments (hour, minute, etc.) with the approriate lowest
value.
Date
You can also pass in a JavaScript Date() Object. The passing in of a tz with this option doesn't make sense. You'll end up with the same ChartTime value no matter what because the JS Date() already sorta has a timezone. I'm not sure if this option is even really useful. In most cases, you are probably better off using ChartTime.getZuluString()
Spec
You can also explicitly spell out the segments in a spec Object in the form of
{granularity: 'day', year: 2009, month: 1, day: 1}
. If the granularity is specified but not all of the segments are
provided, ChartTime will fill in the missing value with the appropriate lowest
value from granularitySpecs.
granularity
If you provide a granularity it will take precedence over whatever fields you've provided in your spec or whatever segments
you have provided in your string. ChartTime will leave off extra values and fill in missing ones with the appropriate lowest
value.
tz
Most of the time, ChartTime assumes that any dates you pass in are timezone less. You'll specify Christmas as 12-25, then you'll shift the boundaries of Christmas for a specific timezone for boundary comparison.
However, if you provide a tz parameter to this constructor, ChartTime will assume you are passing in a true GMT date/time and shift into the provided timezone. So...
d = new ChartTime('2011-01-01T02:00:00:00.000Z', 'day', 'America/New_York')
console.log(d.toString())
# 2010-12-31
Rule of thumb on when you want to use timezones:
- If you have true GMT date/times and you want to create a ChartTime, provide the timezone to this constructor.
- If you have abstract days like Christmas or June 10th and you want to delay the timezone consideration, don't provide a timezone to this constructor.
- In either case, if the dates you want to compare to are in GMT, but you've got ChartTimes or ChartTimeRanges, you'll have to provide a timezone on the way back out of ChartTime/ChartTimeRange
granularityAboveDay()
Convenience function to tell if the ChartTime Object's granularity is above (courser than) "day" level.
getJSDate(tz)
Returns a JavaScript Date Object properly shifted. This Date Object can be compared to other Date Objects that you know are already in the desired timezone. If you have data that comes from an API in GMT. You can first create a ChartTime object from it and then (using this getJSDate() function) you can compare it to JavaScript Date Objects created in local time.
The full name of this function should be getJSDateInGMTasummingThisCTDateIsInTimezone(tz). It converts TO GMT (actually something that can be compared to GMT). It does NOT convert FROM GMT. Use getJSDateInTZfromGMT() if you want to go in the other direction.
Note, you must set the path to the tz files with ChartTime.setTZPath('path/to/tz/files')
before you do timezone
sensitive comparisions.
Usage
ct = new ChartTime('2011-01-01')
d = new Date(Date.UTC(2011, 0, 1))
console.log(ct.getJSDate('GMT').getTime() == d.getTime())
# true
console.log(ct.inGranularity('hour').add(-5).getJSDate('America/New_York').getTime() == d.getTime())
# true
getJSDateString(tz)
Returns the canonical ISO-8601 date in zulu representation but shifted to the specified tz
getJSDateInTZfromGMT(tz)
This assumes that the ChartTime is an actual GMT date/time as opposed to some abstract day like Christmas and shifts it into the specified timezone.
Note, this function will be off by an hour for the times near midnight on the days where there is a shift to/from daylight savings time. The tz rules engine is designed to go in the other direction so we're mis-using it and will be using the wrong moment in rules-space for that hour. The cost of fixing this issue was deamed to high for chart applications.
toString()
Uses granularity mask
to generate the string representation.
dowNumber()
Returns the day of the week as a number. Monday = 1, Sunday = 7
dowString()
Returns the day of the week as a String.
rataDieNumber()
Returns the number of days since 0001-01-01. Works for granularities finer than day (hour, minute, second, millisecond) but ignores the segments of finer granularity than day.
inGranularity(granularity)
Returns a new ChartTime object for the same date-time as this object but in the specified granularity.
Fills in missing finer granularity bits with lowest
values.
daysInMonth()
Returns the number of days in the current month for this ChartTime
isLeapYear()
True if this is a leap year.
is53WeekYear()
True if this is a 53-week year.
$eq(other)
Returns true if this equals other. Throws an error if the granularities don't match.
d3 = new ChartTime({granularity: 'day', year: 2011, month: 12, day: 31})
d4 = new ChartTime('2012-01-01').add(-1)
console.log(d3.$eq(d4))
# true
$gt(other)
Returns true if this is greater than other. Throws an error if the granularities don't match
d1 = new ChartTime({granularity: 'day', year: 2011, month: 2, day: 28})
d2 = new ChartTime({granularity: 'day', year: 2011, month: 3, day: 1})
console.log(d1.$gt(d2))
# false
console.log(d2.$gt(d1))
# true
$gte(other)
True if this is greater than or equal to other.
$lt(other)
True if this is less than other.
$lte(other)
True if this is less than or equal to other.
decrement(granularity)
Decrements by 1.
increment(granularity)
Increments by 1.
addInPlace(qty, granularity)
Adds qty to the ChartTime object. It uses increment and decrement so it's not going to be efficient for large values of qty, but it should be fine for charts where we'll increment/decrement small values of qty.
qty can be negative for subtraction.
add(qty, granularity)
Adds (or subtracts) quantity (negative quantity) and returns a new ChartTime.