text:
---
layout: 	post
title: 		"Java编程思想笔记<七>"
subtitle:	"Reusing Classes"
date: 		2017-3-12 11:40:00
author: 	"玄天强"
header-img:	"img/mn-bg-xtq.jpg"
catalog: true
tags:
    - Thinking in Java
---

*	The first is composition，You’re simply reusing the functionality of the code, not its form.
*	第一种是组合，你只是复用代码的函数功能，不是其形式。
*	The second approach is inheritance，You literally take the form of the existing class and add code to it without modifying the existing class.
*	第二种方法是继承，照搬已有的类，并增添一些代码给它而不改变已有类。

##	Composition syntax

*	You simply place object references inside new classes.
*	在新的类中简单地放对象的引用即可。
*	Every non-primitive object has a toString( ) method.
*	所有的非基本类型对象都有一个toString()方法。
*	If you want the references initialized, you can do it:
*	如果你想初始化引用，你可以按以下方式进行:

		1.At the point the objects are defined.
		1.在对象创建处
		2.In the constructor for that class.
		2.在该类的构造函数中
		3.Right before you actually need to use the object(lazy initialization).
		3.就在你实际使用对象前(懒初始化)
		4.Using instance initialization.
		4.用instance初始化

##	Inheritance syntax

*	It turns out that you’re always doing inheritance when you create a class.
*	通常在创建类时继承。
*	You automatically get all the fields and methods in the base class.
*	你会自动地获得基类的所有字段和方法。
*	This technique of putting a main() in each class allows easy testing for each class.
*	这种给各类放一个main()方法的技巧使得每个类的测试很容易。
*	Even if a class has package access, a public main() is accessible.
*	即使一个类有包访问，公有的main()方法是可以访问的。
*	If a class from some other package were to inherit from base class, it could access only public members.
*	如果一个来自其他包的类要继承自基类，它只能访问公有成员。
*	To allow for inheritance, as a general rule make all fields private and all methods public.
*	为了继承，一般让所有字段私有而所有方法公有。
*	It’s possible to take a method that’s been defined in the base class and modify it.
*	可以使用定义在基类中的方法并对其做修改。
*	Java has the keyword *super* that refers to the “superclass” that the current class inherits.
*	Java中有一个关键字*super*指代当前类所继承的超类。

###	Initializing the base class

*	It can be a bit confusing to try to imagine the resulting object produced by a derived class.
*	要理解由继承类产生的对象优点令人困惑。
*	When you create an object of the derived class, it contains within it a subobject of the base class.
*	当你创建一个继承类的对象时，它里边包含了一个基类的子对象。
*	Perform the initialization in the constructor by calling the base-class constructor.
*	在构造函数中通过调用基类的构造函数进行初始化。
*	Java automatically inserts calls to the base-class constructor in the derived-class constructor.
*	Java在继承类的构造函数中自动插入调用基类的构造函数。
*	The compiler will synthesize a default constructor for you that calls the base class constructor.
*	编译器会自动给你创建一个调用基类构造函数的默认构造函数。

###	Constructors with arguments
*	If your class doesn’t have default arguments, or if you want to call a base-class constructor that has an argument, you must explicitly write the calls to the base-class constructor using the super keyword and the appropriate argument list.
*	如果你的类没有默认参数，或者你想调用有一个参数的基类的构造函数，必须用super关键字和合适的参数列表显式写出对基类构造函数的调用。
*	The call to the base-class constructor must be the first thing you do in the derived-class constructor.
*	对基类构造函数的调用须是你在继承类的构造函数中要做的第一件事。

##	Delegation

*	You place a member object in the class you’re building (like composition), but at the same time you expose all the methods from the member object in your new class (like inheritance).
*	在你创建的类中放一个成员对象(就像组合)，同时你暴露所有的成员对象的方法给新类(就像继承)。
*	Although the Java language doesn’t support delegation, development tools often do.
*	尽管Java不支持委托，开发工具通常会这么做。

##	Combining composition and inheritance
*	The compiler doesn’t watch over you to make sure that you initialize the member objects, so you must remember to pay attention to that.
*	编译器不会监视你来保证你初始化了成员对象，因此你得注意这点。
*	You don’t even need the source code for the methods in order to reuse the code. At most, you just import a package.
*	你甚至无需方法的源代码来重用代码，最多你只是引入一个包。

###	Guaranteeing proper cleanup
*	So if you want something cleaned up for a class, you must explicitly write a special method to do it, and make sure that the client programmer knows that they must call this method.
*	因此如果你想要对一个类做一些清理工作，你必须显式地写一个方法，并确保客户程序员知道他们必须调用该方法。
*	First perform all of the cleanup work specific to your class, in the reverse order of creation. Then call the base-class cleanup method.
*	首先进行你的类的特定清理工作，与创建顺序相反，然后调用基类的清理工作。
*	when you must do cleanup explicitly, diligence and attention are required, because there’s not much you can rely on when it comes to garbage collection.
*	当你必须显式进行清理工作时，小心谨慎是必要的，因为垃圾回收并不靠谱。

###	Name hiding
*	Overloading works regardless of whether the method was defined at this level or in a base class.
*	重载不管方法是定义在当前类还是基类中都有效。
*	It’s far more common to override methods of the same name, using exactly the same signature and return type as in the base class.
*	使用与基类中相同的标识符与返回类型来重写相同名称的方法更普遍。
*	You can choose to add this annotation and the compiler will produce an error message if you accidentally overload instead of overriding.
*	你可以选择添加该注解，编译器将产生一个错误信息如果你不小心用了重载而非重写。

##	Choosing composition vs. inheritance
*	You embed an object so that you can use it to implement features in your new class, but the user of your new class sees the interface you’ve defined for the new class rather than the interface from the embedded object.
*	你插入一个对象以用它来实现你的新类的特性，但新类的使用者看到的是你给新类定义的接口，而不是插入对象的接口。
*	When you inherit, you’re taking a general-purpose class and specializing it for a particular need.
*	当你继承时，你用一个一般类并为某个特定需求将其特殊化。
*	The is-a relationship is expressed with inheritance, and the has-a relationship is expressed with composition.
*	is-a关系由继承表达，而has-a关系由组合表达。

##	protected
*	You want to make something hidden from the world at large and yet allow access for members of derived classes.
*	你想最大程度地隐藏一些东西但允许访问继承类的成员。

##	Upcasting
*	The new class is a type of the existing class.
*	新类是一个已有类的类型。
*	Any message you can send to the base class can also be sent to the derived class.
*	任何你可以发给基类的信息也可以发送给继承类。

###	Why “upcasting”?
*	Casting from a derived type to a base type moves up on the inheritance diagram, so it’s commonly referred to as upcasting.
*	由继承类转为基类在继承图上是向上的，因此通常指上溯造型。
*	Upcasting is always safe because you’re going from a more specific type to a more general type.
*	upcasting一般是安全的，因为你是从一个特殊类型转为一个更一般的类型。
*	It can lose methods, not gain them.
*	可能会丢掉方法，而不是增加它们。
*	The compiler allows upcasting without any explicit casts or other special notation.
*	编译器允许没有显式转换或其他特殊记号的Upcasting.

##	Composition vs. inheritance revisited
*	You should use it sparingly, only when it’s clear that inheritance is useful.
*	你应该较少地用它，只在明显地继承是有用的时候。
*	Whether you’ll ever need to upcast from your new class to the base class.
*	你是否需要从新类强转为基类。

##	The final keyword
*	Java’s final keyword has slightly different meanings depending on the context.
*	Java中的final关键字根据上下文有着不同的意思。

###	final data
*	A value must be given at the time of definition of such a constant.
*	常数在定义时须给定一个值。
*	With a primitive, final makes the value a constant, but with an object reference, final makes the reference a constant.
*	对于基本类型，final使得值为常量，但对于对象引用，final使得引用为常量。
*	However, the object itself can be modified.
*	但是，对象本身可以被更改。
*	Java does not provide a way to make any arbitrary object a constant.
*	Java中没有让任意对象为常量的方法。
*	Just because something is final doesn’t mean that its value is known at compile time.
*	某个东西是final的并不意味着它的值在编译器就是已知的。
*	The difference between making a final value static or non-static.
*	使得一个final量静态或非静态之间的区别。
*	There is no way that I know of to make the array references themselves final.
*	据我所知没有让数组引用本身为final的方法

###	Blank finals
*	The blank final must be initialized before it is used, and the compiler ensures this.
*	blank final必须在使用前进行初始化，编译器保证了这点。
*	A final field inside a class can now be different for each object, and yet it retains its immutable quality.
*	一个类中的final字段互相之间可以不同，但它依然保持了其不可变性。
*	You’re forced to perform assignments to finals either with an expression at the point of definition of the field or in every constructor.
*	你被强制给一个final用一个表达式进行赋值，要么在字段的定义的位置，要么在所有的构造函数中。

###	final arguments
*	This means that inside the method you cannot change what the argument reference points to.
*	这意味着在方法中，你不能改变参数引用的指向。
*	You can read the argument, but you can’t change it.
*	你可以读参数，但不能更改它。
*	This feature is primarily used to pass data to anonymous inner classes.
*	这种特性主要用于给匿名内部类传数据

###	final methods
*	Final methods put a “lock” on the method to prevent any inheriting class from changing its meaning.
*	Final方法给方法加锁以阻止任何继承类改变它的意义。
*	You want to make sure that a method’s behavior is retained during inheritance and cannot be overridden.
*	你想确保一个方法的行为在继承时不会变并且不能重写。

###	final and private
*	Any private methods in a class are implicitly final.
*	类中的任何private方法都是隐式final的
*	If a method is private, it isn’t part of the base-class interface.
*	如果一个方法是private的，它不是基类接口的部分。
*	You haven’t overridden the method; you’ve just created a new method.
*	你没有重写方法，你只是创建了一个新方法。

###	final classes
*	You don’t want to inherit from this class or allow anyone else to do so.
*	你不打算继承该类或是允许其他人这么做。
*	Note that the fields of a final class can be final or not.
*	注意一个final类的字段可以是final或非final的。
*	Bnecause it prevents inheritance, all methods in a final class are implicitly final.
*	由于它不能继承，final类中的所有方法是隐式final的。

###	final caution
*	If you define a method as final, you might prevent the possibility of reusing your class through inheritance in some other programmer’s project simply because you couldn’t imagine it being used that way.
*	如果你定义一个final方法，你可能阻止了在其他程序项目中通过继承重用你的类的可能性，因为没法那样子使用。

##	Initialization and class loading
*	The compiled code for each class exists in its own separate file. That file isn’t loaded until the code is needed.
*	每个类编译后的代码存在于其自己单独的文件中，文件在代码需要时才会加载。
*	class code is loaded at the point of first use.
*	Class代码在第一次使用时被加载。
*	Loading also occurs when a static field or static method is accessed.
*	加载也会在一个静态字段或静态方法被访问时发生。

###	Initialization with inheritance
*	The static initialization in the root base class (in this case, Insect) is performed, and then the next derived class, and so on.
*	根基类中的静态初始化执行了，然后是下一个继承类，这样一直下去。
*	First, all the primitives in this object are set to their default values and the object references are set to *null*.
*	首先，该对象中所有的基本类型被设置为其默认值，对象引用被设置为null。
*	Then the base-class constructor will be called.
*	然后基类的构造函数会被调用。
*	The instance variables are initialized in textual order.
*	实例变量按照代码中的顺序被初始化。
*	Finally, the rest of the body of the constructor is executed.
*	最后，构造函数中其他部分被执行。

path: /_posts/Thinking In Java/2017-03-12-tij-1-xtq (37).md


text:
# PutObject {#reference_l5p_ftw_tdb .reference}

The PutObject operation is used to upload files.

## Request syntax {#section_ald_lkw_bz .section}

```
PUT /ObjectName HTTP/1.1
Content-Length：ContentLength
Content-Type: ContentType
Host: BucketName.oss-cn-hangzhou.aliyuncs.com
Date: GMT Date
Authorization: SignatureValue
```

## Request header {#section_y1z_lkw_bz .section}

|Name|Type|Description|
|----|----|-----------|
|Cache-Control|String|Specifies the web page caching behavior when the object is downloaded. For more information, see [RFC2616](https://www.ietf.org/rfc/rfc2616.txt).  Default: None

|
|Content-Disposition|String|Specifies the name of the object when the object is downloaded. For more information, see [RFC2616](https://www.ietf.org/rfc/rfc2616.txt).  Default: None

|
|Content-Encoding|String|Specifies the content encoding format when the object is downloaded. For more information, see [RFC2616](https://www.ietf.org/rfc/rfc2616.txt).  Default: None

|
|Content-Md5|String|As defined in RFC 1864, the message content \(excluding the header\) is calculated to obtain an MD5 value, which is a 128-bit number. This number is encoded using Base64 into a Content-MD5 value. This request header can be used to check the validity of a message, that is, whether the message content is consistent with the sent content. This request header is optional. However, we recommend that you use this request header for an end-to-end check. Default: None

Restrictions: None

|
|Expires|String|Specifies the expiration time. For more information, see [RFC2616](https://www.ietf.org/rfc/rfc2616.txt).  Default: None

**Note:** OSS imposes no limits or verification on this value.

|
|x-oss-server-side-encryption|String|Specifies the server-side encryption algorithm when OSS creates an object. Valid values: AES256 and KMS

**Note:** You must enable the KMS \(Key Management Service\) on the console to use the KMS encryption algorithm. Otherwise, a KmsServiceNotenabled error code is reported.

|
|x-oss-object-acl|String|Specifies the access permission when OSS creates an object.  Valid values: public-read, private, and public-read-write

|

## Detail analysis {#section_fcx_vkw_bz .section}

-   If you have uploaded the Content-MD5 request header, OSS calculates Content-MD5 of the body and checks if the two are consistent. If the two are different, the error code InvalidDigest is returned.
-   If the Content-Length value in the request header is smaller than the length of data transmitted in the actual request body, OSS still creates a file, but the object size is equal to the size defined by Content-Length, and the remaining data is dropped.
-   If a file of the same name with the object to be added already exists, and you are authorized to access this object, the newly-added file overwrites the existing file, and the system returns the 200 OK message.
-   If the PutObject request carries a parameter prefixed with x-oss-meta-, the parameter is treated as user meta, for example, x-oss-meta-location. A single object can have multiple similar parameters, but the total size of all user meta cannot exceed 8 KB.
-   If the Content length parameter is not added to the header, the system returns the 411 Length Required error. Error code: MissingContentLength.
-   If the length is set, but the message body is not sent, or the size of the sent body is smaller than the specified size, the server waits until time-out, and then returns the 400 Bad Request message. Error code: RequestTimeout.
-   If the bucket of the object to be added does not exist, the system returns the 404 Not Found error. Error code: NoSuchBucket.
-   If you have no permission to access the bucket of the object to be added, the system returns the 403 Forbidden error. Error code: AccessDenied.
-   If the length of the added file exceeds 5 GB, the system returns the 400 Bad Request message. Error code: InvalidArgument.
-   If the length of the input object key exceeds 1023 bytes, the system returns the 400 Bad Request message. Error code: InvalidObjectName.
-   When you put an object, OSS supports the following five header fields defined in [RFC2616](https://www.ietf.org/rfc/rfc2616.txt): Cache-Control, Expires, Content-Encoding, Content-Disposition, and Content-Type. If these headers are set when you upload an object, the corresponding header values are automatically set to the uploaded values next time when this object is downloaded.
-   If the x-oss-server-side-encryption header is specified when you upload an object, the value of this header must be set to AES256. Otherwise, the system returns the 400 error and the error code: InvalidEncryptionAlgorithmError. After this header is specified, the response header also contains this header, and OSS stores the encryption algorithm of the uploaded object. When this object is downloaded, the response header contains x-oss-server-side-encryption, the value of which is set to the encryption algorithm of this object.

## FAQ {#section_w35_wkw_bz .section}

-   **Content-MD5 calculation method error**

    The algorithm defined  in related standards

is used to calculate Content-MD5 in the following process: Calculate the upload Content-MD5, whose value is a 128-bit binary array, and then encode the binary array with Base64. Python is used as an example. The correct calculation code is as follows:

```

>>> import base64,hashlib
>>> hash = hashlib.md5()
>>> hash.update("0123456789")
>>> base64.b64encode(hash.digest())
'eB5eJF1ptWaXm4bijSPyxw=='
```

The result of hash.digest\(\) is used as the input of Base64 encoding. `>>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7'`. A common mistake is to encode the calculated 32-byte MD5 string with Base64. Incorrect example: Encoding hash.hexdigest\(\) with Base64: `>>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7'` The following is the incorrect calculation result. `>>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='`

## Example {#section_orz_dlw_bz .section}

**Request example:**

```
PUT /oss.jpg HTTP/1.1
Host: oss-example.oss-cn-hangzhou.aliyuncs.com
Cache-control: no-cache
Expires: Fri, 28 Feb 2012 05:38:42 GMT
Content-Encoding: utf-8
Content-Disposition: attachment;filename=oss_download.jpg
Date: Fri, 24 Feb 2012 06:03:28 GMT
Content-Type: image/jpg
Content-Length: 344606
Authorization: OSS qn6qrrqxo2oawuk53otfjbyc:kZoYNv66bsmc10+dcGKw5x2PRrk=

[344606 bytes of object data]

```

**Response example:**

```
HTTP/1.1 200 OK
Server: AliyunOSS
Date: Sat, 21 Nov 2015 18:52:34 GMT
Content-Length: 0
Connection: keep-alive
x-oss-request-id: 5650BD72207FB30443962F9A
x-oss-bucket-version:<PHONE_NUMBER>
ETag: "A797938C31D59EDD08D86188F6D5B872"
```

license: MIT

branch_name: refs/heads/master

extension: md

gha_license_id: MIT

license_type: permissive


text:
# RDML

Adopt [RDML](http://rdml.org/) as a standard for presence/absence data?

* TAQMAN panel
* Cepheid results
* Clinical testing?

## Motivations

1. Stop using a bespoke format internal to Samplify.

## Challenges

1. This is a clear choice for qPCR-based presence/absence results (with Cq
   values), but does RDML make sense for presence/absence results reported
   without a quantification?  Does the format allow for this?

2. We will need to either convince NWGC to send us the RDML, or we will need to
   transform from their JSON to RDML ourselves.

gha_language: PLpgSQL


text:
# Visualization

Using Tableau, create visualization for each question in the report. You will
work on this independently just like last week.

To include a Tableau visualization in your report, take a screenshot, save it as an image,
put it in the `learning/week2` folder, and replace `![screenshot](screenshot.png)`  with
your own image. Please makes sure your screenshot includes the _entire_ Tableau interface
including the controls, widgets ...etc.

# Import

Data: [fcq.clean.json](https://github.com/bigdatahci2015/book/blob/master/hackathons/fcq/fcq.clean.json)

(a copy of this file is in your book repository already in the directory `hackathons/fcq`)

This dataset is provided to you in the JSON format. Your first task is to figure out
how to transform this JSON file into a format that can be fed into Tableau. As
a junior and senior, you are expected to be able to look around the Internet
to problem solve.

# How many instructors have taught each subject? Kari

![screenshot](karifcq.png)

At the bottom you can see that WRTG and LAWS have the highest amount of instructors for each subject.

# Does the instruction tends to give out higher grades if they teach more classes? or the reverse? Ming

![screenshot](mingfcq.png)
![screenshot](Mingfcq1.png)

This was difficult to show so I just put an avg grade and the total of subjects which I think correlated to the instructors avg. grade.

# Which department has the lowest enrollment? John

![screenshot](johnfcq.png)

As you can clearly see RASE has the lowest enrollment. The chart is ordered from least to greatest.

# Which subject is most in demand,based on the total number of enrollment? Sussant

![screenshot](sussantfcq.png)

Math has the highest enrollment. The chart is ordered from greatest to least.

# Which course has the highest enrollment? Andrew

![screenshot](andrewfcq.png)

For this one you can see that First year writing has the highest enrollment.

repository: jraesly/book

repo_name: jraesly/book


text:
---
title: "Greenkeeper"
author: Jan
layout: blog-post-tgif-ish
comments: true
---

This is Part 3 of our [little series about what has happened in Hoodie-land](http://hood.ie/blog/we-have-been-busy.html "We. Have. Been. Busy!") in the past <strike>three</strike>five months.

Stop worrying about npm dependencies breaking your build: Greenkeeper saves you time and money by automating dependency updates and notifying you of failed builds so you can spend your development time actually making things.

Greenkeeper came out of something we wanted for Hoodie anyway, and we found it useful in a client project, so we made a product out of it for everyone, why not! :)

We already got [interviewed by IBM about Greenkeeper](https://developer.ibm.com/clouddataservices/2015/10/07/greenkeeper-io-talks-about-node-js-dependency-tracking/).

![The Greenkeeper Workflow](http://greenkeeper.io/workflow_horizontal.png)

In the weeks after the release we’ve kept busy improving Greenkeeper based on user feedback:

1. Initial release: we pin your dependencies and send you a pull request for every update.

Some folks prefer dependency ranges, and others find frequent updates of some packages and the number of pull requests created off-putting.

2. So as a result, we introduced range support with our patented* [Real Time Dependency Break Detection](https://medium.com/greenkeeper-blog/announcing-real-time-dependency-break-detection-for-greenkeeper-4f7558c10d77). Now you get the best of both worlds: version ranges, so your end-users get the latest updates automatically, and you get fewer PRs, but you are still guaranteed to be told **if** a dependency sneaks in a breaking change in a valid version range.

3. The third release cleaned up a lot of little things and made the backend a lot more reliable. Outward facing, we now support your choice of tabs vs. spaces in your package.json (one of you is wrong, but we don’t care ;) and we added support for enabling Greenkeeper on repo forks, to support more workflows more flexibly.

4. This time, we didn’t change anything, but we made all our plans more valuable: every plan on Greenkeeper now comes with support for one private repo. This allows anyone to try out Greenkeeper in any setup without much hassle.

As a result of running this for about 10 weeks now, we are learning a lot about the npm ecosystem. We’ve already sent more than 20,000 pull requests, saving a lot of developer time.

We have a lot more planned for Greenkeeper, [so better sign up now](http://greenkeeper.io)!

branch_name: refs/heads/gh-pages

gha_language: HTML


text:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v3.0.0.html).

## [Unreleased]

## [v3.0.0]

### Added

### Changed

- BREAKING: Moved `userflow.js` from a dependency that's re-exported to being a peer dependency. To update, please `npm install userflow.js` in your own project, and `import userflow from 'userflow.js'`.
- BREAKING: The requirements for Content-Security-Policy has changed. Please consult [our CSP guide[https://userflow.com/docs/dev/csp].
- Moved source code to TypeScript + use Rollup to produce ESM and UMD builds.

[unreleased]: https://github.com/userflow/userflow-electron/compare/v3.0.0...HEAD
[v3.0.0]: https://github.com/userflow/userflow-electron/compare/v2.0.0...v3.0.0

repository: userflow/userflow-electron

branch_name: refs/heads/main

repo_name: userflow/userflow-electron


text:
---
templateKey: about-page
path: /terms-and-conditions/
title: Terms and Conditions
meta:
  description: Terms and Conditions
  robots: NOINDEX
---
# **Terms and Conditions:**

Top Bike tours Portugal, unipessoal, Lda as the headquarters in Rua do Alferes Malheiro 139, 4000-057 Porto, Portugal with VAT number 510 560 890, is licenced to be a tour operator ( nº 7/2014) and tourism agency (nº 7008)

**Reservation and cancellation Policy:**

1. Contact us to confirm if the Bike tour you intend to partake is available.
2. Signal: After receiving a notification from Top Bike Tours Portugal, Pvt. Lda to know that your tour is confirmed, you will need to forward a 35% payment signal. Payment can be done via paypal or by bank transfer.
3. The rest 65% of the payment must be made up to 60 days before the start of your bike tour.
4. If we do not receive the final payment before the mentioned deadline in paragraph 3, we will consider your bike tour cancelled. The signal you’ve payed, will not be refunded.
5. Outdoor activities are subject to weather conditions. In the eventuality of the company foreseeing the weather as a risk for the customer's safety, the company reserves the right to change the itineraries.
6. **Cancellation policy in guided bike tours:**

   1. **Cancellation requested 60 days before tour start :** With the exception of a cancellation fee of 20% of the total value of the package, the company will refund the entire value paid by the costumer, if the cancellation of the tour was notified 60 days before its start. That notification must be sent to Top Bike Tours Portugal, Unipessoal, Lda., by email.
   2. **Cancellation requested between 31 to 59 days:** 40% of the total amount paid will be refunded, if the company is notified at least 31 days before the start of the tour (info@topbiketoursportugal.com).
   3. **Cancellation requested 30 days, or less, before the tour start:** All cancellations communicated to Top Bike Tours Portugal, Pvt. Lda with less than 30 days in advance are not entitled to any refund.
7. **Cancellation policy in self guided bike tours:**

   1. **Cancellation requested 31 days before tour start:** With the exception of a cancellation fee of 15% of the total value of the package, the company will refund the entire value paid by the costumer, if the cancellation of the tour was notified 31 days before its start. That notification must be sent to Top Bike Tours Portugal, Unipessoal, Lda, by email..
   2. **Cancellation requested 30 days, or less, before the tour start:** All cancellations communicated to Top Bike Tours Portugal, Pvt. Lda, with less than 30 days in advance are entitled to a 30% refund.
8. Top Bike Tours Portugal, Unipessoal, Lda. is not responsible for refunding any amount paid for services that weren’t used by you.

**Safety:**

Participants should always follow the instructions of the guide and respect his decisions. The guide knows the route and the country better than anyone else and his priority is the SAFETY of everyone. Our aim is that all participants have fun, however everyone must be aware that their behavior in particular can not prevent the safety and fun of the whole group.

**Insurance:**

Top Bike Tours Portugal,Unipessoal, Lda. holds insurance in accordance with Portuguese law in effect for this type of activity. All participants in our guided activities are covered by Personal Accident insurance (Policy No. 85.00023213 Mútua dos Pescadores) worth 3.500,00 euros for medical expenses, and 20.000,00 euros in case of death or permanent disability insurance and Liability Policy No. 85.00023213 Mútua dos Pescadores ) worth 50.000,00 euros.

We recommend all participants to ensure their Travel Insurance has adequate coverage for Cancellation and Refund, Luggage, Medical Expenses and Repatriation, Death and Permanent Disability.

**Responsability**

Cycling is an adventure and it involves some risks. Participating in a bike tour implies awareness and acceptance of this risk by the participant. By having a bike tour with Top Bike Tours Portugal, Unipessoal, Lda. you are accepting all conditions contained in the terms described above. When we accept your booking, we accept to fulfill our obligations to you and other information that you provide. During the tour clients are responsible for the bicycle they rented. You can’t leave the bicycle alone and you must make proper use of it. If the bike is stolen or if any parts become damaged by misuse, the customer will have to pay their losses.

**Pictures:**

Top Bike Tours Portugal, Unipessoal, Ltd holds the right to use photos taken during activities for promotional purposes only and the marketing of our itineraries.

repository: omegasenior/topbiketoursportugal

gha_language: JavaScript

repo_name: omegasenior/topbiketoursportugal


text:
# UF2 Bootloader

This repository contains a bootloader, derived from Atmel's SAM-BA,
which in addition to the USB CDC (serial) protocol, also supports
the USB MSC (mass storage).

## UF2

**UF2 (USB Flashing Format)** is a name of a file format, developed by Microsoft, that is particularly
suitable for flashing devices over MSC devices. The file consists
of 512 byte blocks, each of which is self-contained and independent
of others.

Each 512 byte block consist of (see `uf2format.h` for details):
* magic numbers at the beginning and at the end
* address where the data should be flashed
* size of data
* data (up to 476 bytes; for SAMD it's 256 bytes so it's easy to flash in one go)

Thus, it's really easy for the microcontroller to recognize a block of
a UF2 file is written and immediately write it to flash.

* **UF2 specification repo:** https://github.com/Microsoft/uf2
* [#DeskOfLadyada UF24U ! LIVE @adafruit #adafruit #programming](https://youtu.be/WxCuB6jxLs0)

## Features

* USB CDC (Serial emulation) monitor mode compatible with Arduino
  (including XYZ commands) and BOSSA flashing tool
* USB MSC interface for writing UF2 files
* reading of the contests of the flash as an UF2 file via USB MSC
* UART Serial (real serial wire) monitor mode (typically disabled due to space constraints)
* In-memory logging for debugging - use the `logs` target to extract the logs using `openocd`
* double-tap reset to stay in the bootloader mode
* automatic reset after UF2 file is written

## Board identification

Configuration files for board `foo` are in `boards/foo/board_config.h` and `board.mk`. You can
build it with `make BOARD=foo`. You can also create `Makefile.user` file with `BOARD=foo`
to change the default.

The board configuration specifies the USB vendor/product name and ID,
as well as the volume label (main thing that the operating systems show).

There is also `BOARD_ID`, which is meant to be machine-readable and specific
to a given version of board hardware. The programming environment might use
this to suggest packages to be imported (i.e., a package for a particular
external flash chip, SD card etc.).

These configuration values can be read from `INFO_UF2.TXT` file.
Presence of this file can be tested to see if the board supports `UF2` flashing,
while contest, particularly `Board-ID` field, can be used for feature detection.

The current flash contents of the board is exposed as `CURRENT.UF2` file.
This file includes the bootloader address space. The last word of bootloader
space points to the string holding the `INFO_UF2.TXT` file, so it can be parsed
by a programming environment to determine which board does the `.UF2` file comes from.

## Handover

When the user space application implements the USB MSC protocol, it's possible to
handover execution to the bootloader in the middle of MSC file transfer,
when the application detects that a UF2 block is written.

Details are being finalized.

## Bootloader update

The bootloader will never write to its own flash area directly.
However, the user code can write there.
Thus, to update the bootloader, one can ship a user-space program,
that contains the new version of the bootloader and copies it to the
appropriate place in flash.

Such a program is generated during build in files `update-bootloader*.uf2`.
If you're already running UF2 bootloader, the easiest way to update
it, is to just copy this file to the exposed MSD drive.

## Build

### Requirements

* `make` and an Unix environment
* `arm-none-eabi-gcc` in the path (the one coming with Yotta will do just fine). You can get the latest version from ARM: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
* `openocd` - you can use the one coming with Arduino (after your install the M0 board support)

Atmel Studio is not supported.

You will need a board with `openocd` support.

Arduino Zero (or M0 Pro) will work just fine as it has an integrated USB EDBG
port. You need to connect both USB ports to your machine to debug - one is for
flashing and getting logs, the other is for the exposed MSC interface.

### Configuration

There is a number of configuration parameters at the top of `uf2.h` file.
Adjust them to your liking.

By default, you cannot enable all the features, as the bootloader would exceed
the 8k allocated to it by Arduino etc. It will assert on startup that it's not bigger
than 8k. Also, the linker script will not allow it.

Three typical configurations are:

* HID, WebUSB, MSC, plus flash reading via FAT; UART and CDC disabled;
  logging optional; **recommended**
* USB CDC and MSC, plus flash reading via FAT; UART disabled;
  logging optional; this may have Windows driver problems
* USB CDC and MSC, no flash reading via FAT (or at least `index.htm` disabled); UART enabled;
  logging disabled; no handover; no HID;
  only this one if you need the UART support in bootloader for whatever reason

CDC and MSC together will work on Linux and Mac with no drivers.
On Windows, if you have drivers installed for the USB ID chosen,
then CDC might work and MSC will not work;
otherwise, if you have no drivers, MSC will work, and CDC will work on Windows 10 only.
Thus, it's best to set the USB ID to one for which there are no drivers.

The bootloader sits at 0x00000000, and the application starts at 0x00002000.

## Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode<EMAIL_ADDRESS>with any additional questions or comments.

## License

See THIRD-PARTY-NOTICES.txt for the original SAM-BA bootloader license from Atmel.

The new code is licensed under MIT.

repository: Teknic-Inc/ClearCore-bootloader

repo_name: Teknic-Inc/ClearCore-bootloader


text:
# Digital Biomarker Discovery Pipeline (DBDP)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

The DBDP is created by the **BIG IDEAS Lab** at Duke University: http://dunn.pratt.duke.edu/

Digital biomarkers are digitally collected data that are transformed into indicators of health outcomes. The BIG IDEAS Lab is developing digital biomarkers for a range of diseases and conditions using a variety of sensors.

Digital biomarkers currently require extensive domain knowledge and computing skills. The purpose of the DBDP is to provide code sets, functions, and algorithms for the entire digital biomarker discovery pipeline to make discovering digital biomarkers more accessible. From the input of wearable sensor data to the development of machine learning and deep learning algorithms, we have provided an open source software resource for the digital biomarker community.

***

#### General Pipeline
1. DigitalBiomarkers-Preprocessing
2. DigitalBiomarkers-ExploratoryDataAnalysis

#### Current Digital Biomarkers
* DigitalBiomarkers-Sleep
* DigitalBiomarkers-HeartRateVariability
* DigitalBiomarkers-RestingHeartRate
* ...more coming soon!

For inclusion into the digital biomarkers discovery pipeline, please follow the instructions in the Instructions subdiretory and create an Issue.

***
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.


text:
---
layout: product
group: materials
subgroup: non-ferrous-metals
subtype: false
publish: true
comments: false
cover-image: "https://cdn11.bigcommerce.com/s-itwgldve/images/stencil/608x608/products/2337/6231/Aluminum_sheets_watermark_v1__69863.1675310618.png?c=2"
albums:
  album0:
    images:
        - "https://cdn11.bigcommerce.com/s-itwgldve/images/stencil/608x608/products/2337/6231/Aluminum_sheets_watermark_v1__69863.1675310618.png?c=2"
        - "https://cdn11.bigcommerce.com/s-itwgldve/images/stencil/608x608/products/2337/6230/Aluminum_sheets_stack_watermark_v1__43986.1675310618.png?c=2"

---

{% include album.html images=page.albums.album0.images cols=3 %}

### Information

Description:
 Aluminum sheets provide outstanding strength to weight ratio as well as corrosion resistance. Used to create real world projects that will outlast other materials.When your project calls for strength with amazing looks these aluminum sheets are perfect for the job. They come with heavy duty clear coat film on both sides protecting the surfaces from scratches to ensure you get the very best premium material. Features  1/8" thickness to create durable and functional parts  Perfect for CNC Router Cutting and Engraving  Lightweight and Rigid Protective plastic cover on both sides to prevent scratches while machining  What is Included  (1) Aluminum 6061-T6 12" x 12" x 1/8"  Product Specifications  Size  12" x 12"  Thickness:  1/8" Material:  Aluminum Alloy: 6061-T6 All registered Trademarks, Logos and other Intellectual Property found on the Site or mentioned herein belong to their respective owners.


text:
# Object-classification
Program to classify different objects

It's build from the face biometric project. For more insight visit that project.
This program is designed to identify different objects.

I have created custom objects and custom images to train them. I have trained the network to identify bottles
and mobile. However, you can design for as many classes of objects as you like.

The work flow of the program:
You would first create the profile of the object by its name and then the profile would be created under the train and test
directory respectively.
For capturing the object image you will give keep the name of the object (the name of the profile) in the first text field
and in the second give the alphabetical ordering of the new objects. say, ist obj: A, 2nd obj: B and so on.
However, the alphabet named sequence shouldn't be repeated. You can even keep the name of the object followed by numbers such as
1st obj: obj1, 2nd obj: obj2.

After you have collected all the custom data then you would want to train the model. Be sure to collect the same number of samples for
all the different objects. By default I have set it to 8 different sample by default. You can increase to as much as you want.
You can even record the different faces of the objects, but again the naming should be properly handled.

For the next session you wouldn't want to train again unless you have new objects to include. You would load the pretrained model
and then start detecting the objects.

The result of the objects would be shown in the Text area, and some of the raw computations and model descriptions would appear in
the terminal.

>>> Create a dataset directory, and training_set, test_set sub directories before executing the program.
8 capture sessions should be there in total. If you want more, be sure to change here:

self.classifier.fit_generator(training_set,
								 steps_per_epoch = self.compute_files()*64,  ---> 8*n
								 epochs = 2,
								 validation_data = test_set,
								 validation_steps = self.compute_files()*16)  ---> 2*n

  >>>  n is the number of capture sessions for different objects.


text:
# input-unified-pointers

[![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)

A unified input to use mouse and touch inputs as if they were the same. Essentially the mouse is another touch point.

## Usage

[![NPM](https://nodei.co/npm/input-unified-pointers.png)](https://nodei.co/npm/input-unified-pointers/)

## License

MIT, see [LICENSE.md](http://github.com/bunnybones1/input-unified-pointers/blob/master/LICENSE.md) for details.

repository: mattdesl/input-unified-pointers

repo_name: mattdesl/input-unified-pointers


text:
# Bootstrap Build Tools Starter

This starter repo may be for you if you want to:

- Eliminate duplication of redefining values to override Bootstrap’s defaults
- Reduce overall file size by leaving out parts of Bootstrap not needed for the project
- Remove the hassle of manually looking up and applying prefixes for things like flexbox
- Accomplish the above with minimal project bloat in terms of additional directories and other clutter

Used along with the post listed next, it is also beneficial if you are new to build tools.

## Getting Started

See the following post for instructions to get the project up and running on your local machine for development and testing purposes.

[Read: How to Use This Repo](http://thinkdobecreate.com/blog/2018/04/14/custom-bootstrap-builds-for-build-tool-n00bs/?utm_source=github&utm_medium=readme&utm_campaign=bt_instructions)

### Prerequisites

Familiarity with Bootstrap 4+ and SASS.

### Installing

Download or clone this repo, then [visit the post](http://thinkdobecreate.com/blog/2018/04/14/custom-bootstrap-builds-for-build-tool-n00bs/?utm_source=github&utm_medium=readme&utm_campaign=bt_instructions) if you are new to build tools.

## Author

* **Stephanie Eckles** - [ThinkDoBeCreate](http://thinkdobecreate.com/?utm_source=github&utm_medium=readme&utm_campaign=bt_instructions)

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details


text:
# _Pig Latin_

## _Kaila Goff_ and _Stephanie Faber_ version 1.0, 1/18/2018

### _Description_

A website to translate sentences input by the user into pig latin. The site has a title exclaiming Pig Latin, and there is a field to type words with a submit button below it.

#### _Known Bugs_

No known bugs at this time

# Setup/Installation
###### Clone from GitHub
###### Open in your preferred browser

## Technologies used

_HTML, CSS, JavaScript, Bootstrap, & jQuery_

### This project is under the MIT License

### Copyright 2018 _Kaila Goff_ & _Stephanie Faber_

repository: eyesicedover/pig-latin

repo_name: eyesicedover/pig-latin


text:
# tdd-codecamp

Step by step reference for the hands on session during the June 16, 2018 TDD codecamp.

## Getting Started

These instructions will get you a copy of the project up and running on your local machine. See [commits](https://github.com/laravelcebu/tdd-codecamp/commits/master) section for reference to the actual code changes made at each step.

## Prerequisites

- Laravel 5.6

## Instructions
Step by step documentation of the afternoon tdd hands on session.

### Steps

1. Let's begin by creating a new Laravel application. Open your terminal, navigate to your development directory and execute the following command
```sh
laravel new ticketbeast
```

2. Next we need to make our test file. This can be achieve using the following command
```sh
php artisan make:test PurchaseTicketsTest
```

3. Time to create our test case! Open the file `app/tests/Feature/PurchaseTicketsTest.php` and locate the following code
```php
/**
 * A basic test example.
 *
 * @return void
 */
public function testExample()
{
    $this->assertTrue(true);
}
```

Replace it with this bit
```php
/** @test */
public function customer_can_purchase_tickets()
{

    // Arrange

    // Act

    // Assert
}
```

Save the changes and run the test using the following command
```sh
./vendor/bin/phpunit --filter=customer_can_purchase_tickets
```

Which will give you the following result
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
This test did not perform any assertions

OK, but incomplete, skipped, or risky tests!
Tests: 1, Assertions: 0, Risky: 1.
```

**NOTE: The filter option indicates that only the given test case will be executed**

4. Lets add a couple more lines to reflect the general idea of how the test case should look like
```php
/** @test */
public function customer_can_purchase_tickets()
{
    // Arrange
    $concert = factory(Concert::class)->create();

    // Act
    $response = $this->post("concerts/{$concert->id}/orders", []);

    // Assert
    $response->assertStatus(201);
}
```

Save the changes and run the test again. Please note that we will be using the same command to run the test unless specified otherwise.
```sh
./vendor/bin/phpunit --filter=customer_can_purchase_tickets
```

At this point you should be seeing the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Error: Class 'Tests\Feature\Concert' not found
```

**TIP: Use the up arrow key to cycle thru your previously executed commands instead of typing or copy/paste to save time.**

5. Create the Concert model by executing the following command
```sh
php artisan make:model Concert
```

You will find out after running the test that we are still getting the same error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Error: Class 'Tests\Feature\Concert' not found
```

Let's fix that by updating the following code
```php
namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PurchaseTicketsTest extends TestCase
```

By aliasing our newly created `Concert` model
```php
namespace Tests\Feature;

use App\Concert;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class PurchaseTicketsTest extends TestCase
```

Running the test again will now result to
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
InvalidArgumentException: Unable to locate factory with name [default] [App\Concert].
```

6. Create a concert factory by executing the following command
```sh
php artisan make:factory ConcertFactory --model="App\Concert"
```

Run the test and arrive at the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Illuminate\Database\QueryException: SQLSTATE[HY000] [1045] Access denied for user 'homestead'@'localhost' (using password: YES) (SQL: insert into `concerts` (`updated_at`, `created_at`) values (2018-06-17 09:05:06, 2018-06-17 09:05:06))
```

7. Open the file ticketbeast\phpunit.xml and locate the following code
```php
<php>
    <env name="APP_ENV" value="testing"/>
    <env name="BCRYPT_ROUNDS" value="4"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
    <env name="MAIL_DRIVER" value="array"/>
</php>
```

Update it to
```php
<php>
    <env name="APP_ENV" value="testing"/>
    <env name="BCRYPT_ROUNDS" value="4"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
    <env name="MAIL_DRIVER" value="array"/>
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value=":memory:"/>
</php>
```

Save the changes and run the test again. This will now result to the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such table: concerts (SQL: insert into "concerts" ("updated_at", "created_at") values (2018-06-17 09:18:25, 2018-06-17 09:18:25))
```

8. Create a migration file by executing the following command
```sh
php artisan make:migration create_concerts_table --create=concerts
```

Running the test again however will result to the same error

Locate the following code in `PurchaseTicketsTest.php`
```php
class PurchaseTicketsTest extends TestCase
{
    /** @test */
    public function customer_can_purchase_tickets()
    {
```

And let's update it to
```php
class PurchaseTicketsTest extends TestCase
{
	use DatabaseMigrations;

	/** @test */
    public function customer_can_purchase_tickets()
    {
```

**NOTE: Adding this line will simply run the migration files automatically everytime the test is run**

Running the test will now give us the following error
```sh
PHP Fatal error:  Trait 'Tests\Feature\DatabaseMigrations' not found in /ticketbeast/tests/Feature/PurchaseTicketsTest.php on line 12
```

Go back to `PurchaseTicketsTest.php` and locate the following code
```php
use App\Concert;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
```

Update it to the following code, save and run the test again
```php
use App\Concert;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
```

It should now give us the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Expected status code 201 but received 404.
Failed asserting that false is true.
```

9. Create controller which will handle all concert ticket order requests by executing the following command
```sh
php artisan make:controller ConcertOrderController --model="App\Concert" --api
```

Open the file `ticketbeast/Http/Controllers/ConcertOrderController.php` and locate the following code
```php
public function store(Request $request)
{
    //
}
```

Let's update it to the following for now
```php
public function store(Request $request)
{
    return response()->json([], 201);
}
```

Save the changes and run the test. This will still result to the same error.

Open `ticketbeast/routes/web.php` and append the following code
```php
Route::post('concerts/{concert}/orders', 'ConcertOrderController@store');
```

Run the test again and BOOM! Our first green light! :muscle: (technically!)
```sh
PHPUnit 7.2.4 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 157 ms, Memory: 16.00MB
```

10. Next, let's update our `customer_can_purchase_tickets` to the following code
```php
	public function customer_can_purchase_tickets()
    {
        // Arrange
        $concert = factory(Concert::class)->create([
        	'ticket_price' => 3250
        ]);

        // Act
        $response = $this->post("concerts/{$concert->id}/orders", [
        	'email' 			=><EMAIL_ADDRESS>            'ticket_quantity' 	=> 3,
            'payment_gateway' 	=> $paymentGateway->getValidTestToken()
        ]);

        // Assert
        $response->assertStatus(201);

        $this->assertEquals(9750, $paymentGateway->totalCharges());
    }
```

**NOTE: total charges = ticket price x ticket quantity = 3250 x 3 = 9750 **

Running the test will now give us the error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 table concerts has no column named ticket_price (SQL: insert into "concerts" ("ticket_price", "updated_at", "created_at") values (3250, 2018-06-17 10:18:09, 2018-06-17 10:18:09))
```

11. Open the `create_concerts_table` migration file and locate the following code

**NOTE: Exact file names will be prefixed differently, _\<prefix\>_create_concerts_table.php_**

```php
Schema::create('concerts', function (Blueprint $table) {
    $table->increments('id');
    $table->timestamps();
});
```

Add a column for ticket price, save and run the test
```php
Schema::create('concerts', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('ticket_price');
    $table->timestamps();
});
```

At this point you should be seeing the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
ErrorException: Undefined variable: paymentGateway
```

12. Create a folder `app/Billing` and create a file `FakePaymentGateway.php` under it

Open and update it's contents to
```php
<?php

namespace App\Billing;

class FakePaymentGateway
{

}
```

Now let's go over to `PurchaseTicketsTest.php` and add the following code
```php
$paymentGateway = new FakePaymentGateway();
```

So that it now looks like this
```php
// Arrange
$paymentGateway = new FakePaymentGateway();
$concert = factory(Concert::class)->create([
    'ticket_price' => 3250
]);
```

After running the test again, the error should have now changed to
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Error: Class 'Tests\Feature\FakePaymentGateway' not found
```

Fixing the reference should be easy enough, like this
```php
use App\Billing\FakePaymentGateway;
use App\Concert;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
```

Save, run the test and now we got ourselves a different error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Error: Call to undefined method App\Billing\FakePaymentGateway::getValidTestToken()
```

Let's add the following method to `FakePaymentGateway.php`
```php
public function getValidTestToken()
{
    return 'valid-token';
}
```

Save and run again to arrive at the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Error: Call to undefined method App\Billing\FakePaymentGateway::totalCharges()
```

This time let's update `FakePaymentGateway.php` so that it now looks like this
```php
class FakePaymentGateway
{
    protected $charges;

    public function __construct()
    {
        $this->charges = collect();
    }

    public function getValidTestToken()
    {
        return 'valid-token';
    }

    public function totalCharges()
    {
        return $this->charges->sum();
    }
}
```
**NOTE: Please refer to the official documentation for [collect](https://laravel.com/docs/5.6/collections)**

At this point the error should now be
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Failed asserting that 0 matches expected 9750.
```

13. Head over to `ConcertOrderController.php` and update the store method to
```php
public function store(Request $request, $concertId)
{
    $paymentGateway = new FakePaymentGateway();
    $concert = Concert::find($concertId);

    $amount = $concert->ticket_price * $request->get('ticket_quantity');
    $paymentGateway->charge($amount, $request->get('payment_gateway'));

    return response()->json([], 201);
}
```

Running the test will now result to
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Expected status code 201 but received 500.
Failed asserting that false is true.
```

Which isn't very helpful so let's open `app\Exceptions\Handler.php`, find and update the report method to
```php
public function report(Exception $exception)
{
    throw $exception;
    parent::report($exception);
}
```
**NOTE: During the actual hands on session, the report method was updated somewhere between step 8 and 9.**

If we run the test again it will now give us
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Symfony\Component\Debug\Exception\FatalThrowableError: Class 'App\Http\Controllers\FakePaymentGateway' not found
```

Ah, much better. Do remember to remove the throw before you publish your code, it is meant for debugging only!

Let's go ahead and add a reference to `FakePaymentGateway`
```php
use App\Billing\FakePaymentGateway;
use App\Concert;
use Illuminate\Http\Request;

class ConcertOrderController extends Controller
```

Once we have that the error should now be
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method App\Billing\FakePaymentGateway::charge()
```

Go ahead and define that method
```php
public function charge($amount, $token)
{
    $this->charges->push($amount);
}
```

Save and run the test so the result will now be
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Failed asserting that 0 matches expected 9750.
```

14. Let's recap
At the end of step 12 we had the following error
```sh
1) Tests\Feature\PurchaseTicketsTest::customer_can_purchase_tickets
Failed asserting that 0 matches expected 9750.
```

During step 13 we added the charge logic which is
```
total charges = ticket price x ticket quantity
```

However we still arrived on the same error before at the beginning of step 13!

Why?

Remember this from `PurchaseTicketsTest.php`?
```php
$paymentGateway = new FakePaymentGateway();
```

We can see here that a new fake payment gateway is being initialized

Moving along the `customer_can_purchase_tickets` method you will see
```php
$response = $this->post("concerts/{$concert->id}/orders", [
    'email'             =><EMAIL_ADDRESS>    'ticket_quantity'   => 3,
    'payment_gateway'   => $paymentGateway->getValidTestToken()
]);
```

Which calls the store method in `ConcertOrderController.php` and a new fake payment gateway is being initialized
```php
$paymentGateway = new FakePaymentGateway();
```

Even thou we added the charge logic and invoke the fake payment gateway charge method and seen below
```php
$amount = $concert->ticket_price * $request->get('ticket_quantity');
$paymentGateway->charge($amount, $request->get('payment_gateway'));
```

Because `$paymentGateway` in `PurchaseTicketsTest.php` is a different instance of `FakePaymentGateway` from that of `$paymentGateway` in `ConcertOrderController.php` it will not be able to receive the changes that have been made when the charge method was invoked in `ConcertOrderController.php`.

To resolve this we need to modify the `FakePaymentGateway` so it implements the Singleton design pattern, ergo it will return the same exact instance everytime it is initialized.

Let's get started.

Create a file named `PaymentGateway.php` under `ticketbeast\app\Billing` and with the following content
```php
<?php

namespace App\Billing;

interface PaymentGateway
{
    public function charge($amount, $token);
}
```

Update `FakePaymentGateway` so that it now looks like this
```php
class FakePaymentGateway implements PaymentGateway
```

Next update `ConcertOrderController.php` to
```php
use App\Billing\FakePaymentGateway;
use App\Billing\PaymentGateway;
use App\Concert;
use Illuminate\Http\Request;

class ConcertOrderController extends Controller
{
    protected $paymentGateway;

    public function __construct(PaymentGateway $paymentGateway)
    {
        $this->paymentGateway = $paymentGateway;
    }
```

And the store method to
```php
public function store(Request $request, $concertId)
{
    $concert = Concert::find($concertId);

    $amount = $concert->ticket_price * $request->get('ticket_quantity');
    $this->paymentGateway->charge($amount, $request->get('payment_gateway'));

    return response()->json([], 201);
}
```

Next we will update `PurchaseTicketsTest.php` to
```php
use App\Billing\FakePaymentGateway;
use App\Concert;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class PurchaseTicketsTest extends TestCase
```

And `customer_can_purchase_tickets` to
```php
public function customer_can_purchase_tickets()
{
    // Arrange
    $paymentGateway = new FakePaymentGateway();
    $this->app->instance(PaymentGateway::class, $paymentGateway);

    $concert = factory(Concert::class)->create([
        'ticket_price' => 3250
    ]);
```

If we run the test again, we should have arrive at a green light with a message similar or equal to
```sh
PHPUnit 7.2.4 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 149 ms, Memory: 16.00MB

OK (1 test, 2 assertions)
```

## Authors

* **Harlequin Doyon** - *Resource Speaker* - [harlekoy](https://github.com/harlekoy)
* **Laravel Cebu** - *Event organizers* - [laravelcebu](https://github.com/laravelcebu)
* **Ian Panara** - *Documentation* - [fatcodingbastard](https://github.com/fatcodingbastard)

See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

## Acknowledgments

* Hat tip to anyone whose code was used
* Sponsors
* Event Organizers
* Resource speakers
* etc

repository: dorelljames/tdd-codecamp

gha_language: PHP

repo_name: dorelljames/tdd-codecamp


text:
licenseplate-game-bruteforce
============================

Consider this a personal repo likely to be of no value to anyone else. Move
along.

The game can be found described
[here](https://en.wikipedia.org/wiki/Car_numberplate_game#In_Europe) (presently
it is the 4th paragraph).
In my family, the rule was always "Shortest and alphebetically earliest is
best", so I proceeded with that assumption.

It may be run with `ruby solve.rb`. Whatever dictionary is present at
`/usr/share/dict/words` will be used.

repository: euank/licenseplate-game-bruteforce

repo_name: euank/licenseplate-game-bruteforce


text:
---
layout: post
title: Ghost 3.x on Google App Engine Standard with Cloudinary and Secret Manager
image: google-free-tier.png
date:  2020-07-06 12:00:00
description: "Technology and Health are my passions. It is my life goal to conquer diabetes
              using technology. It has been twenty-four years since I wrote my first computer program on an old computer running GW-BASIC. Today, I no longer open my shoes outside my computer room to protect it from viruses, but I am always fascinated by programming as writing first \"print 10+20\". Since last December, I have been trying to document my triumphs
              and defeats over diabetes in a structured way. I want to create the easiest, best, fastest, and cheapest tool to control diabetes. After limited research, I zeroed in on ghost blogs
              hosted on google cloud to document my journey. However, there is no single source of
              truth that tells me correctly how to do it."
---
## What to Build?

My thirteen years of diabetes has told me in no uncertain terms that medicine alone is not enough to control diabetes. I wanted to build a product to use technology to help manage diabetes.
I have a strong bias in building products with early adopters. To this end, I decided to make a website
to chronicle the product journey. This product was going to be a dense content blog.
I am a fan of Medium as a product. There is something about the simplicity of the entire experience.
However, Medium has long disabled the ability of mere mortals to host custom domains. Hence, I did the next best thing I googled "medium vs.." The ghost team had done an excellent job on SEO. It met most of my criteria.

## How to host?

Having decided on "Ghost," the question was where to host to achieve the cheapest costs. In November 2019, it invariably
meant determining between which cloud to use. As a software engineer, I hate to pay for software. Of Google, AWS and Azure, only
Google had a perpetual free tier. Google was also distributing 300$ of free credit. So, I decided to go to google.

### Step 1: The Journey Starts with a google search.

Programming today is ninety percent knowing what to google. I started my journey with the search for *"How to host ghost CMS on AppEngine?"*
![Ghost Hosting Google Results](/assets/img/ghost-google-res.png "Ghost Hosting Result")

My first preference was to follow the default guide of the app engine. However, it severely restricts the ability to customize the installation. I discarded the approach. It did highlight a few issues.

* Default Ghost uses local file storage. It is something that is not practical in app-engine.
* The tutorial mentioned something about costs. Unfortunately, I did not pay much attention to it. I would regret it later. (
AppEngine is free only for the standard edition. All tutorials were for flex; this was not free and way too expensive for a
hobby project.)

### Challenge 1: MySql Socket

I wanted to use Cloud SQL as a database. The recommended way to connect to cloud SQL from App Engine is via a Unix socket. At that time,
I was new to Unix socket, and most of the documentation was around connecting to TCP MySQL. It took me some time to realize that
I need to use the environment variable `database__connection__socketPath` instead of `database__connection__host` and
`database__connection__port`.

### Challenge 2: Using Cloudinary for images
I love Cloudinary to host images. It helps that they have a free tier in addition to amazing features. I was encouraged by
an official plugin. There is a quirk in ghost repository wherein adapters cannot be installed as npm plugins. Rather, one has to
move the entire plugin to the installation folder. I found this strange, but I shouldered on.
```bash
$ yarn add ghost-storage-cloudinary@2
$ mv node_modules/ghost-storage-cloudinary core/server/adapters/storage
```
The above commands have been lifted verbatim from the official repository. At this point, I had decided to go with docker deployment, and the plugin came with a  public docker repository.

### Challenge 3: Masquerade mailing list feature for research

The whole reason behind creating this blog was to find early adopters of the platform. I decided to use the default subscribe
feature of Ghost. I also chose to use Mailgun as my backend for the mailing list. I had to do some minor edits to a few
templates and CSS. I was up and away with less than a hundred lines of code. I started documenting my battles.

### Challenge 4: Environment Variables and Cost

In my excitement, I had missed reading the fine print of the free tier—the cheapest flex app engine costs over sixty dollars per month.
I had also punted on secret environment variables. At this moment my Dockerfile looked like

```docker
FROM ghost:3.0.3-alpine as cloudinary
WORKDIR $GHOST_INSTALL/current
ADD subscribe-form.hbs $GHOST_INSTALL/current/content/themes/casper/partials/subscribe-form.hbs
RUN chown node:node $GHOST_INSTALL/current/content/themes/casper/partials/subscribe-form.hbs
ADD default.hbs $GHOST_INSTALL/current/content/themes/casper/default.hbs
RUN chown node:node $GHOST_INSTALL/current/content/themes/casper/default.hbs
ADD site-nav.hbs $GHOST_INSTALL/current/content/themes/casper/partials/site-nav.hbs
RUN chown node:node $GHOST_INSTALL/current/content/themes/casper/partials/site-nav.hbs
ADD screen.css   $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css
RUN chown node:node $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css
ADD screen.css   $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css.map
RUN chown node:node $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css.map
RUN su-exec node yarn add ghost-storage-cloudinary@2

FROM ghost:3.0.3-alpine
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/node_modules $GHOST_INSTALL/current/node_modules
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/node_modules/ghost-storage-cloudinary $GHOST_INSTALL/current/core/server/adapters/storage/ghostStorageCloudinary
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/content/themes/casper/partials/subscribe-form.hbs $GHOST_INSTALL/current/content/themes/casper/partials/subscribe-form.hbs
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/content/themes/casper/default.hbs $GHOST_INSTALL/current/content/themes/casper/default.hbs
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/content/themes/casper/partials/site-nav.hbs $GHOST_INSTALL/current/content/themes/casper/partials/site-nav.hbs
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css  $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css
COPY --chown=node:node --from=cloudinary $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css.map  $GHOST_INSTALL/current/content/themes/casper/assets/built/screen.css.map

RUN set -ex; \
    su-exec node ghost config storage.active ghost-storage-cloudinary; \
    su-exec node ghost config storage.ghostStorageCloudinary.upload.use_filename false; \
    su-exec node ghost config storage.ghostStorageCloudinary.upload.unique_filename true; \
    su-exec node ghost config storage.ghostStorageCloudinary.upload.overwrite false; \
    su-exec node ghost config storage.ghostStorageCloudinary.fetch.quality auto; \
    su-exec node ghost config storage.ghostStorageCloudinary.fetch.secure true;
```

My app.yaml looked like
```yaml
env_variables:
  database__client: mysql
  url: "https://www.project1922.com"
  database__connection__user: "<hardcoded_user>"
  database__connection__password: "<hard_coded password>"
  database__connection__database: "ghost"
  database__connection__socketPath: "/cloudsql/project1922-ghost-blog:us-central1:project-1922-ghost-db"
  mail__transport: "SMTP"
  mail__options__service: "Maligun"
  mail__options__port: 465
  mail__options__host: smtp.mailgun.org
  mail__options__secureConnection: true
  mail__options__auth__user<EMAIL_ADDRESS>  mail__options__auth__pass: <hardcoded_password>
  storage__active: "ghostStorageCloudinary"
  storage__ghostStorageCloudinary__auth__cloud_name: project1922-cloudinary-images
  storage__ghostStorageCloudinary__auth__api_key: <hard_coded>
  storage__ghostStorageCloudinary__auth__api_secret: <hard_coded>
  # The connection name of your instance on its Overview page in the Google
  # Cloud Platform Console, or use `YOUR_PROJECT_ID:YOUR_REGION:YOUR_INSTANCE_NAME`
```
It was a ticking time bomb.

#### Strike 1: Wrong files got pushed
One day, I pushed my app.yaml to a public repo, and my secret keys got exposed. Luckily,
MailGun monitors for exposures. On being alerted, I took evasive actions. I changed the keys and made the repository private.

#### Strike 2: Ran out of free google credits.

Five months elapsed, the blog was running in maintenance mode. Unknown to me, I was burning through free credits, and then I
saw a charge on my credit card. I was alarmed due to past incidents of exposed MailGun keys. I punted for one month. After two months, I decided to fix things. I found that free is only for the standard instance. I decided to move to the standard installation.

### Challenge 5: Let the Source be with you

Ghost documentation actively discourages building from the source.
![Ghost Documentation ScreenShot](/assets/img/ghost-web.png "Ghost Documentation")

They have an excellent CLI tool to install the blog. However, I did not quite like black magic. I thought of installing
as an npm module and overriding the template files inside the node_modules as part of the  startup.
It worked for my localhost but would not work in the app engine. App Engine uses a read-only file system for code. So, I decided
to go with the source. By this time, I had familiarized myself with essential files and what the CLI did.

### Challenge 6: What's in a (variable) name?

I followed documentation of *Install from Source* and managed to get the blog running locally. Now, it was time
to go for the app engine and slay the cost monster.  However, the app engine would not budge easily. It ran into issues with the node version. It was easy to fix. ```"node": "12.X.X",``` instead of ```"node": "^10.13.0 || ^12.10.0",``` fixed this.
However, the blog was not reachable on the internet. Debug logs showed nothing. All I got was a warning
*"App is listening on port 8080. We recommend your App listen on the port defined by the
 PORT environment variable to take advantage of an NGINX layer on port 8080"*
. All things pointed towards a PORT issue. I was running my App on port 8080, the default app for the app engine. The way ghost works are that
it listens on a port defined by the environment variable server__port. GAE had changed the behavior of the app engine to expose this variable as
"PORT".  I had to change the behavior of the ghost code to listen to this variable. I checked my hypothesis by adding the lines
```process.env.PORT || config.get('server').port,``` to *ghost-server.js*. Voila!! It worked. I did not want to change the internal implementation of
Ghost. I decided to change the main index.js file.

```javascript
if(process.env.server__port || process.env.PORT){
    process.env.server__port = process.env.server__port || process.env.PORT ;; //Required for GAE
}
```

It worked, and the blog was working again with reduced costs. The PORT battles led me to believe that I could change default index.js to make the file
compatible with GAE. It will also allow me to take advantage of future changes to Ghost.

### Challenge 7: Secret Environment Variables

All my life, I had used environment variables to store secrets. This architecture left me with problems like exposed private keys. I thought of
solving this problem for my hobby project. I had already bought myself into the idea of injecting environment variables as part of
my startup script. Google had recently introduced "Secret Manager", it seemed like the recommended way to store secrets. I could
fetch the required environment variables as a startup. I could use IAM credentials to restrict access to the keys via service accounts.
As with everything new, there were a few things I had to learn my way.
* First, create secrets using UI.
* Give the default AppEngine service account access to access the secret keys.
* Every secret has version and secret value has to be fetched as payload of enabled version.
```javascript
//Final js code1
if(process.env.server__port || process.env.PORT){
    process.env.server__port = process.env.server__port || process.env.PORT ;; //Required for GA
}
const ReadSecret = require('./utils');

// This is what listen gets called on, it needs to be a full Express App
async function startUp(){
    // Use the request handler at the top level
// @TODO: decide if this should be here or in parent App - should it come after request id mw?
    const secretKeys= process.env.secretKeys ||
        "database__connection__user," +
        "database__connection__password," +
        "mail__options__auth__user," +
        "mail__options__auth__pass," +
        "storage__ghostStorageCloudinary__auth__api_key," +
        "storage__ghostStorageCloudinary__auth__api_secret";

    const secretKeysArr = secretKeys.split(",");
    if((process.env.GOOGLE_CLOUD_PROJECT)!=null){
        const project = process.env.GOOGLE_CLOUD_PROJECT;
        for(key of secretKeysArr){
            process.env[key] = await ReadSecret.readSecret(`projects/${project}/secrets/${key}/versions/1`);
        }
    }
    const startTime = Date.now();
    const debug = require('ghost-ignition').debug('boot:index');
// Sentry must be initialised early on
    const sentry = require('./core/shared/sentry');

    debug('First requires...');

    const ghost = require('./core');

    debug('Required ghost');

    const express = require('./core/shared/express');
    const logging = require('./core/shared/logging');
    const urlService = require('./core/frontend/services/url');
    const ghostApp = express('ghost');

    ghostApp.use(sentry.requestHandler);

    debug('Initialising Ghost');

    ghost().then(function (ghostServer) {
        // Mount our Ghost instance on our desired subdirectory path if it exists.
        ghostApp.use(urlService.utils.getSubdir(), ghostServer.rootApp);

        debug('Starting Ghost');
        // Let Ghost handle starting our server instance.
        return ghostServer.start(ghostApp)
            .then(function afterStart() {
                logging.info('Ghost boot', (Date.now() - startTime) / 1000 + 's');
            });
    }).catch(function (err) {
        logging.error(err);
        setTimeout(() => {
            process.exit(-1);
        }, 100);
    });
};
startUp();

```

```javascript
async function readSecret(name ) {

        // Imports the Secret Manager library
    const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');

    // Instantiates a client
    const client = new SecretManagerServiceClient();

    async function getSecret() {
        const [version] = await client.accessSecretVersion({
            name: name,
        });
        const payload = version.payload.data.toString();

        return payload;
    }

    return getSecret();
    // [END secretmanager_get_secret]
};

module.exports = {readSecret:readSecret};
```
```yaml
runtime: nodejs12
env_variables:
  database__client: mysql
  url: "https://www.project1922.com"
  database__connection__database: ghost
  database__connection__socketPath: "/cloudsql/project1922-ghost-blog:us-central1:project-1922-ghost-db"
  mail__transport: "SMTP"
  mail__options__service: "Maligun"
  mail__options__port: 465
  mail__options__host: smtp.mailgun.org
  mail__options__secureConnection: true
```

It all worked, and I had a clean repository without any hardcoded secret variables.

## PostScript
When writing this post, I came across another post on Ghost 3.0. https://savviest.com/blog/hosting-a-ghost-3-0-blog-on-google-app-engine/. This tutorial was not available when I had started working on my first version and seems like a great option.

### Why is it almost free?

* Cloud SQL is not free, and at its cheapest, it costs about 7 $ per month. Potentially, I could host F1 micro compute engine to run MySQL but
I did not want to deal with it.
* Secret Manager. It should cost less than 1 $ per month.

### References
* https://cloud.google.com/community/tutorials/ghost-on-app-engine-part-1-deploying
* https://ghost.org/docs/install/source/
* https://cloud.google.com/secret-manager/docs
* https://cloud.google.com/free/
* https://www.project1922.com

extension: markdown

gha_language: SCSS


text:
---
title: "Cracking .DMG, .RAR and other passwords on MacOS"
categories:
- Security
- Programming
tags:
- john the ripper
- password
- cracking
- macos
# https://www.iconfinder.com/icons/4757447/key_lock_password_secure_security_icon
thumbnail: thumbnail.svg
---

[John The Ripper](https://www.openwall.com/john/) is a free and open-source software for fast password cracking. Cracking DMG, RAR and other types of passwords is made easier using [magnumripper's "jumbo" version of John The Ripper](https://github.com/magnumripper/JohnTheRipper).
<!-- more -->

## Install John

Install John The Ripper using `brew`

```shell-session
$ brew install john-jumbo
```

## Find John The Ripper Utilities Folder

John comes with extra utilities to help generate hashes. By default `brew` does not install/symlink john's extra utilities to the PATH folder `/usr/local/bin`. The path can be found in a variety of ways:

1. Using `ls` and following the path will eventually return `/usr/local/Cellar/john-jumbo/1.9.0/share/john/` or similar:

```shell-session
$ ls -al /usr/local/bin/john
lrwxr-xr-x 1 admin admin 35 Mar 16 20:04 /usr/local/bin/john -> ../Cellar/john-jumbo/1.9.0/bin/john

$ ls -al /usr/local/Cellar/john-jumbo/1.9.0/bin/john
lrwxr-xr-x 1 calvin staff 18 May 15  2019 /usr/local/Cellar/john-jumbo/1.9.0/bin/john -> ../share/john/john

$ ls -1 /usr/local/Cellar/john-jumbo/1.9.0/share/john/ | head -n 5
1password2john.py
7z2john.pl
DPAPImk2john.py
SIPdump
adxcsouf2john.py
```

2. If you have `readlink` installed, it's even easier:

```shell-session
$ dirname $(readlink -f /usr/local/bin/john)
/usr/local/Cellar/john-jumbo/1.9.0/share/john
```

## Generating Hashes

When cracking files, John cracks the hash of the password rather than the file itself. To generate the hash files, we use the extra utilities from the folder in the last step.

For DMG files, we'll pass the `encrypted-files.dmg` file to the `dmg2john` command and output the hash to a `.hash` file.

```shell-session
$ /usr/local/Cellar/john-jumbo/1.9.0/share/john/dmg2john encrypted-files.dmg > encrypted-files.dmg.hash
encrypted-files.dmg (DMG v2) successfully parsed, iterations count 333333
```

The other tools available to generate hash files are:

- RAR: `rar2john_cmd`
- PDF: `pdf2john.pl`
- ZIP: `zip2john`
- 7Z: `7z2john.pl`

## Crack the Hash

The last step is to crack the hash. We use the `john` tool directly for this step.

To ensure the GPU instead of the CPU is doing the cracking, specify a format with `-opencl` in its suffix. For example, `dmg` will be significantly slower than using `dmg-opencl`.

```shell-session
$ john --format=dmg-opencl encrypted-files.dmg.hash
Device 3: AMD Radeon Pro 560X Compute Engine
Using default input encoding: UTF-8
Loaded 1 password hash (dmg-opencl, Apple DMG [PBKDF2-SHA1 3DES/AES OpenCL])
Cost 1 (iteration count) is 333333 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Error creating binary cache file: No such file or directory
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 13888 candidates left, minimum 16384 needed for performance.
abc_123 (encrypted-files.dmg)
1g 0:00:00:57 N/A 0.01747g/s 815.3p/s 815.3c/s 815.3C/s abc_000..abc_123
Use the "--show" option to display all of the cracked passwords reliably
Session completed
```

You can see the password above is `abc_123`. If it's not clear you can run `john --show encrypted-files.dmg.hash` to present it clearer.

To make things even faster, if you have an idea of what the password is, you can pass a regular expression to john using the `--mask` flag.

```shell-session
$ john --format=dmg-opencl --mask="abc_[0-9][0-9][0-9]" encrypted-files.dmg.hash
```

Another thing I like to do at the end is remove the password on the DMG file and keep it empty:

```shell-session
$ printf '%s\0' abc_123 '' | hdiutil chpass encrypted-files.dmg -oldstdinpass -newstdinpass
```

Now when you open it, click the OK button.

![](enter-password.png)

## Script

To put all the above together, I use this script to set aliases to crack DMG files

```bash
#!/usr/bin/env bash

dmg2john_cmd(){
  echo "Generating hash file"
  "$(dirname $(readlink -f /usr/local/bin/john))/dmg2john" "$1"
}

dmgcrack(){
  dmg="$1"
  dmg2john_cmd "${dmg}" > "${dmg}".hash
  john --format=dmg-opencl "${dmg}".hash
  password=$(john --show "${dmg}".hash | sed '1q;d' | cut -d':' -f2)
  echo "The password for $dmg is $password"
  echo "Setting empty password"
  printf '%s\0' "$password" '' | hdiutil chpass "${dmg}" -oldstdinpass -newstdinpass
  rm "${dmg}".hash
}
```


text:
# How to Contribute to Ann Arbor

We welcome contributions to Ann Arbor!  Ann Arbor is a collaborative project and is made better by multiple contributors.

Be sure you are familiar with Ann Arbor's licensing and code of conduct before you submit to the project.  Important information can also be found in the README.

## Reporting a Bug
* If you found a bug, please check our [issues](https://github.com/formulafolios/ann-arbor/issues).  If the bug is already there, you can add your feedback or open a pull request to fix the bug yourself (see the pull request section below).
* If you do not find an issue for this bug, open a new issue.  Include as much information as you can, including a title, a clear description of the problem, how to recreate the issue, the operating system used when the bug was encountered, the expected behavior, and the actual behavior of the application.

## Open a Pull Request

**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)

If you would like to submit code, style fixes, wording fixes, or changes to documentation, open a pull request.

* Fork and clone the repository
* Create a new branch off of develop for your changes
* Make changes.  Include tests if warranted
* Run nosetests and use a linter (we use [Flake8](http://flake8.pycqa.org/en/latest/)).  Fix any issues
* Pull develop back into your branch and fix any merge conflicts
* Push your changes
* Open a pull request that will merge your branch into develop
* Make sure you give your pull request an informative title
* Provide complete information of what is being changed in the pull request description
* If this pull request will resolve an issue, include a link to the issue in the description

repository: bennpham/ann-arbor

repo_name: bennpham/ann-arbor


text:
# redux-pagestate

## API

### Action Creators

#### set({ key:String, value:JSON, paths:Array<String> })

Sets the pagestate for the specified page.

`key : String` [required]
The name of the page.

`value : JSON` [required]
The new value of the page.  The type can be any valid JSON data type: Number, String, Boolean, Array, Object, null,
undefined.

`paths : Array<String>` [optional]
The paths that the page's state is valid for.  If no path is supplied then the current paths are not modified.

repository: etalisoft/redux-pagestate

repo_name: etalisoft/redux-pagestate


text:
---
title: Paint Box
level: 1
language: en-GB
stylesheet: scratch
embeds: "*.png"
materials: ["Club Leader Resources/*.*","Project Resources/*.*"]
---

# Introduction { .intro }

In this project, you will be making your own paint program!

# Step 1: Making a pen { .activity }

Let's start by making a pen, that can be used to draw on the stage.

## Activity Checklist { .check }

+ Start a new Scratch project, and delete the cat sprite so that your project is empty. You can find the online Scratch editor at jumpto.cc/scratch-new.

+ For this project, you should have a 'Project Resources' folder, containing all of the images you'll need. Make sure that you can find this folder, and ask your club leader if you can't find it.

	![screenshot](paint-resources.png)

+ Let's add the drawing canvas image to your stage. Click the stage, and then click 'Upload backdrop from file'.

	![screenshot](paint-file.png)

+ Find your 'Project Resources' folder, and choose the file called 'frame.png'. If you don't have this image you can draw your own backdrop! Your stage should now look like this:

	![screenshot](paint-frame.png)

+ Let's also add a pen to your project. Click 'Upload sprite from file' and choose the image called 'blue-pencil.png' from your resources folder. Again, if you don't have this image you can draw your own. Click the `i` {.blockmotion} icon, and name this sprite 'Pen'.

	![screenshot](paint-blue-pencil.png)

+ As you'll be using the mouse to draw, you'll want the pen to always follow the mouse. Add this code to your pen sprite:

	```blocks
		when flag clicked
		forever
		  go to [mouse pointer v]
		end
	```

+ Test out this code by clicking the flag and then moving the mouse around the stage. Does this work as you expected?

+ Have you noticed that it's the centre of the pen, and not the tip, that follows the mouse pointer?

	![screenshot](paint-center.png)

	To fix this, click on the 'blue-pencil' costume of your pen sprite, and click 'Set costume center'.

	![screenshot](paint-center-icon.png)

+ You should notice that a crosshair appears on the costume. You can now click just below the tip of the pen, to set this point as the costume centre.

	![screenshot](paint-pen-center.png)

+ Click the 'Scripts' tab, and then test out your pen again - does it work better than it did before?

+ Next, let's make your pen draw whenever the mouse has been clicked. Add this code to your pen sprite:

	```blocks
		when flag clicked
		forever
		  go to [mouse pointer v]
		  if <mouse down?> then
		    pen down
		  else
		    pen up
		  end
		end
	```

	As well as using a `forever` {.blockcontrol} loop to make the pen follow the mouse, you've now also used an `if` {.blockcontrol} statement to draw on the stage if the mouse button is being held down.

+ Test your code again. This time, move the pen around the stage and hold down the mouse button. Can you draw with your pen?

	![screenshot](paint-draw.png)

+ There's one more problem with the pen - you can draw anywhere on the stage, including the bit below the drawing surface!

	![screenshot](paint-draw-problem.png)

	To fix this, you have to tell the pen only to draw if the mouse is clicked _and_ if the y-position of the mouse is greater than -110 (`mouse y`{.blocksensing}`> -110` {.blockoperators}). Change your pen's `if` {.blockcontrol} statement to look like this:

	```blocks
		when flag clicked
		forever
		  go to [mouse pointer v]
		  if < <mouse down?> and < (mouse y) > (-110) > > then
		    pen down
		  else
		    pen up
		  end
		end
	```

+ Test your project; you now shouldn't be able to draw below the drawing surface.

	![screenshot](paint-fixed.png)

## Save your project { .save }

# Step 2: Coloured pens { .activity }

Let's add different colour pens to your project, and allow the user to choose between them!

## Activity Checklist { .check }

+ First, let's add another green pen costume to your pen sprite. Click on your pen sprite, and click 'Upload costume from file' and select the 'green-pencil.png' image to add it to your sprite. Remember to set the centre of your new costume.

	![screenshot](paint-green-costume.png)

+ You also need to add two sprites, that will be used to select the colour of the pen. Click 'Upload sprite from file' to add both the 'blue-selector.png' and 'green-selector.png' images as separate sprites.

	Your stage should now look like this:

	![screenshot](paint-selectors.png)

+ When the green selector icon is clicked, you need to `broadcast` {.blockevents} a message to the pen sprite, telling it to change its costume and pen colour. To do this, firstly add this code to the green selector icon:

	```blocks
		when this sprite clicked
		broadcast [green v]
	```

	To create the `broadcast` {.blockevents} block, click the down arrow and select 'new message...'.

	![screenshot](paint-broadcast.png)

	You can then type 'green' to create your new message.

	![screenshot](paint-green-message.png)

+ You now need to tell your pen sprite what to do when it receives the message. Add this code to your pen sprite:

	```blocks
		when I receive [green v]
		switch costume to [green-pencil v]
		set pen color to [#00FF00]
	```

	To set the pen to colour to green, click the coloured box in the `set color` {.blockpen} block, and click on the green selector icon to choose green as your pen colour.

+ You can now do the same for the blue pen icon, adding this code to the blue selector sprite:

	```blocks
		when this sprite clicked
		broadcast [blue v]
	```

	...and adding this code to the pen sprite:

	```blocks
		when I receive [blue v]
		switch costume to [blue-pencil v]
		set pen color to [#0000FF]
	```

+ Finally, you need to tell your pen sprite what costume and pen colour to choose, as well as clearing the screen, when your project is started. Add this code to the beginning of the pen's `when flag clicked` {.blockevents} code (before the `forever` {.blockcontrol} loop):

	```blocks
		clear
		switch costume to [blue-pencil v]
		set pen color to [#0000FF]
	```

	If you prefer, you can start with a different colour pen!

+ Test out your project. Can you switch between blue and green pens?

	![screenshot](paint-pens-test.png)

## Save your project { .save }

# Step 3: Making mistakes { .activity }

Sometimes mistakes happen, so let's add a 'clear' button and an eraser to our project!

## Activity Checklist { .check }

+ As well as clearing the canvas when your project is started, let's add a button to clear the canvas as well. To do this, add a new sprite using the 'cancel-button.png' image in your 'Resources' folder.

	![screenshot](paint-clear.png)

+ Add code to this new cancel button to clear the canvas when it's clicked.

	```blocks
		when this sprite clicked
		clear
	```

	Notice that you don't need to send a message to clear the canvas, as any sprite can do it!

+ You can also create an eraser. To do this, add the 'eraser.png' image as a new costume to your pen sprite (remember to set the costume centre) _and_ as a new selector sprite.

	![screenshot](paint-eraser.png)

+ You can then add code to the eraser selector sprite, to tell the pen to switch to an eraser.

	```blocks
		when this sprite clicked
		broadcast [eraser v]
	```

+ When the pen receives this message, you can create an eraser by switching the pen costume to the eraser, and switching the pen colour to the same colour as the canvas!

	```blocks
		when I receive [eraser v]
		switch costume to [eraser v]
		set pen color to [#8d8d8d]
	```

+ Test your project, to see if you can clear and erase on the canvas.

	![screenshot](paint-erase-test.png)

# Step 4: Changing the pen width { .activity }

Let's allow the user to draw using a range of different pen sizes.

## Activity Checklist { .check }

+ First, add a new variable called 'width'. If you're not sure how to do this, the 'Balloons' project will help you.

+ Add this line _inside_ the `forever` {.blockcontrol} loop of your pen's code:

	```blocks
		set pen size to (width)
	```

	Your pen width will now repeatedly be set to the value of your 'width' variable.

+ You can change the number stored in this variable by right-clicking on your variable (on the stage) and clicking 'slider'.

	![screenshot](paint-slider.png)

	You can now drag the slider below the variable to change its value.

	![screenshot](paint-slider-change.png)

+ Test your project, and see if you can modify the pen width.

	![screenshot](paint-width-test.png)

	If you prefer, you can set the minimum and maximum value of 'width' that's allowed. To do this, right-click on your variable again and click 'set slider min and max'. Set the minimum and maximum values of your variable to something more sensible, like 1 and 20.

	![screenshot](paint-slider-max.png)

	Keep testing your 'width' variable until you're happy.

## Save your project { .save }

## Challenge: Shortcuts {.challenge}
Can you create keyboard shortcuts for your commands? For example:
+ b = Switch to blue pen
+ g = switch to green pen
+ e = switch to eraser
+ c = clear screen

You could even allow the user to change the pen width with the arrow keys!

 You'll find all of the images you need in your 'Resources' folder. Remember to add keyboard shortcuts for these new pens!

Can you use your pens to draw a picture?

![screenshot](paint-final.png)

## Save your project { .save }

path: /src/scratch/Term 1/Paint Box/Paint Box.md

filename: Paint Box.md