text:
### GoEd
Goed is a Terminal based code/text editor, somewhat inspired by Acme.

**CURRENT STATE**:
It's currently in **ALPHA** and has not been spread around much yet.

I use it as my day to day editor and it "works on my machine"(TM)
It has not been tested much beyond that yet, there are [many open bugs and TODO's](https://github.com/tcolar/goed/issues).

Early screenshot (6/2/2015):
![Screenshot](https://raw.github.com/tcolar/goed/master/screenshot.png)

Of course typically I have a much large window and resolution such as [this screenshot](https://raw.githubusercontent.com/tcolar/goed/master/screenshot_hd.png).

### Installation
Note: Might distribute binaries once stable.

Prerequities:
- Have Go(Golang) installed
- Setup a good monospace terminal font and size (ie: Deja Vu Sans Mono or Monaco, size 10 or so.)

```
# Have your GOPATH set properly
go get github.com/tcolar/goed/...
```

To run it:
```
export PATH=$PATH:$GOPATH/bin #(goed & goed_api must be in your $PATH)
goed <path(s)>

```

Quick start:
- Use right click or Ctrl+O to open a dir/file.
- Use CTRL+T to start a terminal view ($SHELL)

### Supported terminals
In theory it should work with any terminal, however the level of support for things
like mouse support or extended colors vary a lot, here is a short list of tested
setups so far:

Long story short is **use gnome-terminal on Linux, iTerm2 on OsX (with right click menu disabled)**.

Linux:
- Linux / GnomeTerminal : My usual setup, works great.
- Linux / Lxerminal : Works well but does not support mouse events above 256 columns.
- Linux / Konsole : Works well, seems mouse events are slightly offset ?
- Linux / Terminator : Works ok, but can't use right click for "open" action.

OSX (barely tested so far) :
- OSX / Iterm2 : Pretty good, **better if disabling right click context menu under "preferences ->  pointer"**.
- OSX / Term.app : **Don't bother ...**

### Keyboard / Mouse shortcuts

Eventually the plan is to make all the Keyboard and mouse events configurable,
but for now here they are:

| Action                                  | Linux             | Mac (iTerm2)  |
| --------------------------------------- | ----------------- | ------------- |
| Close view / window                     | LeftClick on 'x'  | same          |
|                                         | or CTRL+W         | same          |
| Copy line/selection text           (1)  | CTRL+C            | same          |
| Cut+Copy line/selection text            | CTRL+X            | same          |
| Execute command bar                     | Enter             | same          |
| Navigate views                          | CTRL+Arrows       | SHIFT+Arrrows |
| Open Terminal view                      | CTRL+T            | same          |
| Open path (in New view)                 | RightClick        | same          |
|                                         | or CTRL+O         | same          |
| Open path (in current view)             | ALT+O             | N/A - TBD     |
| Paste text                              | CTRL+V            | same          |
| Quit Goed                               | CTRL+Q            | same          |
| Redo                                    | CTRL+Y            | same          |
| Reload view (not saving changes)        | CTRL+R            | same          |
| Resize / Move view & columns       (2)  | LeftClick top left| same          |
| Save view (to file)                     | CTRL+S            | same          |
| Select all                              | CTRL+A            | same          |
| Select word                             | Dbl LeftClick     | same          |
| Swap views                         (4)  | Dbl LC top left   | same          |
| Undo                                    | CTRL+Z            | same          |
| Text selection                     (3)  | Mouse drag        | same          |
|                                         | or SHIFT+move     | N/A           |
| Toogle command bar                      | ESC               | same          |

  - (1) : In terminal mode, copies if there is a selection, otherwise pass CTRL+C
  - (2) : You click the top left corner of a view (checkmark icon) to initiate the move, then click again where you want to drop it.
  - (3) : Can use Shift + [Arrows, PgUp, PgDown, Home, End].
  - (4) : Double click the top left corner of the view (checkmark icon) to switch that view with the previous current view.

### Terminal

Start a new Terminal with CTRL+T, it will be started in the same path as the current view.

The terminal implements basic vt100 support, enough for things such as top and
interactive git to work.

Note that while in a terminal a limited number of global shortcuts are enabled.

### Terminal actions

The Terminal provides a few builtin shortcuts, such as:
  - `sz` : Set the shell tty rows/cols to match the current goed view size.
  - `o <path>` : To open a given path/location in goed (or just right click it)
  - `s [-i] <pattern> [path]` : Search text (grep -rn[i] <pattern> [path])
  - `f <pattern> [path]` : Find files (find <path> -name *pattern*)

See [res/default/actions](res/default/actions) for more info.

You may create your own actions in ~/.goed/ations/
See [res/Readme.md](res/Readme.md).

### Command bar
The command bar is at the top of the screen. you can toggle it by clicking it or
using the <ESC> key.

Note: The command bar will likely go away in favor of terminal actions or be replaced
by something more useful such as sam like commands.

Currently it supports a few things:
  - `o <path>` : Opens a file or directory.
  - `: <linenumber>` : Goes to the secified line.
  - `/ <pattern>` : Search pattern (grep)
  Anything else will just be executed (via shell) in a new view.

### Configuration
The config file can be edited at ~/.goed/config.toml (The original is under ~/.goed/default/)

You may create custom themes under ~/.goed/themes/ (originals under ~/.goed/default/themes/)

You may create/override actions under ~/.goed/actions/ .

### Reporting issues
Report in github, try not to create duplicates.

If possible try to provide the most recent log found in ~/.goed/log/

### Contributing
- Reporting issues is welcome.
- PR's are even better.
- For new functionality a quick discussion first might be best.

repository: bestwpw/goed

repo_name: bestwpw/goed


text:
# Configuration

This Twig theme aims to simplify the implementation of the [AMP][1] pages in your websites.
If your are familiar with AMP, you've already found out that its markup and its design decisions are very closed. So,
exploiting the Twig potential, this theme exposes a robust API to interact with AMP environment.

To make work the theme, you have to add the Twig path to the directory that the library is.

In the Symfony context:
```yaml
# config/packages/twig.yaml         if you're using the Symfony Flex
# app/config/config.yaml            if you're using the Symfony Standard

twig:
    paths:
        '%kernel.root_dir%/../templates': ~
        '%kernel.project_dir%/vendor/benatespina/amp-twig-theme/templates': AMP
```

In the standalone context:
```php
<?php

$rootProjectDir = '/path/to/project/dir';

require_once __DIR__ . $rootProjectDir . '/vendor/autoload.php';

$loader = new \Twig_Loader_Filesystem();

$loader->addPath(__DIR__ . $rootProjectDir . '/vendor/benatespina/amp-twig-theme/templates', 'AMP');
```

And that's all, the library is ready to use!

- For more information about the use of this library check the "[Getting Started](getting_started.md)" chapter.
- Back to the [index](index.md).

[1]: https://www.ampproject.org/

license: MIT

repository: elbakerino/AMPTwigTheme

branch_name: refs/heads/master

extension: md

gha_license_id: MIT

license_type: permissive

repo_name: elbakerino/AMPTwigTheme


text:
+++
title = "The 22nd International ICT Innovative Services Awards IC1 - Semifinals"
date = 2017-11-04T09:00:00+08:00  # Schedule page publish date.
draft = false

# Talk start and end times.
#   End time can optionally be hidden by prefixing the line with `#`.
time_start = 2017-11-04T09:00:00+08:00
time_end = 2017-11-04T17:00:00+08:00

# Abstract and optional shortened version.
# abstract = "HERO是一個以群眾外包為基礎結合物聯網，透過人手一台的智慧型手機內建的三軸感應器（G-sensor）、GPS作為地震感測器的災變防範APP。以智慧型手機取代傳統地震感測站，使成本大大的降低，也因為手機同時兼具地震測站（發送端）和預警（接收端）功能，預警速度更快，更具有實用價值。"
abstract = "The new version of “H.E.R.O.” is based on the prototype we have built in the previous project and also with the new business model we have created. New epicenter converging algorithm and also new user interface is adapted to this new version."
# abstract_short = "結合物聯網與群眾共創的概念，藉由大眾手機內建的三軸感應器及GPS來佈建廣及全台的地震偵測網"
abstract_short = "We developed a new version of “H.E.R.O.” based on the prototype we have built in the previous project and also with the new business model we have created."

image_preview = "ict.jpg"

# Name of event and optional event URL.
event = "The 22nd International ICT Innovative Services Awards IC1"
event_url = "//innoserve.tca.org.tw/"

# Location of event.
location = "Taipei, Taiwan"

# Is this a selected talk? (true/false)
selected = false

# Projects (optional).
#   Associate this talk with one or more of your projects.
#   Simply enter the filename (excluding '.md') of your project file in `content/project/`.
#   E.g. `projects = ["deep-learning"]` references `content/project/deep-learning.md`.
projects = []

# Tags (optional).
#   Set `tags = []` for no tags, or use the form `tags = ["A Tag", "Another Tag"]` for one or more tags.
tags = []

# Links (optional).
url_pdf = "//drive.google.com/open?id=1LmCDoCNXom-vx4-I1POThp-aYznQZRor"
url_slides = "//drive.google.com/open?id=1Ffu11etQlZvWn6IF9zABXvwGPJOai8H9"
url_video = ""
url_code = ""

# Does the content use math formatting?
math = false

# Does the content use source code highlighting?
highlight = true

# Featured image
# Place your image in the `static/img/` folder and reference its filename below, e.g. `image = "example.jpg"`.
[header]
image = "ict2.jpg"
caption = ""

+++


text:
# Code Style

Unfortunately there is no official Code Style Guide by the Go team, although there is certainly a solid convention on code style that is enforced by `go fmt` and a few other tools.

Two resources that will help you to start writing Go in style include:

1. [Effective Go](https://golang.org/doc/effective_go.html)
2. [Go Wiki](https://github.com/golang/go/wiki/CodeReviewComments)

repository: hellofresh/go-readinglist

repo_name: hellofresh/go-readinglist


text:
# Triangle Tracker C#
#### <IP_ADDRESS>, for Fidgetech
#### Date:8/3/2020  by:_**David Boedigheimer**_
### Description
The user enters in three numbers and then the program tells them whether or not the three numbers create a certain type of triangle. This program was created with C#.
### BDD Process
1. User Inputs 3 numbers
      * **Input**: "2", "4", "3"
      * **Output**: 2, 4, 3
2. If three sides match, Return "Equilateral"
      * **Input**: "8", "8", "8"
      * **Output**: "Your triangle is a Equilateral triangle"
3. If two sides match, Return "Isosceles"
      * **Input**: "4", "4", "7"
      * **Output**: "Your triangle is a Isosceles triangle"
4. If no sides are the same, Return "Scalene"
      * **Input**: "2", "4", "3"
      * **Output**: "Your triangle is a Scalene triangle"
5. If one side is longer that the other 2 combined, it is not a triangle.
      * **Input**: "4" "3" "15"
      * **Output**: "This is not a triangle. Seriously, what is this?"
### Setup
* Click on clone or download
* Copy link to clipboard
* Open your preferred terminal
* Navigate to `$cd Desktop`
* Create a folder to house the copy: `$mkdir "Copy"`
* Paste the link, (this is using github): `$git clone "Link"`
* Navigate to the TriangleTrackerTests folder
* Run `dotnet restore` in the terminal
* Navigate back to the main folder
* Run `dotnet start` and enjoy.
### Contact
Contact me if you have any concerns or questions at<EMAIL_ADDRESS>### Known bugs
There are no know bugs in this program.
### License
This program is lisensed under the MIT license.
Copyright (c) 2020 _**David Boedigheimer**_

repository: CommaderDavid/Triangle-Tracker-C

repo_name: CommaderDavid/Triangle-Tracker-C


text:
---
title: Introduction
weight: 1
icon: "<b>1. </b>"
---
# Introduction

*HyperMake* is a _make-like_ build tool builds projects inside Docker Containers
which have the complete toolchain packaged,
thus no pre-requisites need to be installed on the host.

### What does this mean?

- The project can always be built consistently on any hosts (Windows/Mac/Linux)
  running Docker;
- Anyone is able to build the project instantly and successfully,
  no worry about build environment,
  required software, libraries, version conflicts;

### For example

![](https://raw.githubusercontent.com/evo-cloud/hmake/master/site/gh-pages/static/images/arm-hello.gif)

repository: linadesteem/hmake

gha_language: Go

repo_name: linadesteem/hmake


text:
# Bot Template for Community
This repository contains a bot template to facilitate community adoption. You can find additional [SDK V4](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples) in the BotBuilder-Samples repo.

## Contributing

repository: juscelior/bot-template-community

gha_language: C#

repo_name: juscelior/bot-template-community


text:
# JSBerry Roadmap

***This is a living document, it describes what features we should implement in priority.***

This document could be influenced by the community feedback, security issues, stability, future needs, etc.

### alpha

**Note:** This version will not be ready for production use. However, we will publish it to allow the community to test and contribute it and give us feedback.

<EMAIL_ADDRESS>* ~~Create Modules/Plugin manager, load balancer, logger.~~
* ~~Mediator with ACTIONS.~~
* ~~ROUTER with routes and middlewares support.~~
* ~~Add "express" REST plugin.~~
* ~~Add "mongoose" plugin.~~
* ~~vulnerabilities checkers: "nsp" and "snyk".~~
* ~~Update middlewares, add layers.~~
* ~~Add "koa" REST plugin.~~
* ~~Add "twillio" sms plugin.~~
* ~~v8 debug inspector.~~

<EMAIL_ADDRESS>* ~~Add "sendmail" plugin, connect to errors~~.
* ~~Add "graphql" plugin~~.
* Add "restify" REST plugin.
* Add "websockets" plugin.
* Remove default logger, add "pino" logger plugin.
* Error handler module.
* Authorization middleware.
* Validation middleware.
* Permission middleware.
* Add "sequelize" plugin.
* Add "nginx" and "docker" config.

<EMAIL_ADDRESS>(Main planned changes in future)`
* Add Sheduler to core.
* Add Registry to core.
* Add Cache plugin (Redis).

repository: ximet/jsberry

repo_name: ximet/jsberry


text:
# Circuits

NetBox is ideal for managing your network's transit and peering providers and circuits. It provides all the flexibility needed to model physical circuits in both data center and enterprise environments, and allows for "connecting" circuits directly to device interfaces via cables.

```mermaid
flowchart TD
    ASN --> Provider
    Provider --> ProviderNetwork & ProviderAccount & Circuit
    ProviderAccount --> Circuit
    CircuitType --> Circuit

click ASN "../../models/circuits/asn/"
click Circuit "../../models/circuits/circuit/"
click CircuitType "../../models/circuits/circuittype/"
click Provider "../../models/circuits/provider/"
click ProviderAccount "../../models/circuits/provideraccount/"
click ProviderNetwork "../../models/circuits/providernetwork/"
```

## Providers

A provider is any organization which provides Internet or private connectivity. Typically, these are large carriers, however they might also include regional providers or even internal services. Each provider can be assigned account and contact details, and may have one or more AS numbers assigned to it.

Sometimes you'll need to model provider networks into which you don't have full visibility; these are typically represented on topology diagrams with cloud icons. NetBox facilitates this through its provider network model: A provider network represents a "black box" network to which your circuits can connect. A common example is a provider MPLS network connecting multiple sites.

## Circuits

A circuit is a physical connection between two points, which is installed and maintained by an external provider. For example, an Internet connection delivered as a fiber optic cable would be modeled as a circuit in NetBox.

Each circuit is associated with a provider and assigned a circuit ID, which must be unique to that provider. A circuit is also assigned a user-defined type, operational status, and various other operating characteristics. Provider accounts can also be employed to further categorize circuits belonging to a common provider: These may represent different business units or technologies.

Each circuit may have up to two terminations (A and Z) defined. Each termination can be associated with a particular site or provider network. In the case of the former, a cable can be connected between the circuit termination and a device component to map its physical connectivity.

!!! warning "Physical vs. Virtual Circuits"
    The circuit model in NetBox represents **physical** connections. Don't confuse these with _virtual_ circuits which may be offered by providers overlaid on physical infrastructure. (For example, a VLAN-tagged subinterface would be a virtual circuit.) A good rule of thumb: If you can't point to it, it's not a physical circuit.

repository: netbox-community/netbox

branch_name: refs/heads/develop

gha_language: Python

repo_name: netbox-community/netbox


text:
---
title: Reviewing my Netlify Analytics
description: Thanks to Netlify Analytics I know to focus on writing how-to articles, but it has less data than I hoped
tags:
    - Meta
    - Netlify
pubDate: 2023-03-08T06:53-0400
---

Thanks to Netlify Analytics I know to focus on writing how-to articles, but it has less data than I hoped.

**Some context:** Netlify provides analytics information for $9 per month per site. They offer data from server requests including page views, unique visitors, top locations, and sources.

- [The data varies greatly](https://blog.jim-nielsen.com/2020/google-vs-netlify-analytics/) from client-side options like Google Analytics

**The numbers:**

- My site received **38,000** page views from **13,000** unique visitors in the last 30 days
- The top location was the **United States**, followed distantly by Germany, France, and China
- The most popular page was a tool for [looking up words by consonant-vowel patterns](https://www.seanmcp.com/articles/english-words-by-consonant-vowel-pattern/)
- The most popular content were **how-to articles**

**Trade-offs:** Netlify Analytics was easy to set up with an existing project — just one click after adding payment information. But it lacks comprehensive data for informed decision making.

- I want to know how all of my pages are performing, but Netlify’s dashboard limits you to 15 results.
- The inclusion of bot traffic add uncertainty to the numbers.

**Takeaway:** People are visiting this site for guides on completing a particular task. These are broken down into two categories: tutorials and debugging.

- In order to create value for my readers, I’m going to focus this area
- I expect more for $9/month and probably won’t continue the subscription

**Read more:**

- [https://www.netlify.com/products/analytics/](https://www.netlify.com/products/analytics/)
- [https://blog.jim-nielsen.com/2020/google-vs-netlify-analytics/](https://blog.jim-nielsen.com/2020/google-vs-netlify-analytics/)
- [https://css-tricks.com/comparing-data-in-google-and-netlify-analytics/](https://css-tricks.com/comparing-data-in-google-and-netlify-analytics/)
- [https://answers.netlify.com/t/over-100x-more-views-in-netlify-analytics-than-google-analytics/15403](https://answers.netlify.com/t/over-100x-more-views-in-netlify-analytics-than-google-analytics/15403)
- [https://codeboosh.com/is-netlify-analytics-worth-it/](https://codeboosh.com/is-netlify-analytics-worth-it/)

gha_language: Astro


text:
# Client-side Samples for Order, Position and Balance events

This document describes how a client application can subscribe to Saxo Bank's Event Notification Service (ENS).

More on ENS: <https://www.developer.saxo/openapi/learn/event-notification>

Interactive demo: <https://saxobank.github.io/openapi-samples-js/websockets/order-events-monitoring/>

repository: SaxoBank/openapi-samples-js

branch_name: refs/heads/main

gha_language: JavaScript

repo_name: SaxoBank/openapi-samples-js


text:
---
layout: post
title: "Playing with Seesmic"
date: 2007-11-05 11:16
comments: true
categories: Web 2.0
author: Oliver Thylmann
---

If you don't know yet what [Seesmic](http://seesmic.com) from [Loic](http://loiclemeur.com) is about, check out his presentation at VON. (I am actually mentioned twice as oliver from germany and the greetings from germany at the end :))

<object width="425" height="366"><param name="movie" value="http://www.youtube.com/v/W1tFCQQrIh8&rel=1&border=0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/W1tFCQQrIh8&rel=1&border=0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="366"></embed></object>

In short, Loic is trying to build a quasi Twitter for Video, but kind of making it into a real new age TV Platform. Next to letting everyone post a video, see those by their friends, there will be shows automatically generated by videos through voting mechanisms in channels. These might be edited summaries but I am still not shure how these will work in an automated manner. Next he is trying to build small Seesmic Cafes all over the world in major cities where people can come, hang out, and have some chats in front of the camera.

I've been playing with the platform for a bit at the moment and I really do like it. The biggest problem is that I need more filters to get the content from my friends only, because otherwise videos become too much. But the fun thing is that this is a wonderful move on the mobile side. Just imagine getting the videos via the podcast client on your Nokia N95, and allowing you to easily answer from the N95. Now imagine something big happens somewhere. As I said ages ago, [press is not longer going to be the first on the scene](http://blog.thylmann.net/2006/01/12/press-no-longer-first-on-the-scene/), and with something like Seesmic, with a good Atom interface to post video, and something that pulls together channels based on user feedback, I can see the videos run on CNN now in my head.

extension: markdown


text:
# VdmLibraryFtpTransportBundle

**Not maintained anymore : use
[VdmLibraryFlysystemTransportBundle](https://github.com/3slab/VdmLibraryFlysystemTransportBundle) instead with
[VdmLibraryBundle v3.x](https://github.com/3slab/VdmLibraryBundle)**

This source can collect data from a ftp server.

## Configuration reference

```
framework:
    messenger:
        transports:
            consumer:
                dsn: "sftp://user:password@sftp.fr:2222"
                retry_strategy:
                    max_retries: 0
                options:
                    monitoring:
                        enabled: true
                    mode: move
                    ftp_options:
                        dirpath: path/to/your/files/
                        storage: path/to/your/storage/
```

Configuration | Description
--- | ---
dsn | the url you want to collect (needs to start by ftp or sftp)
retry_strategy.max_retries | needs to be 0 because ftp transport does not support this feature
options.mode | two mode available (move|delete), `move` to deplace the file in other folder when it is treated, `delete` to remove it.
options.ftp_options | options to manage your ftp actions
options.ftp_options.dirpath | path to your directory
options.ftp_options.storage | If you choose option `move` you have to configure this path.
options.monitoring.enabled | if true, hook up in the vdm library bundle monitoring system to send information about the FTP response

## Custom ftp executor

A custom ftp executor allows you to customize how you call the ftp server. It's necessary if you have differents action to make on files.

Just create a class in your project that extends `Vdm\Bundle\LibraryFtpTransportBundle\Executor\AbstractFtpExecutor`. It will
automatically replace the default executor.

**If you have 2 custom executor. Only a single one will be used, the second is ignored.**

```
namespace App\FtpExecutor;

use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Envelope;
use Vdm\Bundle\LibraryBundle\Model\Message;
use Vdm\Bundle\LibraryFtpTransportBundle\Executor\AbstractFtpExecutor;
use Vdm\Bundle\LibraryBundle\Stamp\StopAfterHandleStamp;

class CustomFtpExecutor implements AbstractFtpExecutor
{
    /**
     * @var LoggerInterface
    */
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        parent::__construct();
        $this->logger = $logger;
    }

    public function execute(array $files): iterable
    {
        $files = array_filter($files, function($file) {
            return (isset($file['type']) && $file['type'] === 'file');
        });

        foreach ($files as $key => $file) {
            $file = $this->ftpClient->get($file);
            $message = new Message($file);

            yield $this->getEnvelope($files, $key, $message);
        }

        yield new Envelope(new Message(""), [new StopAfterHandleStamp()]);
    }

    private function getEnvelope(array $files, int $key, Message $message): Envelope
    {
        $stamps = [];

        // Put the stop stamp on the last file
        if (array_key_last($files) === $key) {
            $stamps = [new StopAfterHandleStamp()];
        }

        return new Envelope($message, $stamps);
    }
}
```

There are 2 important things your custom executor needs to do :

* `yield` a new envelope with a VDM Message instance
* Add a `StopAfterHandleStamp` stamp to the yielded envelope if you want to stop after handling the last file (if not,
  the messenger worker loop over and will execute it once again).

*Note : thanks to the yield system, you can implement a loop in your execute function and return items once at a time*

*Note : you can keep state in your custom executor so if it is executed again, adapt your ftp call*

## Monitoring

If you enable monitoring, it will track the following metrics :

* Size of the Ftp file body
* Counter the ftp error

gha_language: PHP


text:
## 文章索引
1、 Dropbox通过自建基础技术设施在两年内省了差不多7500万美元

2、 文章： 不，你可能不需要区块链

3、 文章： 深入浅出Java 10的实验性JIT编译器Graal

4、 视频演讲： 大规模分布式系统架构下调测能力构建之道

5、 Talk is cheap, show me the architecture

6、 在Docker Compose上使用GPU运行TensorFlow

7、 文章： electron工具包介绍:用于构建和启动Electron应用程序的Electron应用

8、 物联网技术周报第 132 期: Arduino 与 Mindwave 传感器 制作脑控无人机

9、 谷歌开源针对iOS的可访问性测试框架

10、 VueConf.US大会上与Gregg Pollack的问答

11、 Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them

12、 Becoming A UX Leader

1、Dropbox通过自建基础技术设施在两年内省了差不多7500万美元

TOM KRAZIT
[http://www.infoq.com/cn/news/2018/04/Dropbox-7500?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/Dropbox-7500?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

Dropbox公司在2018年2月23日的S-1公告中称，在决定搭建自己的基础设施并减少对Amazon Web Services的依赖之后，它在两年内减少了7460万美元的运维成本。
 By TOM KRAZIT  Translated by 张健欣
---------------

2、文章： 不，你可能不需要区块链

Ashton Kemerling
[http://www.infoq.com/cn/articles/no-you-probably-dont-need-a-blockchain?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/articles/no-you-probably-dont-need-a-blockchain?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

就算不相信买点比特币就能让你发大财然后迈向人生巅峰，你肯定听说过到处都有人说，比特币并不是未来，真正是未来的应该是区块链！无数人笃信这个观点。但本文作者Ashton Kemerling认为有关区块链的一切都是在做铺垫。区块链不能代表未来，这技术在未来也不会有大范围应用，至少目前还没有相关迹象。
 By Ashton Kemerling  Translated by 大愚若智
---------------

3、文章： 深入浅出Java 10的实验性JIT编译器Graal

郑雨迪
[http://www.infoq.com/cn/articles/java-10-jit-compiler-graal?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/articles/java-10-jit-compiler-graal?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

Graal是一个以Java为主要编程语言，面向Java bytecode的编译器。与用C++实现的C1及C2相比，它的模块化更加明显，也更加容易维护。Graal既可以作为动态编译器，在运行时编译热点方法；亦可以作为静态编译器，实现AOT编译。在Java 10中，Graal作为试验性JIT compiler一同发布（JEP 317）。这篇文章将介绍Graal在动态编译上的应用。
 By 郑雨迪
---------------

4、视频演讲： 大规模分布式系统架构下调测能力构建之道

李鑫
[http://www.infoq.com/cn/presentations/construction-of-down-regulation-of-measurement-capability?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/presentations/construction-of-down-regulation-of-measurement-capability?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

如何既享受分布式服务带给我们的好处，又享有单体应用下调测的便利性？我们需要构建一套调测框架，通过这套框架解决分布式服务所带来的服务及数据的依赖问题，从而通过一种轻量化的模式构建起单机调测能力，解决开发人员本地调测需求、提升研发效率。讲师将通过自身的经验来详细展示如何有机结合分布式服务 MOCK（微服务、MQ、Cache、File、DBProxy）、Stub 数据制作及管理、服务直连调测、契约测试保障等能力来构建一套应对研发各阶段开发需求的调测框架及方法论。

 By 李鑫
---------------

5、Talk is cheap, show me the architecture

David
[http://www.infoq.com/cn/news/2018/04/talk-is-cheap?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/talk-is-cheap?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

就像当年在法拉第表演圆盘发电机被质疑时，法拉第答道:“一个刚刚出生的婴儿有什么作用呢?”
 By David
---------------

6、在Docker Compose上使用GPU运行TensorFlow

Beining
[http://www.infoq.com/cn/news/2018/04/Docker-Compose-TensorFlow-GPU?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/Docker-Compose-TensorFlow-GPU?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

Deep Systems将在Docker Compose上使用GPU运行TensorFlow的经验进行了分享。
 By Beining
---------------

7、文章： electron工具包介绍:用于构建和启动Electron应用程序的Electron应用

Philipp Langhans
[http://www.infoq.com/cn/articles/introducing-electron-toolkit-the-electron-app?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/articles/introducing-electron-toolkit-the-electron-app?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

electron工具包是一个用于启动Electron应用的轻量级的、小型的、非常强大的开源应用程序。electron工具包可以在你现有的Electron项目中从npm安装和启动。它可以帮助你构建、发布你的应用，甚至生成完整的网站，其丰富的功能特性可以帮你节约大量的时间。
 By Philipp Langhans  Translated by 孙浩
---------------

8、物联网技术周报第 132 期: Arduino 与 Mindwave 传感器 制作脑控无人机

黄峰达
[http://www.infoq.com/cn/news/2018/04/iot-weekly-132?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/iot-weekly-132?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

Arduino 与 Mindwave 传感器制作脑控无人机；Node-RED 与 Raspberry Pi 构建物联网 MineCraft 城堡；物联网设备六种攻击面及其应对；微软将为 IoT 投入 50 亿美元，物联网大战一触即发；意法半导体 STM32 软件包，让简单的物联网产品具有亚马逊的 Alexa 技术；阿里巴巴重兵布局“云芯片” YoC；MIT 研发“读心机”：你不张嘴就知道想说什么。
 By 黄峰达
---------------

9、谷歌开源针对iOS的可访问性测试框架

Sergio De Simone
[http://www.infoq.com/cn/news/2018/04/accessibility-tests-ios-gtxilib?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/accessibility-tests-ios-gtxilib?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

谷歌GTXiLib是针对iOS的可访问性自动化测试框架，现在它已经基于Apache许可证开源。GTXiLib是使用Objective-C编写的，并且能够与Xcode的单元测试基础设施进行集成。
 By Sergio De Simone  Translated by 张卫滨
---------------

10、VueConf.US大会上与Gregg Pollack的问答

Kevin Ball
[http://www.infoq.com/cn/news/2018/04/q-a-with-gregg-pollack-on-vue-js?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global](http://www.infoq.com/cn/news/2018/04/q-a-with-gregg-pollack-on-vue-js?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global)

InfoQ择机采访了Pollack，采访内容涉及：Vue.js的内部机制、他对Vue.js社区的看法、学习Vue的最好方法，以及导致Vue成功的更多原因。
 By Kevin Ball  Translated by 盖磊
---------------

11、Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them

Lou Franco
[https://www.smashingmagazine.com/2018/04/sirikit-intents-app-guide/](https://www.smashingmagazine.com/2018/04/sirikit-intents-app-guide/)

              <meta charset="utf-8">
              <link rel="canonical" href="https://www.smashingmagazine.com/2018/04/sirikit-intents-app-guide/" />
              <title>Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them</title>

Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them

                    <address>Lou Franco</address>

                  <time datetime="2018-04-11T17:00:44+02:00" class="op-published">2018-04-11T17:00:44+02:00</time>
                  <time datetime="2018-04-11T22:10:30+00:00" class="op-modified">2018-04-11T22:10:30+00:00</time>

Since iOS 5, Siri has helped iPhone users send messages, set reminders and look up restaurants with Apple’s apps. Starting in iOS 10, we have been able to use Siri in some of our own apps as well.

In order to use this functionality, your app must fit within Apple’s predefined Siri “domains and intents.” In this article, we’ll learn about what those are and see whether our apps can use them. We’ll take a simple app that is a to-do list manager and learn how to add Siri support. We’ll also go through the Apple developer website’s guidelines on configuration and Swift code for a new type of extension that was introduced with SiriKit: the Intents extension.

When you get to the coding part of this article, you will need Xcode (at least version 9.x), and it would be good if you are familiar with iOS development in Swift because we’re going to add Siri to a small working app. We’ll go through the steps of setting up a extension on Apple’s developer website and of adding the Siri extension code to the app.

“Hey Siri, Why Do I Need You?”

Sometimes I use my phone while on my couch, with both hands free, and I can give the screen my full attention. Maybe I’ll text my sister to plan our mom’s birthday or reply to a question in Trello. I can see the app. I can tap the screen. I can type.

But I might be walking around my town, listening to a podcast, when a text comes in on my watch. My phone is in my pocket, and I can’t easily answer while walking.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the , of course.

        Explore features →

With Siri, I can hold down my headphone’s control button and say, “Text my sister that I’ll be there by two o’clock.” Siri is great when you are on the go and can’t give full attention to your phone or when the interaction is minor, but it requires several taps and a bunch of typing.

This is fine if I want to use Apple apps for these interactions. But some categories of apps, like messaging, have very popular alternatives. Other activities, such as booking a ride or reserving a table in a restaurant, are not even possible with Apple’s built-in apps but are perfect for Siri.

Apple’s Approach To Voice Assistants

To enable Siri in third-party apps, Apple had to decide on a mechanism to take the sound from the user’s voice and somehow get it to the app in a way that it could fulfill the request. To make this possible, Apple requires the user to mention the app’s name in the request, but they had several options of what to do with the rest of the request.

It could have sent a sound file to the app.

The benefit of this approach is that the app could try to handle literally any request the user might have for it. Amazon or Google might have liked this approach because they already have sophisticated voice-recognition services. But most apps would not be able to handle this very easily.

It could have turned the speech into text and sent that.

Because many apps don’t have sophisticated natural-language implementations, the user would usually have to stick to very particular phrases, and non-English support would be up to the app developer to implement.

It could have asked you to provide a list of phrases that you understand.

This mechanism is closer to what Amazon does with Alexa (in its “skills” framework), and it enables far more uses of Alexa than SiriKit can currently handle. In an Alexa skill, you provide phrases with placeholder variables that Alexa will fill in for you. For example, “Alexa, remind me at $TIME$ to $REMINDER$” — Alexa will run this phrase against what the user has said and tell you the values for TIME and REMINDER. As with the previous mechanism, the developer needs to do all of the translation, and there isn’t a lot of flexibility if the user says something slightly different.

It could define a list of requests with parameters and send the app a structured request.

This is actually what Apple does, and the benefit is that it can support a variety of languages, and it does all of the work to try to understand all of the ways a user might phrase a request. The big downside is that you can only implement handlers for requests that Apple defines. This is great if you have, for example, a messaging app, but if you have a music-streaming service or a podcast player, you have no way to use SiriKit right now.

Similarly, there are three ways for apps to talk back to the user: with sound, with text that gets converted, or by expressing the kind of thing you want to say and letting the system figure out the exact way to express it. The last solution (which is what Apple does) puts the burden of translation on Apple, but it gives you limited ways to use your own words to describe things.

The kinds of requests you can handle are defined in SiriKit’s domains and intents. An intent is a type of request that a user might make, like texting a contact or finding a photo. Each intent has a list of parameters — for example, texting requires a contact and a message.

A domain is just a group of related intents. Reading a text and sending a text are both in the messaging domain. Booking a ride and getting a location are in the ride-booking domain. There are domains for making VoIP calls, starting workouts, searching for photos and a few more things. SiriKit’s documentation contains a .

A common criticism of Siri is that it seems unable to handle requests as well as Google and Alexa, and that the third-party voice ecosystem enabled by Apple’s competitors is richer.

I agree with those criticisms.  Even if your app does fit, you can’t control all of the words Siri says or understands; so, if you have a particular way of talking about things in your app, you can’t always teach that to Siri.

The hope of iOS developers is both that Apple will greatly expand its list of intents and that its natural language processing becomes much better. If it does that, then we will have a voice assistant that works without developers having to do translation or understand all of the ways of saying the same thing. And implementing support for structured requests is actually fairly simple to do — a lot easier than building a natural language parser.

Another big benefit of the intents framework is that it is not limited to Siri and voice requests. Even now, the Maps app can generate an intents-based request of your app (for example, a restaurant reservation). It does this programmatically (not from voice or natural language). If Apple allowed apps to discover each other’s exposed intents, we’d have a much better way for apps to work together, (as opposed to ).

Finally, because an intent is a structured request with parameters, there is a simple way for an app to express that parameters are missing or that it needs help distinguishing between some options. Siri can then ask follow-up questions to resolve the parameters without the app needing to conduct the conversation.

The Ride-Booking Domain

To understand domains and intents, let’s look at the . This is the domain that you would use to ask Siri to get you a Lyft car.

Apple defines how to ask for a ride and how to get information about it, but there is actually no built-in Apple app that can actually handle this request. This is one of the few domains where a SiriKit-enabled app is required.

You can invoke one of the intents via voice or directly from Maps. Some of the intents for this domain are:

Request a ride

Use this one to book a ride. You’ll need to provide a pick-up and drop-off location, and the app might also need to know your party’s size and what kind of ride you want. A sample phrase might be, “Book me a ride with <appname>.”

Get the ride’s status

Use this intent to find out whether your request was received and to get information about the vehicle and driver, including their location. The Maps app uses this intent to show an updated image of the car as it is approaching you.

Cancel a ride

Use this to cancel a ride that you have booked.

For any of this intents, Siri might need to know more information. As you’ll see when we implement an intent handler, your Intents extension can tell Siri that a required parameter is missing, and Siri will prompt the user for it.

The fact that intents can be invoked programmatically by Maps shows how intents might enable inter-app communication in the future.

Note: You can get a , including ride-booking.

Adding Lists And Notes Domain Support To Your App

OK, now that we understand the basics of SiriKit, let’s look at how you would go about adding support for Siri in an app that involves a lot of configuration and a class for each intent you want to handle.

The rest of this article consists of the detailed steps to add Siri support to an app. There are five high-level things you need to do:

Prepare to add a new extension to the app by creating provisioning profiles with new entitlements for it on Apple’s developer website.

Configure your app (via its plist) to use the entitlements.

Use Xcode’s template to get started with some sample code.

Add the code to support your Siri intent.

Configure Siri’s vocabulary via plists.

Don’t worry: We’ll go through each of these, explaining extensions and entitlements along the way.

To focus on just the Siri parts, I’ve prepared a simple to-do list manager, List-o-Mat.

)

You can find the .

To create it, all I did was start with the Xcode Master-Detail app template and make both screens into a UITableView. I added a way to add and delete lists and items, and a way to check off items as done. All of the navigation is generated by the template.

To store the data, I used the Codable protocol, (), which turns structs into JSON and saves it in a text file in the documents folder.

I’ve deliberately kept the code very simple. If you have any experience with Swift and making view controllers, then you should have no problem with it.

Now we can go through the steps of adding SiriKit support. The high-level steps would be the same for any app and whichever domain and intents you plan to implement. We’ll mostly be dealing with Apple’s developer website, editing plists and writing a bit of Swift.

For List-o-Mat, we’ll focus on the , which is broadly applicable to things like note-taking apps and to-do lists.

In the lists and notes domain, we have the following intents that would make sense for our app.

Get a list of tasks.

Add a new task to a list.

Because the interactions with Siri actually happen outside of your app (maybe even when you app is not running), iOS uses an extension to implement this.

The Intents Extension

If you have not worked with extensions, you’ll need to know three main things:

An extension is a separate process. It is delivered inside of your app’s bundle, but it runs completely on its own, with its own sandbox.

Your app and extension can communicate with each other by being in the same app group. The easiest way is via the group’s shared sandbox folders (so, they can read and write to the same files if you put them there).

Extensions require their own app IDs, profiles and entitlements.

To add an extension to your app, start by logging into your  and going to the “Certificates, Identifiers, & Profiles” section.

Updating Your Apple Developer App Account Data

In our Apple developer account, the first thing we need to do is create an app group. Go to the “App Groups” section under “Identifiers” and add one.

)

It must start with group, followed by your usual reverse domain-based identifier. Because it has a prefix, you can use your app’s identifier for the rest.

Then, we need to update our app’s ID to use this group and to enable Siri:

Go to the “App IDs” section and click on your app’s ID;

Click the “Edit” button;

Enable app groups (if not enabled for another extension).

)

Then configure the app group by clicking the “Edit” button. Choose the app group from before.

)

Enable SiriKit.

)

Click “Done” to save it.

Now, we need to create a new app ID for our extension:

In the same “App IDs” section, add a new app ID. This will be your app’s identifier, with a suffix. Do not use just Intents as a suffix because this name will become your module’s name in Swift and would then conflict with the real Intents.

)

Enable this app ID for app groups as well (and set up the group as we did before).

Now, create a development provisioning profile for the Intents extension, and regenerate your app’s provisioning profile. Download and install them as you would normally do.

Now that our profiles are installed, we need to go to Xcode and update the app’s entitlements.

Updating Your App’s Entitlements In Xcode

Back in Xcode, choose your project’s name in the project navigator. Then, choose your app’s main target, and go to the “Capabilities” tab. In there, you will see a switch to turn on Siri support.

)

Further down the list, you can turn on app groups and configure it.

)

If you have set it up correctly, you’ll see this in your app’s .entitlements file:

)

Now, we are finally ready to add the Intents extension target to our project.

Adding The Intents Extension

We’re finally ready to add the extension. In Xcode, choose “File” → “New Target.” This sheet will pop up:

)

Choose “Intents Extension” and click the “Next” button. Fill out the following screen:

)

The product name needs to match whatever you made the suffix in the intents app ID on the Apple developer website.

We are choosing not to add an intents UI extension. This isn’t covered in this article, but you could add it later if you need one. Basically, it’s a way to put your own branding and display style into Siri’s visual results.

When you are done, Xcode will create an intents handler class that we can use as a starting part for our Siri implementation.

The Intents Handler: Resolve, Confirm And Handle

Xcode generated a new target that has a starting point for us.

The first thing you have to do is set up this new target to be in the same app group as the app. As before, go to the “Capabilities” tab of the target, and turn on app groups, and configure it with your group name. Remember, apps in the same group have a sandbox that they can use to share files with each other. We need this in order for Siri requests to get to our app.

List-o-Mat has a function that returns the group document folder. We should use it whenever we want to read or write to a shared file.

func documentsFolder() -> URL? {
    return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.app-o-mat.ListOMat")
}

For example, when we save the lists, we use this:

func save(lists: Lists) {
    guard let docsDir = documentsFolder() else {
        fatalError("no docs dir")
    }

    let url = docsDir.appendingPathComponent(fileName, isDirectory: false)

    // Encode lists as JSON and save to url
}

The Intents extension template created a file named IntentHandler.swift, with a class named IntentHandler. It also configured it to be the intents’ entry point in the extension’s plist.

The intent extension plist configures IntentHandler as the entry point

In this same plist, you will see a section to declare the intents we support. We’re going to start with the one that allows searching for lists, which is named INSearchForNotebookItemsIntent. Add it to the array under IntentsSupported.

)

Now, go to IntentHandler.swift and replace its contents with this code:

import Intents

class IntentHandler: INExtension {
    override func handler(for intent: INIntent) -> Any? {
        switch intent {
        case is INSearchForNotebookItemsIntent:
            return SearchItemsIntentHandler()
        default:
            return nil
        }
    }
}

The handler function is called to get an object to handle a specific intent. You can just implement all of the protocols in this class and return self, but we’ll put each intent in its own class to keep it better organized.

Because we intend to have a few different classes, let’s give them a common base class for code that we need to share between them:

class ListOMatIntentsHandler: NSObject {
}

The intents framework requires us to inherit from NSObject. We’ll fill in some methods later.

We start our search implementation with this:

class SearchItemsIntentHandler: ListOMatIntentsHandler,
                                                       INSearchForNotebookItemsIntentHandling {
}

To set an intent handler, we need to implement three basic steps

Resolve the parameters.

Make sure required parameters are given, and disambiguate any you don’t fully understand.

Confirm that the request is doable.

This is often optional, but even if you know that each parameter is good, you might still need access to an outside resource or have other requirements.

Handle the request.

Do the thing that is being requested.

INSearchForNotebookItemsIntent, the first intent we’ll implement, can be used as a task search. The kinds of requests we can handle with this are, “In List-o-Mat, show the grocery store list” or “In List-o-Mat, show the store list.”

Aside: “List-o-Mat” is actually a bad name for a SiriKit app because Siri has a hard time with hyphens in apps. Luckily, SiriKit allows us to have alternate names and to provide pronunciation. In the app’s Info.plist, add this section:

Add alternate app name's and pronunciation guides to the app plist

This allows the user to say “list oh mat” and for that to be understood as a single word (without hyphens). It doesn’t look ideal on the screen, but without it, Siri sometimes thinks “List” and “Mat” are separate words and gets very confused.

Resolve: Figuring Out The Parameters

For a search for notebook items, there are several parameters:

the item type (a task, a task list, or a note),

the title of the item,

the content of the item,

the completion status (whether the task is marked done or not),

the location it is associated with,

the date it is associated with.

We require only the first two, so we’ll need to write resolve functions for them. INSearchForNotebookItemsIntent has methods for us to implement.

Because we only care about showing task lists, we’ll hardcode that into the resolve for item type. In SearchItemsIntentHandler, add this:

func resolveItemType(for intent: INSearchForNotebookItemsIntent,
                         with completion: @escaping (INNotebookItemTypeResolutionResult) -> Void) {

    completion(.success(with: .taskList))
}

So, no matter what the user says, we’ll be searching for task lists. If we wanted to expand our search support, we’d let Siri try to figure this out from the original phrase and then just use completion(.needsValue()) if the item type was missing. Alternatively, we could try to guess from the title by seeing what matches it. In this case, we would complete with success when Siri knows what it is, and we would use completion(.notRequired()) when we are going to try multiple possibilities.

Title resolution is a little trickier. What we want is for Siri to use a list if it finds one with an exact match for what you said. If it’s unsure or if there is more than one possibility, then we want Siri to ask us for help in figuring it out. To do this, SiriKit provides a set of resolution enums that let us express what we want to happen next.

So, if you say “Grocery Store,” then Siri would have an exact match. But if you say “Store,” then Siri would present a menu of matching lists.

We’ll start with this function to give the basic structure:

func resolveTitle(for intent: INSearchForNotebookItemsIntent, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) {
    guard let title = intent.title else {
        completion(.needsValue())
        return
    }

    let possibleLists = getPossibleLists(for: title)
    completeResolveListName(with: possibleLists, for: title, with: completion)
}

We’ll implement getPossibleLists(for:) and completeResolveListName(with:for:with:) in the ListOMatIntentsHandler base class.

getPossibleLists(for:) needs to try to fuzzy match the title that Siri passes us with the actual list names.

public func getPossibleLists(for listName: INSpeakableString) -> [INSpeakableString] {
    var possibleLists = [INSpeakableString]()
    for l in loadLists() {
        if l.name.lowercased() == listName.spokenPhrase.lowercased() {
            return [INSpeakableString(spokenPhrase: l.name)]
        }
        if l.name.lowercased().contains(listName.spokenPhrase.lowercased()) || listName.spokenPhrase.lowercased() == "all" {
            possibleLists.append(INSpeakableString(spokenPhrase: l.name))
        }
    }
    return possibleLists
}

We loop through all of our lists. If we get an exact match, we’ll return it, and if not, we’ll return an array of possibilities. In this function, we’re simply checking to see whether the word the user said is contained in a list name (so, a pretty simple match). This lets “Grocery” match “Grocery Store.” A more advanced algorithm might try to match based on words that sound the same (for example, with the ),

completeResolveListName(with:for:with:) is responsible for deciding what to do with this list of possibilities.

public func completeResolveListName(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) {
    switch possibleLists.count {
    case 0:
        completion(.unsupported())
    case 1:
        if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() {
            completion(.success(with: possibleLists[0]))
        } else {
            completion(.confirmationRequired(with: possibleLists[0]))
        }
    default:
        completion(.disambiguation(with: possibleLists))
    }
}

If we got an exact match, we tell Siri that we succeeded. If we got one inexact match, we tell Siri to ask the user if we guessed it right.

If we got multiple matches, then we use completion(.disambiguation(with: possibleLists)) to tell Siri to show a list and let the user pick one.

Now that we know what the request is, we need to look at the whole thing and make sure we can handle it.

Confirm: Check All Of Your Dependencies

In this case, if we have resolved all of the parameters, we can always handle the request. Typical confirm() implementations might check the availability of external services or check authorization levels.

Because confirm() is optional, we could just do nothing, and Siri would assume we could handle any request with resolved parameters. To be explicit, we could use this:

func confirm(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) {
    completion(INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil))
}

This means we can handle anything.

Handle: Do It

The final step is to handle the request.

func handle(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) {
    guard
        let title = intent.title,
        let list = loadLists().filter({ $0.name.lowercased() == title.spokenPhrase.lowercased()}).first
    else {
        completion(INSearchForNotebookItemsIntentResponse(code: .failure, userActivity: nil))
        return
    }

    let response = INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil)
    response.tasks = list.items.map {
        return INTask(title: INSpeakableString(spokenPhrase: $0.name),
                      status: $0.done ? INTaskStatus.completed : INTaskStatus.notCompleted,
                      taskType: INTaskType.notCompletable,
                      spatialEventTrigger: nil,
                      temporalEventTrigger: nil,
                      createdDateComponents: nil,
                      modifiedDateComponents: nil,
                      identifier: "\(list.name)\t\($0.name)")
    }
    completion(response)
}

First, we find the list based on the title. At this point, resolveTitle has already made sure that we’ll get an exact match. But if there’s an issue, we can still return a failure.

When we have a failure, we have the option of passing a user activity. If your app uses  and has a way to handle this exact type of request, then Siri might try deferring to your app to try the request there. It will not do this when we are in a voice-only context (for example, you started with “Hey Siri”), and it doesn’t guarantee that it will do it in other cases, so don’t count on it.

This is now ready to test. Choose the intent extension in the target list in Xcode. But before you run it, edit the scheme.

Edit the scheme of the the intent to add a sample phrase for debugging.

That brings up a way to provide a query directly:

)

Notice, I am using “ListOMat” because of the hyphens issue mentioned above. Luckily, it’s pronounced the same as my app’s name, so it should not be much of an issue.

Back in the app, I made a “Grocery Store” list and a “Hardware Store” list. If I ask Siri for the “store” list, it will go through the disambiguation path, which looks like this:

)

If you say “Grocery Store,” then you’ll get an exact match, which goes right to the results.

Adding Items Via Siri

Now that we know the basic concepts of resolve, confirm and handle, we can quickly add an intent to add an item to a list.

First, add INAddTasksIntent to the extension’s plist:

)

Then, update our IntentHandler’s handle function.

override func handler(for intent: INIntent) -> Any? {
    switch intent {
    case is INSearchForNotebookItemsIntent:
        return SearchItemsIntentHandler()
    case is INAddTasksIntent:
        return AddItemsIntentHandler()
    default:
        return nil
    }
}

Add a stub for the new class:

class AddItemsIntentHandler: ListOMatIntentsHandler, INAddTasksIntentHandling {
}

Adding an item needs a similar resolve for searching, except with a target task list instead of a title.

func resolveTargetTaskList(for intent: INAddTasksIntent, with completion: @escaping (INTaskListResolutionResult) -> Void) {

    guard let title = intent.targetTaskList?.title else {
        completion(.needsValue())
        return
    }

    let possibleLists = getPossibleLists(for: title)
    completeResolveTaskList(with: possibleLists, for: title, with: completion)
}

completeResolveTaskList is just like completeResolveListName, but with slightly different types (a task list instead of the title of a task list).

public func completeResolveTaskList(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) {

    let taskLists = possibleLists.map {
        return INTaskList(title: $0, tasks: [], groupName: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil)
    }

    switch possibleLists.count {
    case 0:
        completion(.unsupported())
    case 1:
        if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() {
            completion(.success(with: taskLists[0]))
        } else {
            completion(.confirmationRequired(with: taskLists[0]))
        }
    default:
        completion(.disambiguation(with: taskLists))
    }
}

It has the same disambiguation logic and behaves in exactly the same way. Saying “Store” needs to be disambiguated, and saying “Grocery Store” would be an exact match.

We’ll leave confirm unimplemented and accept the default. For handle, we need to add an item to the list and save it.

func handle(intent: INAddTasksIntent, completion: @escaping (INAddTasksIntentResponse) -> Void) {
    var lists = loadLists()
    guard
        let taskList = intent.targetTaskList,
        let listIndex = lists.index(where: { $0.name.lowercased() == taskList.title.spokenPhrase.lowercased() }),
        let itemNames = intent.taskTitles, itemNames.count > 0
    else {
            completion(INAddTasksIntentResponse(code: .failure, userActivity: nil))
            return
    }

    // Get the list
    var list = lists[listIndex]

    // Add the items
    var addedTasks = [INTask]()
    for item in itemNames {
        list.addItem(name: item.spokenPhrase, at: list.items.count)
        addedTasks.append(INTask(title: item, status: .notCompleted, taskType: .notCompletable, spatialEventTrigger: nil, temporalEventTrigger: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil))
    }

    // Save the new list
    lists[listIndex] = list
    save(lists: lists)

    // Respond with the added items
    let response = INAddTasksIntentResponse(code: .success, userActivity: nil)
    response.addedTasks = addedTasks
    completion(response)
}

We get a list of items and a target list. We look up the list and add the items. We also need to prepare a response for Siri to show with the added items and send it to the completion function.

This function can handle a phrase like, “In ListOMat, add apples to the grocery list.” It can also handle a list of items like, “rice, onions and olives.”

Siri adds a few items to the grocery store list

Almost Done, Just A Few More Settings

All of this will work in your simulator or local device, but if you want to submit this, you’ll need to add a NSSiriUsageDescription key to your app’s plist, with a string that describes what you are using Siri for. Something like “Your requests about lists will be sent to Siri” is fine.

You should also add a call to:

INPreferences.requestSiriAuthorization { (status) in }

Put this in your main view controller’s viewDidLoad to ask the user for Siri access. This will show the message you configured above and also let the user know that they could be using Siri for this app.

The device will ask for permission if you try to use Siri in the app.

Finally, you’ll need to tell Siri what to tell the user if the user asks what your app can do, by providing some :

Create a plist file in your app (not the extension), named AppIntentVocabulary.plist.

Fill out the intents and phrases that you support.

)

There is no way to really know all of the phrases that Siri will use for an intent, but Apple does provide a few samples for each intent in its documentation. The  show us that Siri can understand “Show me all my notes on <appName>,” but I found other phrases by trial and error (for example, Siri understands what “lists” are too, not just notes).

Summary

As you can see, adding Siri support to an app has a lot of steps, with a lot of configuration. But the code needed to handle the requests was fairly simple.

There are a lot of steps, but each one is small, and you might be familiar with a few of them if you have used extensions before.

Here is what you’ll need to prepare for a new extension on Apple’s developer website:

Make an app ID for an Intents extension.

Make an app group if you don’t already have one.

Use the app group in the app ID for the app and extension.

Add Siri support to the app’s ID.

Regenerate the profiles and download them.

And here are the steps in Xcode for creating Siri’s Intents extension:

Add an Intents extension using the Xcode template.

Update the entitlements of the app and extension to match the profiles (groups and Siri support).

Add your intents to the extension’s plist.

And you’ll need to add code to do the following things:

Use the app group sandbox to communicate between the app and extension.

Add classes to support each intent with resolve, confirm and handle functions.

Update the generated IntentHandler to use those classes.

Ask for Siri access somewhere in your app.

Finally, there are some Siri-specific configuration settings:

Add the Siri support security string to your app’s plist.

Add sample phrases to an AppIntentVocabulary.plist file in your app.

Run the intent target to test; edit the scheme to provide the phrase.

OK, that is a lot, but if your app fits one of Siri’s domains, then users will expect that they can interact with it via voice. And because the competition for voice assistants is so good, we can only expect that WWDC 2018 will bring a bunch more domains and, hopefully, much better Siri.

Further Reading

“,” Apple

The technical documentation contains the full list of domains and intents.

“,” Apple

Includes code for many domains.

“” (video, Safari only), WWDC 2016 Apple

“” (video, Safari only), WWDC 2017, Apple

Apple introduces lists and notes

“,” Apple

The full list of lists and notes intents.

  (da, ra, al, il)

---------------

12、Becoming A UX Leader

Christopher Murphy
[https://www.smashingmagazine.com/2018/04/becoming-a-ux-leader/](https://www.smashingmagazine.com/2018/04/becoming-a-ux-leader/)

              <meta charset="utf-8">
              <link rel="canonical" href="https://www.smashingmagazine.com/2018/04/becoming-a-ux-leader/" />
              <title>Becoming A UX Leader</title>

Becoming A UX Leader

                    <address>Christopher Murphy</address>

                  <time datetime="2018-04-11T12:50:15+02:00" class="op-published">2018-04-11T12:50:15+02:00</time>
                  <time datetime="2018-04-11T22:10:30+00:00" class="op-modified">2018-04-11T22:10:30+00:00</time>

(This is a sponsored article.) In my previous article on , I explored the rapidly growing need for UX teams as a result of the emergence of design as a wider business driver. As teams grow, so too does a need for leaders to nurture and guide them.

In my final article in this series on user experience design, I’ll explore the different characteristics of an effective UX leader, and provide some practical advice about growing into a leadership role.

I’ve worked in many organizations — both large and small, and in both the private and public sectors — and, from experience, leadership is a rare quality that is far from commonplace. Truly inspiring leaders are few and far between; if you’re fortunate to work with one, make every effort to learn from them.

Managers that have risen up the ranks don’t automatically become great leaders, and perhaps one of the biggest lessons I’ve learned is that truly inspirational leaders — those that inspire passion and commitment — aren’t as commonplace as you’d think.

A UX leader is truly a hybrid, perhaps more so than in many other — more traditional — businesses. A UX leader needs to encompass a wide range of skills:

Establishing, driving and articulating a vision;

Communicating across different teams, including design, research, writing, engineering, and business (no small undertaking!);

Acting as a champion for user-focused design;

Mapping design decisions to key performance indicators (KPIs), and vice-versa, so that success can be measured; and

Managing a team, ensuring all the team’s members are challenged and motivated.

UX leadership is not unlike being bi-lingual — or, more accurately, multi-lingual — and it’s a skill that requires dexterity so that nothing gets lost in translation.

This hybrid skill set can seem daunting, but — like anything — the attributes of leadership can be learned and developed. In my final article in this series of ten, I’ll explore what defines a leader and focus on the qualities and attributes needed to step up to this important role.

Undertaking A Skills Audit

Every leader is different, and every leader will be informed by the different experiences they have accumulated to date. There are, however, certain qualities and attributes that leaders tend to share in common.

Great leaders demonstrate self-awareness. They tend to have the maturity to have looked themselves in the mirror and identified aspects of their character that they may need to develop if they are to grow as leaders.

Having identified their strengths and weaknesses and pinpointing areas for improvement, they will have an idea of what they know and — equally important — what they don’t know. As Donald Rumsfeld famously put it:

“There are known knowns: there are things we know we know. We also know there are known unknowns: That is to say, we know there are some things we do not know. But there are also unknown unknowns: the things we don't know we don't know.”

Rumsfeld might have been talking about unknown unknowns in a conflict scenario, but his insight applies equally to the world of leadership. To grow as a leader, it’s important to widen your knowledge so that it addresses both:

The Known Unknowns

Skills you know that you don’t know, which you can identify through a self-critical skills audit; and

The Unknown Unknowns

Skills you don’t know you don’t know, which you can identify through inviting your peers to review your strengths and weaknesses.

In short, a skills audit will equip you with a roadmap that you can use as a map to plot a path from where you are now to where you want to be.

		<img
			srcset="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_400/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png 400w,
			        https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_800/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png 800w,
			        https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_1200/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png 1200w,
			        https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_1600/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png 1600w,
			        https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_2000/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png 2000w"
			src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_auto/w_400/https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/192739e7-cf18-4c76-bd52-25d0fa70cd3b/skills-roadmap.png"
			sizes="100vw"
			alt="a map that you can use to plot a path from where you are now to where you want to be"
		/>

			Undertaking a skills audit will enable you to develop a map that you can use to plot a path from where you are now to where you want to be. ()

To become an effective leader is to embark upon a journey, identifying the gaps in your knowledge and — step by step — addressing these gaps so that you’re prepared for the leadership role ahead.

Identifying The Gaps In Your Knowledge

One way to identify the gaps in your knowledge is to undertake an honest and self-reflective ‘skills audit’ while making an effort to both learn about yourself and learn about the environment you are working within.

To become a UX leader, it’s critical to develop this self-awareness, identifying the knowledge you need to acquire by undertaking both self-assessments and peer assessments. With your gaps in knowledge identified, it’s possible to build a learning pathway to address these gaps.

In the introduction, I touched on a brief list of skills that an effective and well-equipped leader needs to develop. That list is just the tip of a very large iceberg. At the very least, a hybrid UX leader needs to equip themselves by:

Developing an awareness of context, expanding beyond the realms of design to encompass a broader business context;

Understanding and building relationships with a cross-section of team members;

Identifying outcomes and goals, establishing KPIs that will help to deliver these successfully;

Managing budgets, both soft and hard; and

Planning and mapping time, often across a diversified team.

These are just a handful of skills that an effective UX leader needs to develop. If you’re anything like me, hardly any of this was taught at art school, so you’ll need to learn these skills yourself. This article will help to point you in the right direction. I’ve also provided a list of required reading for reference to ensure you’re well covered.

A 360º Assessment

A 360º degree leadership assessment is a form of . Drawn from the world of business, but equally applicable to the world of user experience, it is an excellent way to measure your effectiveness and influence as a leader.

Unlike a top-down appraisal, where a leader or manager appraises an employee underneath them in the hierarchy, a 360º assessment involves inviting your colleagues — at your peer level — to appraise you, highlighting your strengths and weaknesses.

This isn’t easy — and can lead to some uncomfortable home truths — but it can prove a critical tool in helping you to identify the qualities you need to work on. You might, for example, consider yourself an excellent listener only to discover that your colleagues feel like this is something you need to work on.

This willingness to put yourself under the spotlight, identify your weaknesses, address these, and develop yourself is one of the defining characteristics of leaders. Great leaders are always learning and they aren’t afraid to admit that fact.

A 360º assessment is a great way to uncover your ‘unknown unknowns’, i.e. the gaps in your knowledge that you aren’t aware of. With these discoveries in hand, it’s possible to build ‘a learning road-map’ that will allow you to develop the skills you need.

Build A Roadmap

With the gaps in your knowledge identified, it’s important to adopt some strategies to address these gaps. Great leaders understand that learning is a lifelong process and to transition into a leadership role will require — inevitably — the acquisition of new skills.

To develop as a leader, it’s important to address your knowledge gaps in a considered and systematic manner. By working back from your skills audit, identify what you need to work on and build a learning programme accordingly.

This will inevitably involve developing an understanding of different domains of knowledge, but that’s the leader’s path. The important thing is to take it step by step and, of course, to take that first step.

We are fortunate now to be working in an age in which we have an abundance of learning materials at our fingertips. We no longer need to enroll in a course at a university to learn; we can put together our own bespoke learning programmes.

We now have so many tools we can use, from paid resources like  which offers the ability to “learn new skills, pursue your interests and advance your career.”

In short, you have everything you need to enhance your career just a click away.

It’s Not Just You

Great leaders understand that it’s not about the effort of individuals, working alone. It’s about the effort of individuals — working collectively. Looking back through the history of innovation, we can see that most (if not all) of the greatest breakthroughs were driven by teams that were motivated by inspirational leaders.

Thomas Edison didn’t invent the lightbulb alone; he had an ‘ was similarly conceived.

Great leaders understand that it’s not about them as individuals, but it’s about the teams they put together, which they motivate and orchestrate. They have the humility to build and lead teams that deliver towards the greater good.

This — above all — is one of the defining characteristics of a great leader: they prioritize and celebrate the team’s success over and above their own success.

It’s All About Teamwork

Truly great leaders understand the importance that teams play in delivering outcomes and goals. One of the most important roles a leader needs to undertake is to act as a lynchpin that sits at the heart of a team, identifying new and existing team members, nurturing them, and building them into a team that works effectively together.

A forward-thinking leader won’t just focus on the present, but will proactively develop a vision and long-term goals for future success. To deliver upon this vision of future success will involve both identifying potential new team members, but — just as importantly — developing existing team members. This involves opening your eyes to the different aspects of the business environment you occupy, getting to know your team, and identifying team members’ strengths and weaknesses.

As a UX leader, an important role you’ll play is helping others by mentoring and coaching them, ensuring they are equipped with the skills they need to grow. Again, this is where a truly selfless leader will put others first, in the knowledge that the stronger the team, the stronger the outcomes will be.

As a UX leader, you’ll also act as a champion for design within the wider business context. You’ll act as a bridge — and occasionally, a buffer — between the interface of business requirements and design requirements. Your role will be to champion the power of design and sell its benefits, always singing your team’s praises and — occasionally — fighting on their behalf (often without their awareness).

The Art Of Delegation

It’s possible to build a great UX team from the inside by developing existing team members, and an effective leader will use delegation as an effective development tool to enhance their team members’ capabilities.

Delegation isn’t just passing off the tasks you don’t want to do, it’s about empowering the different individuals in a team. A true leader understands this and spends the time required to learn how to delegate effectively.

Delegation is about education and expanding others’ skill sets, and it’s a powerful tool when used correctly. Effective delegation is a skill, one that you’ll need to acquire to step up into a UX leadership role.

When delegating a task to a team member, it’s important to explain to them why you’re delegating the task. As a leader, your role is to provide clear guidance and this involves explaining why you’ve chosen a team member for a task and how they will be supported, developed and rewarded for taking the task on.

This latter point is critical: All too often managers who lack leadership skills use delegation as a means to offload tasks and responsibility, unaware of the power of delegation. This is poor delegation and it’s ineffective leadership, though I imagine, sadly, we have all experienced it! An effective leader understands and strives to delegate effectively by:

defining the task, establishing the outcomes and goals;

identifying the appropriate individual or team to take the task on;

assessing the team member(s) ability and ascertaining any training needs;

explaining their reasoning, clearly outlining why they chose the individual or team;

stating the required results;

agreeing on realistic deadlines; and

providing feedback on completion of the task.

When outlined like this, it becomes clear that effective delegation is more than simply passing on a task you’re unwilling to undertake. Instead, it’s a powerful tool that an effective UX leader uses to enable their team members to take ownership of opportunities, whilst growing their skills and experience.

Give Success And Accept Failure

A great leader is selfless: they give credit for any successes to the team; and accept the responsibility for any failures alone.

A true leader gives success to the team, ensuring that — when there’s a win — the team is celebrated for its success. A true leader takes pleasure in celebrating the team’s win. When it comes to failure, however, a true leader steps up and takes responsibility. A mark of a truly great leader is this selflessness.

As a leader, you set the direction and nurture the team, so it stands to reason that, if things go wrong — which they often do — you’re willing to shoulder the responsibility. This understanding — that you need to give success and accept failure — is what separates great leaders from mediocre managers.

Poor managers will seek to ‘deflect the blame,’ looking for anyone but themselves to apportion responsibility to. Inspiring leaders are aware that, at the end of the day, they are responsible for the decisions made and outcomes reached; when things go wrong they accept responsibility.

If you’re to truly inspire others and lead them to achieve great things, it’s important to remember this distinction between managers and leaders. By giving success and accepting failure, you’ll breed intense loyalty in your team.

Lead By Example

Great leaders understand the importance of leading by example, acting as a beacon for others. To truly inspire a team, it helps to connect yourself with that team, and not isolate yourself. Rolling up your sleeves and pitching in, especially when deadlines are pressing, is a great way to demonstrate that you haven’t lost touch with the ‘front line.’

A great leader understands that success is — always — a team effort and that a motivated team will deliver far more than the sum of its parts.

As I’ve noted in my previous articles: If you’re ever the smartest person in a room, find another room. An effective leader has the confidence to surround themselves with other, smarter people.

Leadership isn’t about individual status or being seen to be the most talented. It’s about teamwork and getting the most out of a well-oiled machine of individuals working effectively together.

Get Out Of Your Silo

To lead effectively, it’s important to get out of your silo and to see the world as others do. This means getting to know all of the team, throughout the organization and at every level.

Leaders that isolate themselves — in their often luxurious corner offices — are, in my experience, poor leaders (if, indeed, they can be called leaders at all!). By distancing themselves from the individuals that make up an organization they run the very real risk of losing touch.

To lead, get out of your silo and acquaint yourself with the totality of your team and, if you’re considering a move into leadership, make it your primary task to explore all the facets of the business.

The Pieces Of The Jigsaw

To lead effectively, you need to have an understanding of others and their different skills. In my last article, , I wrote about the idea of ‘T-shaped’ people — those that have a depth of skill in their field, along with the willingness and ability to collaborate across disciplines. Great leaders tend to be T-shaped, flourishing by seeing things from others’ perspectives.

Every organization — no matter how large or small — is like an elaborate jigsaw that is made up of many different interlocking parts. An effective leader is informed by an understanding of this context, they will have made the effort to see all of the pieces of the jigsaw. As a UX leader, you’ll need to familiarize yourself with a wide range of different teams, including design, research, writing, engineering, and business.

To lead effectively, it’s important to push outside of your comfort zone and learn about these different specialisms. Do so and you will ensure that you can communicate to these different stakeholders. At the risk of mixing metaphors, you will be the glue that holds the jigsaw together.

Sweat The Details

As Charles and Ray Eames put it:

“The details aren’t the details, they make the product.”

Great leaders understand this: they set the bar high and they encourage and motivate the teams they lead to deliver on the details. To lead a team, it’s important to appreciate the need to strive for excellence. Great leaders aren’t happy to accept the status quo, especially if the status quo can be improved upon.

Of course, these qualities can be learned, but many of us — thankfully — have them, innately. Few (if any) of us are happy with second best and, in a field driven by a desire to create delightful and memorable user experiences, we appreciate the importance of details and their place in the grand scheme of things. This is a great foundation on which to build leadership skills.

To thrive as a leader, it’s important to share this focus on the details with others, ensuring they understand and appreciate the role that the details play in the whole. Act as a beacon of excellence: lead by example; never settle for second best; give success and accept failure… and your team will follow you.

In Closing

As user experience design matures as a discipline, and the number of different specializations multiplies, so too does the discipline’s need for leaders, to nurture and grow teams. As a relatively new field of expertise, the opportunities to develop as a UX leader are tremendous.

Leadership is a skill and — like any skill — it can be learned. As I’ve noted throughout this series of articles, one of the best places to learn is to look to other disciplines for guidance, widening the frame of reference. When we consider leadership, this is certainly true.

There is a great deal we can learn from the world of business, and websites like  — amongst many, many others — offer us a wealth of insight.

There’s never been a more exciting time to work in User Experience design. UX has the potential to impact on so many facets of life, and the world is crying out for leaders to step up and lead the charge. I’d encourage anyone eager to learn and to grow to undertake a skills audit, take the first step, and embark on the journey into leadership. Leadership is a privilege, rich with rewards, and is something I’d strongly encourage exploring.

Suggested Reading

There are many great publications, offline and online, that will help you on your adventure. I’ve included a few below to start you on your journey.

The Harvard Business Review website is an excellent starting point and its guide, , provides an excellent overview on developing leadership qualities.

Peter Drucker’s writing on leadership is also well worth reading. Drucker has written many books, one I would strongly recommend is . It’s a short (but very powerful) read, and I read it at least two or three times a year.

If you’re serious about enhancing your leadership credentials, Michael D. Watkins’s , provides a comprehensive insight into transitioning into leadership roles.

Finally, HBR’s website — mentioned above — is definitely worth bookmarking. Its business-focused flavor offers designers a different perspective on leadership, which is well worth becoming acquainted with.

This article is part of the UX design series sponsored by Adobe.  to stay updated and informed on the latest trends and insights for UX/UI design.

  (ra, il)

---------------

repository: iv-web/ivweb-weekly

repo_name: iv-web/ivweb-weekly


text:
theme: mathjax

Include `theme: mathjax` at the beginning of your file to enable MathJax
rendering. The default MathJax theme uses the [CDN][1].

LaTeX can be included inline between single dollar signs: $e = mc^2$ or
in blocks between double dollar signs:

$$
    \sum_{n=1}^\infty \frac{1}{n}
$$

$$
    (1+x)^n
    = 1 + nx
    + \frac{n(n-1)}{2!}x^2
    + \frac{n(n-1)(n-2)}{3!}x^3
    + \ldots
$$

[1]: http://www.mathjax.org/download/mathjax-cdn-terms-of-service/

This is the source for the above example:

---
    theme: mathjax

    Include `theme: mathjax` at the beginning of your file to enable MathJax
    rendering. The default MathJax theme uses the [CDN][1].

    LaTeX can be included inline between single dollar signs: $e = mc^2$ or
    in blocks between double dollar signs:

    $$
        \sum_{n=1}^\infty \frac{1}{n}
    $$

    $$
        (1+x)^n
        = 1 + nx
        + \frac{n(n-1)}{2!}x^2
        + \frac{n(n-1)(n-2)}{3!}x^3
        + \ldots
    $$

    [1]: http://www.mathjax.org/download/mathjax-cdn-terms-of-service/

repository: kevinbeaty/mvw-mathjax

repo_name: kevinbeaty/mvw-mathjax


text:
# Book Search

![licence: MIT](https://img.shields.io/badge/license-MIT-blue)

## Description
Book Search is a fun and easy way to search for and save books you are interested in. Enter any search and get a list of relevant books with titles, authors, images, links and descriptions. Sign up or login to save your favorite books!

Book search is built using:
  - MongoDB
  - Express
  - React
  - Node
  - GraphQL
  - Apollo-Server
  - JSON Web Tokens for user authentication

### [Deployed Application](https://book-search-3000.herokuapp.com/)

### Screenshot
![screen-shot](./client/assets/appScreenshot.jpg)

## Questions

- Feel free to reach out with any questions

## License
- MIT

### Contact information:
- GitHub: [jchavezval](https://www.github.com/jchavezval)
- Email: [jmchv20011@gmail.com](mailto: jmchv2001@gmail.com)

repository: jchavezval/book-search-engine

repo_name: jchavezval/book-search-engine


text:
# Nuklear-Bindings : A Ruby bindings for Nuklear UI Library #

Provides Nuklear ( https://github.com/vurtun/nuklear ) interfaces for ruby (MRI).

*   Created : 2016-06-23
*   Last modified : 2017-08-14

## Prerequisites ##

*   Ruby-FFI ( https://github.com/ffi/ffi )
    *   $ gem install ffi

*   For demo/example.rb : opengl-bindings ( https://github.com/vaiorabbit/ruby-opengl )
    *   $ gem install opengl-bindings

## How to Use ##

1. Build Nuklear shared library
    *   See nuklear_dll

2. Include nuklear.rb in your script.
    *   ex.) require_relative 'nuklear'

3. Load shared library
    *   ex.) Nuklear.load_lib('libnuklear.dylib')

4. Setup OpenGL

See demo/example.rb for details.

## License ##

All source codes are available under the terms of the zlib/libpng license.

	Nuklear-Bindings : A Ruby bindings for Nuklear
	Copyright (c) 2016-2018 vaiorabbit

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	    1. The origin of this software must not be misrepresented; you must not
	    claim that you wrote the original software. If you use this software
	    in a product, an acknowledgment in the product documentation would be
	    appreciated but is not required.

	    2. Altered source versions must be plainly marked as such, and must not be
	    misrepresented as being the original software.

	    3. This notice may not be removed or altered from any source
	    distribution.

license: Zlib

repository: vaiorabbit/ruby-nuklear

repo_name: vaiorabbit/ruby-nuklear


text:
### [CVE-2016-0595](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0595)
![](https://img.shields.io/static/v1?label=Product&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Vulnerability&message=n%2Fa&color=brighgreen)

### Description

Unspecified vulnerability in Oracle MySQL 5.6.27 and earlier allows remote authenticated users to affect availability via vectors related to DML.

### POC

#### Reference
- http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html

#### Github
No PoCs found on GitHub currently.

repository: trickest/cve

gha_language: HTML

repo_name: trickest/cve


text:
# hexs

This is a very small package which contains functions that format hex strings.
The purpose of this formatting is to make a given hex string of even length,
remove a "0x" prefix if present, and remove a "L" suffix if present.

It also includes a convenience function, `hexs()`, which calls the built-in `hex()`
function and formats the result.

## Usage

```
>>> from hexs import is_hex, hexs, format_hex
>>> hexs(5)
'05'
>>> format_hex('0x5')
'05'
>>> is_hex('g')
False
>>> is_hex(29)
False
>>> is_hex('f')
True
```

## License

MIT License.

repository: Kefkius/hexs

repo_name: Kefkius/hexs


text:
# race-track-archiver

This utility will generate a JSON file that contains all of the details of a YB tracked race. It takes a single input: the race slug which comes from a URL like: `https://yb.tl/stmalo2021`

## Installation

Clone this repository locally, then:

To use the binned reference to the app, you'll need to install it globally: `npm install -g`. Otherwise just `npm install` and `chmod +x index.js`.

### Filtering

Let's say you want to get a CSV of retirements. You can do this with the [jq](https://stedolan.github.io/jq/download/) utility and `npm install -g @json2csv/cli`. Install it, then:

```bash
$ npm i -g json2csv
cat race_fastnet2021.json | jq -c '.teams[] | select(.status=="RETIRED")' | jq -s | json2csv -f id,sail,name,model,explain  -o retirements.csv
```

## GeoJSON

To create a GeoJSON file of the race details (e.g., start line, TSS, etc.):

```bash
$ race-track-archiver fastnet2021
Go get fastnet2021
Retrieved fastnet2021 to race_fastnet2021.json
$ node to_geojson.js fastnet2021
Load fastnet2021
Converted fastnet2021's race geometries to race_fastnet2021.geojson
```

## GPX Track (Navionics Track)

To create a GPX file that can be imported to Navionics as a Track, use:

```bash
$ race-track-archiver fastnet2021
Go get fastnet2021
Retrieved fastnet2021 to race_fastnet2021.json
$ node build_gpx.js fastnet2021 GBR8367
Load fastnet2021
First Time: 2021-08-08T10:05:00.000Z
Latests Time: 2021-08-11T13:15:01.000Z
Wrote Rho as of 2021-08-11T13:15:01.000Z to track_fastnet2021_GBR8367_20210811131501.gpx
```

Then, send the file to a mobile device for viewing. You should be able to do this by sending it to yourself in an email, in WhatsApp (using WhatsApp Desktop), or Air Drop (on a Mac). When prompted on your device, open it with "Boating" (the current name for the Navionics app).

## TODO

- [ ] Filter out positions after a boat finishes or retires (we don't care where they went after retiring)
- [ ] Add visualisation layer
- [ ] Make sense of the leaderboard output (likely duplicates)
- [ ] Figure out if there's a way to list all of the known YB races. (When predictwind.com's YB tab is working--based on a [tutorial video](https://www.youtube.com/watch?v=SoQEIreSnTE)--it should list all races.)

repository: mklaber/race-track-archiver

repo_name: mklaber/race-track-archiver


text:
---
layout: post
title: "Web Puzzle"
categories: clues
images: [web_puzzle1.jpg, web_puzzle2.jpg]
latlong: [42.453, -71.396]
---

The code inside the 3D puzzle box can be redeemed at the Sc4venger Hunt website. This unlocks an HTML puzzle in the style of "HD White's Puzzle of Doom" or "NotPron" requiring her to change the URL to move to the next puzzle.


text:
# mongoDB
Basic syntax for CRUD operation and also other commands.

# My first Mongo Commands
* mongod => used for running mongo deamon or other word use for running mongodb
* mongo => for running the mongo shell.
* help => for showing help in the mongo shell.
* show dbs => for showing the databases.
* use => for using an existing db or create a new db.
* show collections for showing the current database.

# Most Important
# CRUD
* insert => for inserting data to the database. syntax: db.[nameOfdb].insert({key : "value"}).

* find => for diplaying data or finding given key data. syntax : db.[nameOfdb].find() or db.[nameOfdb].find({key: "value"})

* update => is used for updaing the database. syntax: db.[nameOfdb].update({name: "[value]"},
  {$set : {[keyToChange] : "[newValue]"}}) and we can also set the new property by using the new $set object
  the syntax is: db.[nameOfdb].update({name: "[value]"}, {$set : {[newKey] : "[newValue]"}})

* remove => is used for removing or deleting elements from database. In order to delete a collection or value
  the syntax is: db.[nameOfdb].remove({[nameOfdbKEY]:"[nameOfdbVALUE]"})
* remove => We can also remove the number of or limit the number to remove
  or delete.
  db.[nameOfdb].remove({key: "[value]"}).limit["HowMuchCollectionToDelete"].


text:
SCC Core version v3.2.0
==========================

Release is now available from:

  <https://github.com/stakecube/StakeCubeCoin/releases>

This is a new hotfix release.

Please report bugs using the issue tracker at github:

  <https://github.com/stakecube/StakeCubeCoin/issues>

Upgrading and downgrading
=========================

How to Upgrade
--------------

If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes for older versions), then run the
installer (on Windows) or just copy over /Applications/SCC-Qt (on Mac) or
sccd/scc-qt (on Linux). If you upgrade after DIP0003 activation and you were
using version < 0.13 you will have to reindex (start with -reindex-chainstate
or -reindex) to make sure your wallet has all the new data synced. Upgrading
from version 0.13 should not require any additional actions.

When upgrading from a version prior to v3.1.0, the
first startup of SCC Core will run a migration process which can take a few
minutes to finish. After the migration, a downgrade to an older version is only
possible with a reindex (or reindex-chainstate).

Notable changes
===============

This release adds some missing translations and help strings. It also fixes
a couple of build issues and a rare crash on some linux systems.

<IP_ADDRESS> Change log
===================

- [`6a54af0df7`](https://github.com/stakecube/StakeCubeCoin/commit/6a54af0df7) Bump to v3.2.0
- [`97e8461234`](https://github.com/stakecube/StakeCubeCoin/commit/97e8461234) doc: Archive v3.1.0 release notes
- [`3661f36bbd`](https://github.com/stakecube/StakeCubeCoin/commit/3661f36bbd) Merge #14416: Fix OSX dmg issue (10.12 to 10.14) (#4177)
- [`575e0a3070`](https://github.com/stakecube/StakeCubeCoin/commit/575e0a3070) qt: Add `QFont::Normal` as a supported font weight when no other font weights were found (#4175)
- [`ce4a73b790`](https://github.com/stakecube/StakeCubeCoin/commit/ce4a73b790) rpc: Fix `upgradetohd` help text (#4170)
- [`2fa8ddf160`](https://github.com/stakecube/StakeCubeCoin/commit/2fa8ddf160) Translations 202105 (add missing) (#4169)

Credits
=======

Thanks to everyone who directly contributed to this release:

- dustinface (xdustinface)
- strophy
- UdjinM6

As well as everyone that submitted issues and reviewed pull requests.

repository: stakecube/StakeCubeCoin

repo_name: stakecube/StakeCubeCoin