text:
const { WebClient } = require('@slack/web-api');
const AWS = require('aws-sdk');
const Access = require('../../access');

const web = new WebClient(process.env.SLACK_ACCESS_TOKEN);

module.exports = {
  /**
   * Opens a modal to handle approval rejection
   * @param {*} payload
   */
  handleBlockActionPayload: async function handleBlockActionPayload(payload) {
    const action = payload.actions[0];
    const metadata = JSON.parse(action.value);
    metadata.channelId = payload.channel.id;
    metadata.messageTs = payload.message.ts;

    await web.views.open({
      trigger_id: payload.trigger_id,
      view: {
        type: 'modal',
        callback_id: 'codepipeline-approval_reject-deploy',
        clear_on_close: true,
        private_metadata: JSON.stringify(metadata),
        title: {
          type: 'plain_text',
          text: 'Reject Deployment',
        },
        submit: {
          type: 'plain_text',
          text: 'Reject',
        },
        blocks: [
          {
            type: 'input',
            block_id: 'codepipeline-approval_reject-deploy-summary',
            label: {
              type: 'plain_text',
              text: 'Reason',
            },
            // hint: {
            //   type: 'plain_text',
            //   text:
            //     'Put each path on its own line. All paths must start with a slash. Paths may include wildcards (*), which must be the last character if included.',
            // },
            element: {
              type: 'plain_text_input',
              action_id: 'codepipeline-approval_reject-deploy-summary',
              placeholder: {
                type: 'plain_text',
                text: 'e.g., "No op", "Issue discovered in staging"',
              },
              multiline: true,
            },
          },
        ],
      },
    });
  },
  /**
   * Handles modal submission, sending the approval result to CodePipeline
   * and updating the approval notification message in Slack
   * @param {*} payload
   */
  handleViewSubmissionPayload: async function handleViewSubmissionPayload(
    payload,
  ) {
    // Get the value from the modal's input block
    const { values } = payload.view.state;
    const block = values['codepipeline-approval_reject-deploy-summary'];
    const action = block['codepipeline-approval_reject-deploy-summary'];
    const { value } = action;

    const approvalParams = JSON.parse(payload.view.private_metadata);

    const pipelineRegion = approvalParams.result.summary.split(',')[0];
    const pipelineAccountId = approvalParams.result.summary.split(',')[1];

    approvalParams.result.summary = value;

    const channelId = approvalParams.channelId;
    const messageTs = approvalParams.messageTs;
    delete approvalParams.channelId;
    delete approvalParams.messageTs;

    // Assume a role in the selected account that has permission to
    // putApprovalResult
    const role = await Access.devopsRole(pipelineAccountId);

    const codepipeline = new AWS.CodePipeline({
      apiVersion: '2019-03-26',
      region: pipelineRegion,
      accessKeyId: role.Credentials.AccessKeyId,
      secretAccessKey: role.Credentials.SecretAccessKey,
      sessionToken: role.Credentials.SessionToken,
    });

    await codepipeline.putApprovalResult(approvalParams).promise();

    // Get the message that included the approval notification/button
    const history = await web.conversations.history({
      limit: 1,
      inclusive: true,
      channel: channelId,
      latest: messageTs,
    });

    // Update approval notification message in Slack
    const msg = history.messages[0];

    // These changes are made to the message constructed in the Spire CD
    // pipeline events handler Lambda, where the production approval message is
    // handled
    msg.attachments[0].color = '#a30200';
    msg.attachments[0].blocks.splice(2, 1);
    msg.attachments[0].blocks[1].text.text = `❌ <@${payload.user.id}> rejected this release with the reason:\n> ${value}`;

    await web.chat.update({
      channel: channelId,
      ts: messageTs,
      // @ts-ignore
      attachments: msg.attachments,
    });
  },
};


text:
	// FileName: NewChat.lua
	// Written by: Xsitsu
	// Description: Bridges the topbar in corescripts to any chat system running in the non-corescripts environment.
]]
local CoreGuiService = game:GetService("CoreGui")
local RobloxGui = CoreGuiService:WaitForChild("RobloxGui")

local StarterGui = game:GetService("StarterGui")
local GuiService = game:GetService("GuiService")
local PlayersService = game:GetService("Players")

local ChatTypesSet = false
local ClassicChatEnabled = PlayersService.ClassicChat
local BubbleChatEnabled = PlayersService.BubbleChat

local Util = require(RobloxGui.Modules.ChatUtil)

local moduleApiTable = {}
do
		local ChatWindowState =
		{
			Visible = true,
			MessageCount = 0,
			TopbarEnabled = true,
			CoreGuiEnabled = true,
		}

		local communicationsConnections = {}
		local eventConnections = {}

		local SetCoreCache = {}

		local function FindInCollectionByKeyAndType(collection, indexName, type)
			if (collection and collection[indexName] and collection[indexName]:IsA(type)) then
				return collection[indexName]
			end
			return nil
		end

		local function DispatchEvent(eventName, ...)
			local event = FindInCollectionByKeyAndType(communicationsConnections.ChatWindow, eventName, "BindableEvent")
			if (event) then
				event:Fire(...)
				return true
			end
			return false
		end

		local function AttemptInvokeFunction(functionName, ...)
			local func = FindInCollectionByKeyAndType(communicationsConnections.ChatWindow, functionName, "BindableFunction")
			if (func) then
				return true, func:Invoke()
			end
			return false, nil
		end

		local function DoConnectGetCore(connectionName)
			StarterGui:RegisterGetCore(connectionName, function(data)
				local func = FindInCollectionByKeyAndType(communicationsConnections.GetCore, connectionName, "BindableFunction")
				local rVal = nil
				if (func) then rVal = func:Invoke(data) end
				return rVal
			end)
		end

		function moduleApiTable:ToggleVisibility()
			ChatWindowState.Visible = not ChatWindowState.Visible
			local didFire = DispatchEvent("ToggleVisibility")
			if (not didFire) then
				moduleApiTable.VisibilityStateChanged:fire(ChatWindowState.Visible)
			end
		end

		function moduleApiTable:SetVisible(visible)
			ChatWindowState.Visible = visible
			local didFire = DispatchEvent("SetVisible", ChatWindowState.Visible)
			if (not didFire) then
				moduleApiTable.VisibilityStateChanged:fire(ChatWindowState.Visible)
			end
		end

		function moduleApiTable:FocusChatBar()
			DispatchEvent("FocusChatBar")
		end

		function moduleApiTable:GetVisibility()
			local success, retVal = AttemptInvokeFunction("GetVisibility")
			if (success) then
				return retVal
			else
				return ChatWindowState.Visible
			end
		end

		function moduleApiTable:GetMessageCount()
			local success, retVal = AttemptInvokeFunction("GetMessageCount")
			if (success) then
				return retVal
			else
				return ChatWindowState.MessageCount
			end
		end

		function moduleApiTable:TopbarEnabledChanged(enabled)
			ChatWindowState.TopbarEnabled = enabled
			DispatchEvent("TopbarEnabledChanged", ChatWindowState.TopbarEnabled)
		end

		function moduleApiTable:IsFocused(useWasFocused)
			local success, retVal = AttemptInvokeFunction("IsFocused", useWasFocused)
			if (success) then
				return retVal
			else
				return false
			end
		end

		function moduleApiTable:ClassicChatEnabled()
			return ClassicChatEnabled
		end

		function moduleApiTable:IsBubbleChatOnly()
			return BubbleChatEnabled and not ClassicChatEnabled
		end

		function moduleApiTable:IsDisabled()
			return not (BubbleChatEnabled or ClassicChatEnabled)
		end

		function SetInitialChatTypes(chatTypesTable)
			if ChatTypesSet then
				return
			end
			ChatTypesSet = true

			local bubbleChat = chatTypesTable.BubbleChatEnabled
			local classicChat = chatTypesTable.ClassicChatEnabled
			if type(bubbleChat) == "boolean" then
				BubbleChatEnabled = bubbleChat
			end
			if type(classicChat) == "boolean" then
				ClassicChatEnabled = classicChat
			end

			if not (ClassicChatEnabled or BubbleChatEnabled) then
				moduleApiTable.ChatDisabled:fire()
			end
			if BubbleChatEnabled and not ClassicChatEnabled then
				moduleApiTable.BubbleChatOnlySet:fire()
			end
		end

		moduleApiTable.ChatBarFocusChanged = Util.Signal()
		moduleApiTable.VisibilityStateChanged = Util.Signal()
		moduleApiTable.MessagesChanged = Util.Signal()

		-- Signals that are called when we get information on if Bubble Chat and Classic chat are enabled from the chat.
		moduleApiTable.BubbleChatOnlySet = Util.Signal()
		moduleApiTable.ChatDisabled = Util.Signal()

		StarterGui.CoreGuiChangedSignal:connect(function(coreGuiType, enabled)
			if (coreGuiType == Enum.CoreGuiType.All or coreGuiType == Enum.CoreGuiType.Chat) then
				ChatWindowState.CoreGuiEnabled = enabled
				DispatchEvent("CoreGuiEnabled", ChatWindowState.CoreGuiEnabled)
			end
		end)

		GuiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
		GuiService.SpecialKeyPressed:connect(function(key, modifiers)
			DispatchEvent("SpecialKeyPressed", key, modifiers)
		end)

		function DoConnectSetCore(setCoreName)
			StarterGui:RegisterSetCore(setCoreName, function(data)
				local event = FindInCollectionByKeyAndType(communicationsConnections.SetCore, setCoreName, "BindableEvent")
				if (event) then
					event:Fire(data)
				else
					if SetCoreCache[setCoreName] == nil then
						SetCoreCache[setCoreName] = {}
					end
					table.insert(SetCoreCache[setCoreName], data)
				end
			end)
		end

		DoConnectSetCore("ChatMakeSystemMessage")
		DoConnectSetCore("ChatWindowPosition")
		DoConnectSetCore("ChatWindowSize")
		DoConnectSetCore("ChatBarDisabled")

		DoConnectGetCore("ChatWindowPosition")
		DoConnectGetCore("ChatWindowSize")
		DoConnectGetCore("ChatBarDisabled")

		local function RegisterCoreGuiConnections(containerTable)
			if (type(containerTable) == "table") then
				local chatWindowCollection = containerTable.ChatWindow
				local setCoreCollection = containerTable.SetCore
				local getCoreCollection = containerTable.GetCore

				if (type(chatWindowCollection) == "table") then
					for i, v in pairs(eventConnections) do
						v:disconnect()
					end

					if type(chatWindowCollection.ChatTypes) == "table" then
						SetInitialChatTypes(chatWindowCollection.ChatTypes)
					end

					eventConnections = {}
					communicationsConnections.ChatWindow = {}

					communicationsConnections.ChatWindow.ToggleVisibility = FindInCollectionByKeyAndType(chatWindowCollection, "ToggleVisibility", "BindableEvent")
					communicationsConnections.ChatWindow.SetVisible = FindInCollectionByKeyAndType(chatWindowCollection, "SetVisible", "BindableEvent")
					communicationsConnections.ChatWindow.FocusChatBar = FindInCollectionByKeyAndType(chatWindowCollection, "FocusChatBar", "BindableEvent")
					communicationsConnections.ChatWindow.TopbarEnabledChanged = FindInCollectionByKeyAndType(chatWindowCollection, "TopbarEnabledChanged", "BindableEvent")
					communicationsConnections.ChatWindow.IsFocused = FindInCollectionByKeyAndType(chatWindowCollection, "IsFocused", "BindableFunction")
					communicationsConnections.ChatWindow.SpecialKeyPressed = FindInCollectionByKeyAndType(chatWindowCollection, "SpecialKeyPressed", "BindableEvent")

					local function DoConnect(index)
						communicationsConnections.ChatWindow[index] = FindInCollectionByKeyAndType(chatWindowCollection, index, "BindableEvent")
						if (communicationsConnections.ChatWindow[index]) then
							local con = communicationsConnections.ChatWindow[index].Event:connect(function(...) moduleApiTable[index]:fire(...) end)
							table.insert(eventConnections, con)
						end
					end

					DoConnect("ChatBarFocusChanged")
					DoConnect("VisibilityStateChanged")
					DoConnect("MessagesChanged")

					local index = "MessagePosted"
					communicationsConnections.ChatWindow[index] = FindInCollectionByKeyAndType(chatWindowCollection, index, "BindableEvent")
					if (communicationsConnections.ChatWindow[index]) then
						local con = communicationsConnections.ChatWindow[index].Event:connect(function(message) game:GetService("Players"):Chat(message) end)
						table.insert(eventConnections, con)
					end

					moduleApiTable:SetVisible(ChatWindowState.Visible)
					moduleApiTable:TopbarEnabledChanged(ChatWindowState.TopbarEnabled)

					local event = FindInCollectionByKeyAndType(chatWindowCollection, "CoreGuiEnabled", "BindableEvent")
					if (event) then
						communicationsConnections.ChatWindow.CoreGuiEnabled = event
						event:Fire(ChatWindowState.CoreGuiEnabled)
					end

				else
					error("Table 'ChatWindow' must be provided!")

				end

				if (type(setCoreCollection) == "table" and type(getCoreCollection) == "table") then
					communicationsConnections.SetCore = {}
					communicationsConnections.GetCore = {}

					local function addSetCore(setCoreName)
						local event = FindInCollectionByKeyAndType(setCoreCollection, setCoreName, "BindableEvent")
						if (event) then
							communicationsConnections.SetCore[setCoreName] = event
							if SetCoreCache[setCoreName] then
								for i, data in pairs(SetCoreCache[setCoreName]) do
									event:Fire(data)
								end
								SetCoreCache[setCoreName] = nil
							end
						end
					end

					addSetCore("ChatMakeSystemMessage")
					addSetCore("ChatWindowPosition")
					addSetCore("ChatWindowSize")
					addSetCore("ChatBarDisabled")

					communicationsConnections.GetCore.ChatWindowPosition = FindInCollectionByKeyAndType(getCoreCollection, "ChatWindowPosition", "BindableFunction")
					communicationsConnections.GetCore.ChatWindowSize = FindInCollectionByKeyAndType(getCoreCollection, "ChatWindowSize", "BindableFunction")
					communicationsConnections.GetCore.ChatBarDisabled = FindInCollectionByKeyAndType(getCoreCollection, "ChatBarDisabled", "BindableFunction")

				elseif (type(setCoreCollection) ~= "nil" or type(getCoreCollection) ~= "nil") then
					error("Both 'SetCore' and 'GetCore' must be tables if provided!")

				end

			end
		end

		StarterGui:RegisterSetCore("CoreGuiChatConnections", RegisterCoreGuiConnections)

end

return moduleApiTable

redpajama_set_name: RedPajamaGithub


text:
module ScormCloud
	class TaggingService < BaseService
		not_implemented :get_course_tags, :set_course_tags, :add_course_tag,
				:remove_course_tag, :get_learner_tags, :set_learner_tags, :add_learner_tag,
				:remove_learner_tag, :get_registration_tags, :set_registration_tags,
				:add_registration_tag, :remove_registration_tag
	end
end


text: module.exports = require('./lib/kotlin');


text:
layout: post
title: "How was the biggest DDoS attack in Internet history perpetrated?"
description: Learn how the Dyn attack was perpetrated, how it could have been prevented and how to avoid similar attacks in the future
date: 2016-10-25 08:30
alias: /how-the-biggest-attack-in-internet-was-perpertrated/
is_non-tech: true
category: Hot Topic, Security, Attacks
design:
  bg_color: "#222228"
  image: https://cdn.auth0.com/blog/biggest-internet-attack/logo.png
author:
  name: Prosper Otemuyiwa
  url: http://twitter.com/unicodeveloper?lang=en
  mail: prosper.otemuyiwa@auth0.com
  avatar: https://en.gravatar.com/avatar/1097492785caf9ffeebffeb624202d8f?s=200
tags:
- internet-attack
- internet-history
- iot
- dyn
related:
- 2016-07-11-pokemon-go-catches-all-your-data
- 2015-11-06-surprised-turns-out-consumers-dont-trust-iot-security/
- 2015-12-28-securing-your-nodebots-with-json-web-tokens

---

---

**TL;DR:** Last week, one of the biggest attacks in the internet history was perpetrated via a group of hackers during which popular websites like **Twitter**, **Netflix**, **GitHub**, **Amazon**, **Spotify** were knocked offline. These web sites were not accessible for the period the attacks lasted. A Distributed Denial of Service (DDOS) attack on Dyn - a domain name server company -  affected the online availability of these popular platforms.

---

## How did it happen?

Investigations about the recent DDOS attacks primarily revolved around **Internet of Things(IoT)**. It was revealed that several cameras, digital video recorders(DVRs) were hacked to create a massive botnet that struck Dyn with lots of traffic, about a trillion bits of data per second. These cameras and devices were vulnerable because they used default and common guessable passwords.

The attack on Dyn came from tens of millions of IP addresses according to the formal statement that was released on Dyn's website. The botnet that invoked the attack looks for smart home and **Internet of things** devices and transforms them into bots to use in cyberattacks. It was also discovered that one of the reasons this was so easily done was that most IoT devices still use the default username and password combination that they were shipped with. An example of a common username is `root`. These credentials are easy to find on the Internet, and were probably used to compromise thousands of devices with minimal effort.

## How could it have been prevented?

It is not new that in the **Internet of things** world, a lot of default and guessable passwords are used for these devices. In short, it's been a thing of concern for a long time that a lot of these devices are not well secured. For instance, several security cameras such as the one produced by Hangzhou XiongMai Technologies (XM) have a web app which requires a username and password to gain access to. But according to Wikholm, it's actually possible to bypass the login process by providing the IP address of a target device and adding "DVR.htm" to the end. These simple steps shown below will go a long way in preventing a lot of the cyber attacks happening frequently.

* Always change default passwords - Most of these devices hardcode the default passwords, so in most cases it would involve a firmware rewrite from the manufacturer. Companies responsible for creating these devices can provide an over-the-air update capability to enable the change from default to a complex username and password combination. In cases where the default passwords can be changed easily, please change it as soon as you purchase the device.
* Brute Force Protection - A certain limit can be set on failed login attempts on a device. If it exceeds a certain number, you can block the user!
* Change passwords frequently - The more devices, apps and systems get hacked, the likelihood that your password is leaked increases. Make a habit of frequently changing your passwords. More details can be found [here](https://auth0.com/blog/avoiding-password-reuse-attacks/)

## How can Auth0 help secure IoT?

Here at Auth0, we conducted a survey about both developer and consumer sentiments when it comes to the state of IoT security and what people think about the future. This very interesting [post](https://auth0.com/blog/surprised-turns-out-consumers-dont-trust-iot-security/) gives full details about the survey.

![Do you believe IoT devices are secure](https://cdn.auth0.com/blog/iot-survey/do-you-believe-iot-devices-are-secure-2.png)

![Do you trust your personal data to IoT devices](https://cdn.auth0.com/blog/iot-survey/do-you-trust-your-personal-data-to-iot-devices.png)

You can use **Auth0** to simplify the implementation of your identity security. Auth0 provides the following:

- Can function as your authentication server, providing you with secure Json Web Tokens (JWTs)
- Keeps you up to date on the latest security vulnerabilities
- Provides [passwordless](https://auth0.com/passwordless) authentication, thus removing the vulnerabilities involved with hacked passwords.
- Provides [Anomaly Detection](https://auth0.com/learn/anomaly-detection/)
- Provides [Breached Password](https://auth0.com/breached-passwords) detection

## Conclusion

Cyber attacks are becoming the order of the day and many companies that develop IoT devices constantly think about user experience before security. Experts are concerned about the security of IoT devices for a long time, but nobody took action to improve that. Security should be *first-class* when dealing with connected devices and any type of application. Now that the world witnessed what lack of security in connected devices can do, it is important that manufacturers of IoT devices and users start taking security seriously to prevent similar or even worst attacks in the future.

{% include tweet_quote.html quote_text="Security should be first-class when dealing with connected devices and any type of application!" %}


text:
namespace Client
{
    partial class AddANewPerson
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle();
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle();
            this.dataGridView_users = new System.Windows.Forms.DataGridView();
            this.LogoColumn = new System.Windows.Forms.DataGridViewImageColumn();
            this.NameUser = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.label1 = new System.Windows.Forms.Label();
            this.button2 = new System.Windows.Forms.Button();
            this.button1 = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView_users)).BeginInit();
            this.SuspendLayout();
            //
            // dataGridView_users
            //
            this.dataGridView_users.AllowUserToAddRows = false;
            this.dataGridView_users.AllowUserToDeleteRows = false;
            dataGridViewCellStyle9.BackColor = System.Drawing.Color.White;
            dataGridViewCellStyle9.ForeColor = System.Drawing.Color.Black;
            dataGridViewCellStyle9.SelectionBackColor = System.Drawing.Color.WhiteSmoke;
            dataGridViewCellStyle9.SelectionForeColor = System.Drawing.Color.Black;
            this.dataGridView_users.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle9;
            this.dataGridView_users.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText;
            this.dataGridView_users.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
            this.dataGridView_users.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView_users.ColumnHeadersVisible = false;
            this.dataGridView_users.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.LogoColumn,
            this.NameUser});
            this.dataGridView_users.Location = new System.Drawing.Point(-2, 20);
            this.dataGridView_users.Name = "dataGridView_users";
            this.dataGridView_users.ReadOnly = true;
            this.dataGridView_users.RowHeadersVisible = false;
            this.dataGridView_users.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            dataGridViewCellStyle10.BackColor = System.Drawing.Color.White;
            dataGridViewCellStyle10.ForeColor = System.Drawing.Color.Black;
            dataGridViewCellStyle10.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            dataGridViewCellStyle10.SelectionForeColor = System.Drawing.Color.Black;
            this.dataGridView_users.RowsDefaultCellStyle = dataGridViewCellStyle10;
            this.dataGridView_users.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dataGridView_users.Size = new System.Drawing.Size(390, 185);
            this.dataGridView_users.TabIndex = 9;
            //
            // LogoColumn
            //
            this.LogoColumn.HeaderText = "Logo";
            this.LogoColumn.MinimumWidth = 25;
            this.LogoColumn.Name = "LogoColumn";
            this.LogoColumn.ReadOnly = true;
            this.LogoColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False;
            this.LogoColumn.Width = 25;
            //
            // NameUser
            //
            this.NameUser.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
            this.NameUser.HeaderText = "User";
            this.NameUser.Name = "NameUser";
            this.NameUser.ReadOnly = true;
            this.NameUser.Width = 5;
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(13, 4);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(273, 13);
            this.label1.TabIndex = 10;
            this.label1.Text = "Choose person that you want to add to this conversation";
            //
            // button2
            //
            this.button2.Image = global::Client.Properties.Resources.cross;
            this.button2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.button2.Location = new System.Drawing.Point(183, 211);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(205, 23);
            this.button2.TabIndex = 12;
            this.button2.Text = "Cancel";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            //
            // button1
            //
            this.button1.Image = global::Client.Properties.Resources.tick;
            this.button1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.button1.Location = new System.Drawing.Point(-2, 211);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(179, 23);
            this.button1.TabIndex = 11;
            this.button1.Text = "OK";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // AddANewPerson
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(385, 236);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.dataGridView_users);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
            this.Name = "AddANewPerson";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Add a new person into a conversation";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView_users)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.DataGridView dataGridView_users;
        private System.Windows.Forms.DataGridViewImageColumn LogoColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn NameUser;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button1;
    }
}


text:
@interface NSData (XMPP)

- (NSData *)md5Digest;

- (NSData *)sha1Digest;

- (NSString *)hexStringValue;

- (NSString *)base64Encoded;
- (NSData *)base64Decoded;

@end


text:
import re
from collections import namedtuple
from datetime import date, datetime
from decimal import Decimal
from typing import Any, Union

from django.core.exceptions import ValidationError
from django.db.models import Model, QuerySet
from django.utils.functional import cached_property, lazy
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from schwifty.exceptions import InvalidAccountCode
from schwifty.iban import IBAN

from ..conf import settings
from ..utils import currency, paragraph

Price = Union[Decimal, int]

class PaymentStatusMixin:
    price: Price
    discount: Price
    received: Price
    returned: Price
    amount_due: Price
    overdue: Price
    overpaid: Price

    @property
    def paid(self) -> Price:
        return self.received - self.returned

    @property
    def receivable(self) -> Price:
        return self.price - self.discount

    @property
    def balance(self) -> Price:
        return self.paid - self.receivable

    @property
    def color(self) -> str:
        if self.overdue:
            return settings.LEPRIKON_COLOR_OVERDUE
        if self.amount_due:
            return settings.LEPRIKON_COLOR_NOTPAID
        if self.overpaid:
            return settings.LEPRIKON_COLOR_OVERPAID
        return settings.LEPRIKON_COLOR_PAID

    @property
    def amount_due_color(self) -> str:
        if self.overdue:
            return settings.LEPRIKON_COLOR_OVERDUE
        if self.amount_due:
            return settings.LEPRIKON_COLOR_NOTPAID
        return settings.LEPRIKON_COLOR_PAID

    @property
    def overpaid_color(self) -> str:
        if self.overpaid:
            return settings.LEPRIKON_COLOR_OVERPAID
        return settings.LEPRIKON_COLOR_PAID

    @property
    def title(self) -> str:
        titles = []
        if self.amount_due and (self.amount_due != self.overdue):
            titles.append(_("amount due {}").format(currency(self.amount_due)))
        if self.overdue:
            titles.append(_("overdue {}").format(currency(self.overdue)))
        if self.overpaid:
            titles.append(_("{} overpaid").format(currency(self.overpaid)))
        if self.balance == 0:
            if self.receivable:
                titles.append(_("paid"))
            else:
                titles.append(_("payment not requested"))
        elif self.balance < 0 and not self.amount_due:  # self.due_from > self.current_date:
            titles.append(_("payment not requested yet"))
        return ", ".join(map(str, titles))

    def __xrepr__(self) -> str:
        return (
            "{type_name}(price={price}, discount={discount}, received={received}, returned={returned}, "
            "balance={balance}, amount_due={amount_due}, overdue={overdue}, overpaid={overpaid})".format(
                type_name=type(self).__name__,
                price=self.price,
                discount=self.discount,
                received=self.received,
                returned=self.returned,
                balance=self.balance,
                amount_due=self.amount_due,
                overdue=self.overdue,
                overpaid=self.overpaid,
            )
        )

    def __add__(self, other):
        return PaymentStatusSum(
            price=self.price + (other and other.price),
            discount=self.discount + (other and other.discount),
            received=self.received + (other and other.received),
            returned=self.returned + (other and other.returned),
            amount_due=self.amount_due + (other and other.amount_due),
            overdue=self.overdue + (other and other.overdue),
            overpaid=self.overpaid + (other and other.overpaid),
        )

    __radd__ = __add__

class PaymentStatus(
    PaymentStatusMixin,
    namedtuple(
        "_PaymentsStatus",
        ["price", "discount", "explanation", "received", "returned", "current_date", "due_from", "due_date"],
    ),
):
    explanation: str
    current_date: date
    due_from: date
    due_date: date

    @property
    def amount_due(self) -> Price:
        return max(self.receivable - self.paid, 0) if self.due_from and self.due_from <= self.current_date else 0

    @property
    def overdue(self) -> Price:
        return self.amount_due if self.due_date and self.due_date < self.current_date else 0

    @property
    def overpaid(self) -> Price:
        return max(self.balance, 0)

    def __str__(self) -> str:
        return format_html(
            '{balance}',
            color=self.color,
            balance=currency(self.balance),
            title=self.title,
        )

class PaymentStatusSum(
    PaymentStatusMixin,
    namedtuple(
        "_PaymentStatusSum",
        ["price", "discount", "received", "returned", "amount_due", "overdue", "overpaid"],
    ),
):
    pass

class BankAccount(IBAN):
    czech_bban_regex = re.compile(r"(([0-9]{1,6})\s?-\s?)?([0-9]{1,10})\s?/\s?([0-9]{4})")
    czech_bban_weights = (1, 2, 4, 8, 5, 10, 9, 7, 3, 6)

    def _validate_czech(self, part: str) -> bool:
        check = 0
        for i, n in enumerate(reversed(part)):
            check += int(n) * self.czech_bban_weights[i]
        if check % 11:
            raise InvalidAccountCode()

    def __init__(self, bank_account: str):
        match = self.czech_bban_regex.match(bank_account)
        if match:
            x, prefix, account, bank_code = match.groups()
            self._validate_czech(prefix or "")
            self._validate_czech(account)
            account_code = (prefix or "").zfill(6) + account.zfill(10)
            bank_account = f"CZ??{bank_code}{account_code}"
        super().__init__(bank_account)

    @cached_property
    def account_prefix(self):
        return self.account_code[:6].lstrip("0")

    @cached_property
    def account_number(self):
        return self.account_code[6:].lstrip("0")

    def __str__(self):
        if self.country_code == "CZ":
            return "%s%s%s/%s" % (
                self.account_prefix,
                self.account_prefix and "-",
                self.account_number,
                self.bank_code,
            )
        else:
            return self.formatted

def parse_bank_account(bank_account: Any) -> BankAccount:
    if isinstance(bank_account, BankAccount):
        return bank_account
    if isinstance(bank_account, IBAN):
        return BankAccount(bank_account.compact)
    if not isinstance(bank_account, str):
        bank_account = str(bank_account)
    try:
        return BankAccount(bank_account)
    except ValueError:
        raise ValidationError(
            message=_("Enter a valid account number."),
            code="invalid",
        )

def generate_variable_symbol(registration):
    # get base variable symol from the configured expression
    variable_symbol = eval(settings.LEPRIKON_VARIABLE_SYMBOL_EXPRESSION, {"reg": registration})

    # add check digit
    odd_sum = 0
    even_sum = 0
    for i, char in enumerate(str(variable_symbol)):
        if i % 2:
            even_sum += int(char)
        else:
            odd_sum += int(char)
    check_digit = (odd_sum * 3 + even_sum) % 10
    return variable_symbol * 10 + check_digit

def help_text_with_html_default(help_text, html_default):
    keep_empty = paragraph(_("Keep empty to use default value:"))
    return mark_safe(
        "{}{}{}".format(
            paragraph(help_text),
            keep_empty,
            html_default,
        )
        if help_text
        else "{}{}".format(
            keep_empty,
            html_default,
        )
    )

lazy_help_text_with_html_default = lazy(help_text_with_html_default, str)

def help_text_with_default(help_text, default):
    keep_empty_default = _("Keep empty to use default value: {}").format(default)
    return paragraph("{}\n\n{}".format(help_text, keep_empty_default) if help_text else keep_empty_default)

lazy_help_text_with_default = lazy(help_text_with_default, str)

def change_year(d, year_delta):
    if isinstance(d, date):
        try:
            return date(d.year + year_delta, d.month, d.day)
        except ValueError:
            # handle leap-year
            return date(d.year + year_delta, d.month, d.day - 1)
    else:
        try:
            return datetime(d.year + year_delta, d.month, d.day)
        except ValueError:
            # handle leap-year
            return datetime(d.year + year_delta, d.month, d.day - 1, d.hour, d.minute, d.second)

def shorten(string, length):
    if len(string) <= length:
        return string
    half = length // 2 - 1
    return f"{string[:half]}...{string[half + 3 - length:]}"

def copy_related_objects(target: Model, **kwargs: QuerySet):
    for attr, qs in kwargs.items():
        related_objects = list(qs.all())
        remote_field_name = target._meta.get_field(attr).remote_field.name
        for obj in related_objects:
            obj.pk = None
            setattr(obj, remote_field_name, target)
        qs.model.objects.bulk_create(related_objects)


text:
var charts = function() {

    var BORDER_PADDING = 8;
    var LEGEND_BORDER_PADDING = 5;
    var LEGEND_ROW_GAP_PERC = 20;
    var LABEL_MULT = 1.5;
    var TICK_LABEL_FONT_MULT = 3.5;
    var GROUP_GAP_PERC = 6;
    var BAR_GAP_PERC = 2;
    var FONT_MULT_FOR_BAR_LABEL = 4;
    var MAX_CATEGORY_TICK_NUM = 25;
    var FONT_MULT_FOR_TICK_LABEL = 6;

    var IS_STACKED = false;

    var AXIS_UNITS_ENABLED        = true;
    var XAXIS_TICKS_ENABLED       = false;
    var XAXIS_TICK_LABELS_ENABLED = false;
    var YAXIS_TICKS_ENABLED       = true;
    var YAXIS_TICK_LABELS_ENABLED = true;
    var GRID_LINES_ENABLED        = true;

    var FONT_FAMILY                = 'Arial';
    var DEFAULT_FONT_SIZE          = 10;
    var MAIN_TITLE_FONT_SIZE       = 1.4 * DEFAULT_FONT_SIZE;
    var SUB_TITLE_FONT_SIZE        = 1.3 * DEFAULT_FONT_SIZE;
    var AXIS_TITLE_FONT_SIZE       = 1.3 * DEFAULT_FONT_SIZE;
    var AXIS_UNITS_FONT_SIZE       = 1.2 * DEFAULT_FONT_SIZE;
    var AXIS_TICK_LABEL_FONT_SIZE  =       DEFAULT_FONT_SIZE;

    var AXIS_STROKE_WIDTH        = 2;
    var AXIS_TICK_NUM            = 5;
    var AXIS_TICK_LENGTH         = 4;
    var GRID_LINES_STROKE_WIDTH  = 1;

    var TITLE_COLOR           = 'Black';
    var AXIS_COLOR            = 'Black';
    var AXIS_TITLE_COLOR      = 'Black';
    var AXIS_TICK_COLOR       = 'Black';
    var AXIS_TICK_LABEL_COLOR = 'Black';
    var GRID_LINES_COLOR      = 'LightGray';
    var SERIES_COLORS = [ 'DarkRed',   'DarkGreen',    'DarkBlue',
                          'Tomato',    'Orange',       'Magenta',
                          'Salmon',    'Gold',         'DeepSkyBlue',
                          'FireBrick', 'Khaki',        'DeepPink',
                          'Plum',      'LemonChiffon', 'Lavender' ];

    // For Bar Charts

    var BAR_LABEL_FONT_SIZE = DEFAULT_FONT_SIZE;
    var BAR_LABEL_COLOR = 'Black';

    // For Legend

    var LEGEND_ENABLED   = false;
    var LEGEND_WIDTH     = 200;
    var LEGEND_BOX_SIZE  = 16;
    var LEGEND_FONT_SIZE = DEFAULT_FONT_SIZE;

    function setAttribute(obj, config, attrName, defaultValue) {
        if (config.hasOwnProperty(attrName)) {
            obj[attrName] = config[attrName];
        } else {
            obj[attrName] = defaultValue;
        }
    }

    function updateAttribute(obj, config, attrName) {
        if (config.hasOwnProperty(attrName)) {
            obj[attrName] = config[attrName];
        }
    }

    function sizeArray(array, desiredLength, createFunc, disposeFunc) {
        while (array.length < desiredLength) {
            array.push(createFunc(array.length));
        }
        while (array.length > desiredLength) {
            var item = array.pop();
            disposeFunc(item);
        }
    }

    // orientation : 'x', 'y'
    // type        : 'category' (for x), 'left' (for y), 'right' (for y)
    function createAxis(chart, config, orientation, type) {
        var axis = { };

        setAttribute(axis, config, 'title',     null);
        setAttribute(axis, config, 'formatter', null);

        setAttribute(axis, config, 'unitsEnabled', AXIS_UNITS_ENABLED);
        if (orientation == 'x') {
            setAttribute(axis, config, 'ticksEnabled', XAXIS_TICKS_ENABLED);
            setAttribute(axis, config, 'tickLabelsEnabled',
                         XAXIS_TICK_LABELS_ENABLED);
        } else {
            setAttribute(axis, config, 'ticksEnabled', YAXIS_TICKS_ENABLED);
            setAttribute(axis, config, 'tickLabelsEnabled',
                         YAXIS_TICK_LABELS_ENABLED);
        }

        setAttribute(axis, config, 'gridLinesEnabled',  false);

        setAttribute(axis, config, 'fontFamily',        FONT_FAMILY);
        setAttribute(axis, config, 'titleFontSize',     AXIS_TITLE_FONT_SIZE);
        setAttribute(axis, config, 'unitsFontSize',     AXIS_UNITS_FONT_SIZE);
        setAttribute(axis, config, 'tickLabelFontSize', AXIS_TICK_LABEL_FONT_SIZE);

        setAttribute(axis, config, 'strokeWidth',          AXIS_STROKE_WIDTH);
        setAttribute(axis, config, 'tickNum',              AXIS_TICK_NUM);
        setAttribute(axis, config, 'tickLength',           AXIS_TICK_LENGTH);
        setAttribute(axis, config, 'gridLinesStrokeWidth', GRID_LINES_STROKE_WIDTH);

        setAttribute(axis, config, 'axisColor',       AXIS_COLOR);
        setAttribute(axis, config, 'titleColor',      AXIS_TITLE_COLOR);
        setAttribute(axis, config, 'unitsColor',      AXIS_TITLE_COLOR);
        setAttribute(axis, config, 'tickColor',       AXIS_TICK_COLOR);
        setAttribute(axis, config, 'tickLabelColor',  AXIS_TICK_LABEL_COLOR);
        setAttribute(axis, config, 'gridLinesColor',  GRID_LINES_COLOR);

        if (type == 'category') {
            axis.unitsEnabled = false;
            axis.gridLinesEnabled = false;
            axis.tickNum = 0;
        }

        function updateLabels() {
            if (axis.title != null) {
                axis.titleLabel.tSetText(axis.title);
            }
        }

        function createTickLine() {
            return chart.createLine(axis.strokeWidth, axis.tickColor);
        }

        var tickLabelAnchor = null;
        var tickLabelShift = null;
        if (orientation == 'x') {
            tickLabelAnchor = 'middle';
            tickLabelShift = 'sub';
        } else {
            tickLabelAnchor = (type == 'left') ? 'end' : 'start';
            tickLabelShift = 'baseline';
        }

        function createTickLabel() {
            return chart.createLabel(axis.tickLabelFontSize,
                                     axis.tickLabelColor,
                                     tickLabelAnchor, tickLabelShift);
        }

        function sizeTickArrays(num, labelNum) {
            if (labelNum == null) {
                labelNum = num;
            }
            if (axis.ticksEnabled) {
                sizeArray(axis.tickLines, num,
                          function(index) { return createTickLine(); },
                          function(line) { chart.removeObj(line); });

                if (axis.tickLabelsEnabled) {
                    sizeArray(axis.tickLabels, labelNum,
                              function(index) { return createTickLabel(); },
                              function(label) { chart.removeObj(label); });
                }
            }
        }

        function init() {
            var shift = (orientation == 'x') ? 'baseline' : 'sub';
            axis.axisLine = chart.createLine(axis.strokeWidth, axis.axisColor);
            if (axis.title != null) {
                axis.titleLabel = chart.createLabel(axis.titleFontSize,
                                                    axis.titleColor,
                                                    'middle', shift);
            }
            if (axis.unitsEnabled) {
                axis.unitsLabel = chart.createLabel(axis.unitsFontSize,
                                                    axis.unitsColor,
                                                    'middle', shift);
            }

            if (axis.ticksEnabled) {
                axis.tickLines = [ ];
                if (axis.tickLabelsEnabled) {
                    axis.tickLabels = [ ];
                }

                if (type != 'category') {
                    sizeTickArrays(axis.tickNum + 1);
                }
            }
            if (axis.gridLinesEnabled) {
                axis.gridLines = [ ];
                for (var i = 1; i <= axis.tickNum; i += 1) {
                    axis.gridLines[i] = chart.createLine(axis.gridLinesStrokWidth,
                                                        axis.gridLinesColor);
                }
            }

            updateLabels();
        }

        function calcSizes(curr) {
            var mult = (orientation == 'x' || type == 'right') ? -1 : 1;

            if (axis.title != null) {
                axis.titlePos = curr;
                curr += mult * LABEL_MULT * axis.titleFontSize;
            }
            if (axis.unitsEnabled) {
                axis.unitsPos = curr;
                curr += mult * LABEL_MULT * axis.unitsFontSize;
            }
            if (axis.ticksEnabled) {
                if (axis.tickLabelsEnabled) {
                    if (orientation == 'x') {
                        curr += mult * LABEL_MULT * axis.tickLabelFontSize;
                    } else {
                        curr += mult * TICK_LABEL_FONT_MULT * axis.tickLabelFontSize;
                    }
                }
                curr += mult * 2 * axis.tickLength;
            }

            return curr;
        }

        function resize() {
            if (orientation == 'x') {
                axis.axisLine.tSetLimits(chart.toChartX(0),
                                         chart.toChartY(0),
                                         chart.toChartX(1),
                                         chart.toChartY(0));
            } else {
                var x = 0;
                if (type == 'right') {
                    x = 1;
                }
                axis.axisLine.tSetLimits(chart.toChartX(x),
                                         chart.toChartY(0),
                                         chart.toChartX(x),
                                         chart.chartAxisY);

            }

            if (axis.title != null) {
                if (orientation == 'x') {
                    axis.titleLabel.tSetPos(chart.toChartX(0.5),
                                            axis.titlePos);
                } else {
                    var rotate = (type == 'left') ? -90 : 90;
                    var x = axis.titlePos;
                    var y = chart.toChartY(0.5);
                    axis.titleLabel.tSetPos(x, y);
                    axis.titleLabel.tTransform(x, y, rotate);
                }
            }

            if (axis.unitsEnabled) {
                if (orientation == 'x') {
                    axis.unitsLabel.tSetPos(chart.toChartX(0.5),
                                            axis.unitsPos);
                } else {
                    var rotate = (type == 'left') ? -90 : 90;
                    var x = axis.unitsPos;
                    var y = chart.toChartY(0.5);
                    axis.unitsLabel.tSetPos(x, y);
                    axis.unitsLabel.tTransform(x, y, rotate);
                }
            }

            if (axis.ticksEnabled || axis.gridLinesEnabled) {
                var mult = (orientation == 'x' || type == 'right') ? 1 : -1;
                var curr = 0;
                var gap = 1 / axis.tickNum;
                for (var i = 0; i <= axis.tickNum; i += 1) {
                    if (orientation == 'x') {
                        if (type != 'category') {
                            // TODO: x-axis ticks / gridlines not supported
                        }
                    } else {
                        var leftX = chart.toChartX(0);
                        var rightX = chart.toChartX(1);
                        var y = chart.toChartY(curr);
                        var axisX = (type == 'left') ? leftX : rightX;
                        var tickLength = mult * axis.tickLength;
                        if (axis.ticksEnabled) {
                            axis.tickLines[i].tSetLimits(axisX,
                                                         y,
                                                         axisX + tickLength,
                                                         y);
                            if (axis.tickLabelsEnabled) {
                                axis.tickLabels[i].tSetPos(axisX + 2 * tickLength,
                                                           y);
                            }
                        }
                        if (axis.gridLinesEnabled && i > 0) {
                            axis.gridLines[i].tSetLimits(leftX, y,
                                                         rightX, y);
                        }
                    }
                    curr += gap;
                }
            }
        }

        function update(adjMax) {
            updateLabels();

            if (axis.unitsEnabled) {
                var unitsLabelStr = '';
                var formatter = axis.formatter;
                if (formatter != null) {
                    unitsLabelStr += ' ' + formatter.unitStr;
                }
                if (adjMax.presentationMultiplier != 1) {
                    unitsLabelStr += ' (x' + adjMax.presentationMultiplier + ')';
                }
                axis.unitsLabel.tSetText(unitsLabelStr);
            }

            if (type != 'category' &&
                axis.ticksEnabled && axis.tickLabelsEnabled) {
                var num = axis.tickNum;
                var fixedDigits = adjMax.fixedDigits;
                var gap = adjMax.presentationMax / num;
                var curr = 0;
                for (var i = 0; i <= num; i += 1) {
                    var labelStr = null;
                    if (fixedDigits != 0) {
                        labelStr = curr.toFixed(fixedDigits);
                    } else {
                        labelStr = String(curr);
                    }
                    axis.tickLabels[i].tSetText(labelStr);
                    curr += gap;
                }
            }
        }

        function updateAttributes(config) {
            updateAttribute(axis, config, 'title');
            updateAttribute(axis, config, 'formatter');

            updateLabels();
        }

        function updateCategoryXAxis(tickXs, labels) {
            if (axis.ticksEnabled) {
                var num = tickXs.length;
                if (num > MAX_CATEGORY_TICK_NUM) {
                    num = 0;
                }
                var labelNum = num;
                if (FONT_MULT_FOR_TICK_LABEL * axis.tickLabelFontSize >
                    chart.chartWidth / num) {
                    labelNum = 0;
                }
                if (labels == null) {
                    labelNum = 0;
                }
                sizeTickArrays(num, labelNum);

                var tickLength = axis.tickLength;
                for (var i = 0; i < num; i += 1) {
                    var x = chart.toChartX(tickXs[i]);
                    var y = chart.toChartY(0);
                    axis.tickLines[i].tSetLimits(x, y, x, y + tickLength);
                    if (axis.tickLabelsEnabled) {
                        if (labels != null && i < labelNum) {
                            axis.tickLabels[i].tSetPos(x, y + 2 * tickLength);
                            axis.tickLabels[i].tSetText(labels[i]);
                        }
                    }
                }
            }
        }

        function bringToFront() {
            chart.bringToFront(axis.axisLine);
        }

        init();

        return { formatter           : function() { return axis.formatter; },
                 calcSizes           : calcSizes,
                 resize              : resize,
                 update              : update,
                 updateAttributes    : updateAttributes,
                 updateCategoryXAxis : updateCategoryXAxis,
                 bringToFront        : bringToFront };
    }

    function updateLabels(chart) {
        if (chart.mainTitle != null) {
            chart.mainTitleLabel.tSetText(chart.mainTitle);
        }
        if (chart.subTitle != null) {
            chart.subTitleLabel.tSetText(chart.subTitle);
        }

        chart.seriesNames = [ ];
        chart.seriesYAxes = [ ];
        chart.seriesFormatters = [ ];
        var series = chart.series;
        for (var i = 0; i < chart.seriesNum; i += 1) {
            var yAxis = 0;
            if (series[i].hasOwnProperty('yAxis')) {
                if (series[i].yAxis == 1) {
                    yAxis = 1;
                } else {
                    yAxis = 0;
                }
            }
            chart.seriesNames[i] = series[i].Name;
            chart.seriesYAxes[i] = yAxis;
            var formatter = chart.yAxes[yAxis].formatter();
            chart.seriesFormatters[i] = formatter;
        }

        if (chart.legend != null) {
            chart.legend.update();
        }
    }

    function initAttributes(chart, config) {
        setAttribute(chart, config, 'series',        null);
        chart.series = utils.getArray(chart.series);
        setAttribute(chart, config, 'isStacked',     IS_STACKED);

        setAttribute(chart, config, 'xAxisConfig',  null);
        setAttribute(chart, config, 'yAxis0Config', null);
        setAttribute(chart, config, 'yAxis1Config', null);

        setAttribute(chart, config, 'mainTitle', null);
        setAttribute(chart, config, 'subTitle',  null);

        setAttribute(chart, config, 'borderPadding', BORDER_PADDING);

        setAttribute(chart, config, 'fontFamily',        FONT_FAMILY);
        setAttribute(chart, config, 'mainTitleFontSize', MAIN_TITLE_FONT_SIZE);
        setAttribute(chart, config, 'subTitleFontSize',  SUB_TITLE_FONT_SIZE);

        setAttribute(chart, config, 'mainTitleColor', TITLE_COLOR);
        setAttribute(chart, config, 'subTitleColor',  TITLE_COLOR);
        setAttribute(chart, config, 'seriesColors',   SERIES_COLORS);

        // For Legend
        setAttribute(chart, config, 'legendEnabled',  LEGEND_ENABLED);
        setAttribute(chart, config, 'legendWidth',    LEGEND_WIDTH);
        setAttribute(chart, config, 'legendBoxSize',  LEGEND_BOX_SIZE);
        setAttribute(chart, config, 'legendFontSize', LEGEND_FONT_SIZE);

        // For Bar Charts
        setAttribute(chart, config, 'barLabelFontSize', BAR_LABEL_FONT_SIZE);
        setAttribute(chart, config, 'barLabelColor',    BAR_LABEL_COLOR);

        chart.div = toolkit.createDiv();
        chart.svg = svgtoolkit.createSVG(chart.div);
        chart.bgRect = svgtoolkit.createRect(chart.svg);
        chart.bgRect.tSetPos(0, 0);
        chart.bgRect.tSetFillOpacity(0);

        chart.createLabel = function(fontSize, color,
                                     textAnchor, baselineShift) {
            var label = svgtoolkit.createText('', this.svg);
            if (fontSize != null) {
                label.tSetFont(this.fontFamily, fontSize);
            }
            if (color != null) {
                label.tSetFill(color);
            }
            if (textAnchor != null) {
                label.tSetTextAnchor(textAnchor);
            }
            if (baselineShift != null) {

                label.tSetBaselineShift(baselineShift);
            }
            return label;
        }

        chart.createLine = function(strokeWidth, color) {
            var line = svgtoolkit.createLine(null, null, null, null, this.svg);
            line.tSetStroke(color, strokeWidth);
            return line;
        }

        chart.createRect = function(color) {
            var rect = svgtoolkit.createRect(this.svg);
            rect.tSetFill(color);
            return rect;
        }

        chart.removeObj = function(obj) {
            this.svg.removeChild(obj);
        }

        chart.chartWidth = 0;
        chart.chartHeight = 0;

        // 0 <= x <= 1
        chart.toChartX = function(x) {
            return chart.chartX + x * chart.chartWidth;
        }

        // 0 <= y <= 1
        chart.toChartY = function(y) {
            return chart.chartY + (1 - y) * chart.chartHeight;
        }

        // 0 <= width <= 1
        chart.toChartWidth = function(width) {
            return width * chart.chartWidth;
        }

        // 0 <= height <= 1
        chart.toChartHeight = function(height) {
            return height * chart.chartHeight;
        }

        chart.max    = [    0,    0 ];
        chart.adjMax = [ null, null ];

        chart.bringToFront = function(objs) {
            objs = utils.getArray(objs);
            for (var i = 0; i < objs.length; i += 1) {
                var obj = objs[i];
                if (obj != null) {
                    this.svg.removeChild(obj);
                    this.svg.appendChild(obj);
                }
            }
        }
    }

    function updateAttributes(chart, config) {
        updateAttribute(chart, config, 'series');
        chart.series = utils.getArray(chart.series);
        updateAttribute(chart, config, 'mainTitle');
        updateAttribute(chart, config, 'subTitle');

        if (chart.xAxis != null && config.hasOwnProperty('xAxisConfig')) {
            chart.xAxis.updateAttributes(config.xAxisConfig);
        }
        if (chart.yAxes[0] != null && config.hasOwnProperty('yAxis0Config')) {
            chart.yAxes[0].updateAttributes(config.yAxis0Config);
        }
        if (chart.yAxes[1] != null && config.hasOwnProperty('yAxis1Config')) {
            chart.yAxes[1].updateAttributes(config.yAxis1Config);
        }

        for (var i = 0; i < chart.seriesNum; i += 1) {
            var yAxis = chart.seriesYAxes[i];
            var formatter = chart.yAxes[yAxis].formatter();
            chart.seriesFormatters[i] = formatter;
        }

        updateLabels(chart);
    }

    function createLegend(chart) {
        var div = toolkit.createDiv();
        var svg = svgtoolkit.createSVG(div);

        var seriesNum = chart.seriesNum;
        var rowGap = LEGEND_ROW_GAP_PERC * chart.legendBoxSize / 100;
        var height = 2 * LEGEND_BORDER_PADDING +
            seriesNum * chart.legendBoxSize +
            (seriesNum - 1) * rowGap;

        var labels = [ ];

        svg.tSetDims(chart.legendWidth, height);
        var x = LEGEND_BORDER_PADDING;
        var y = LEGEND_BORDER_PADDING;
        for (var i = 0; i < seriesNum; i += 1) {
            var bar = svgtoolkit.createRect(svg);
            bar.tSetFill(chart.seriesColors[i]);
            bar.tSetDims(chart.legendBoxSize, chart.legendBoxSize);
            bar.tSetPos(x, y);

            var labelX = x + 1.5 * chart.legendBoxSize;
            var labelY = y + chart.legendBoxSize;
            var label = svgtoolkit.createText('', svg);
            label.tSetPos(labelX, labelY);
            label.tSetFont(chart.fontFamily, chart.legendFontSize);
            label.tSetTextAnchor('start');
            label.tSetBaselineShift('super');
            labels[i] = label;

            y += chart.legendBoxSize + rowGap;
        }

        function update() {
            for (var i = 0; i < chart.seriesNum; i += 1) {
                labels[i].tSetText(chart.seriesNames[i]);
            }
        }

        return { panel  : div,
                 update : update };
    }

    function initChart(chart, config, xAxisType) {
        initAttributes(chart, config);

        if (chart.mainTitle != null) {
            chart.mainTitleLabel = chart.createLabel(chart.mainTitleFontSize,
                                                     chart.mainTitleColor,
                                                     'middle', 'sub');
        }
        if (chart.subTitle != null) {
            chart.subTitleLabel = chart.createLabel(chart.subTitleFontSize,
                                                    chart.subTitleColor,
                                                    'middle', 'sub');
        }

        chart.xAxis = null;
        chart.yAxes = [ null, null ];
        if (chart.xAxisConfig) {
            chart.xAxis = createAxis(chart, chart.xAxisConfig, 'x', xAxisType);
        }
        if (chart.yAxis0Config) {
            chart.yAxes[0] = createAxis(chart, chart.yAxis0Config, 'y', 'left');
        }
        if (chart.yAxis1Config) {
            chart.yAxes[1] = createAxis(chart, chart.yAxis1Config, 'y', 'right');
        }

        chart.seriesNum = chart.series.length;

        chart.legend = null;
        if (chart.legendEnabled) {
            chart.legend = createLegend(chart);
        }

        updateLabels(chart);
    }

    function resizeChart(chart, totalWidth, totalHeight) {
        chart.svg.tSetDims(totalWidth, totalHeight);
        chart.bgRect.tSetDims(totalWidth, totalHeight);

        var startX = chart.borderPadding;
        var startY = chart.borderPadding;
        var endX = totalWidth - chart.borderPadding;
        var endY = totalHeight - chart.borderPadding;

        var mainTitleY = 0;
        var subTitleY = 0;
        var yAxisTopY = 0;

        if (chart.mainTitle != null) {
            mainTitleY = startY;
            startY += LABEL_MULT * chart.mainTitleFontSize;
        }
        if (chart.subTitle != null) {
            subTitleY = startY;
            startY += LABEL_MULT * chart.subTitleFontSize;
        }
        yAxisTopY = startY;
        startY += LABEL_MULT * chart.barLabelFontSize;

        if (chart.xAxis != null) {
            endY = chart.xAxis.calcSizes(endY);
        }
        if (chart.yAxes[0] != null) {
            startX = chart.yAxes[0].calcSizes(startX);
        }
        if (chart.yAxes[1] != null) {
            endX = chart.yAxes[1].calcSizes(endX);
        }

        chart.chartX = startX;
        chart.chartY = startY;
        chart.chartAxisY = yAxisTopY;
        chart.chartWidth = endX - startX;
        chart.chartHeight = endY - startY;

        if (chart.mainTitle != null) {
            chart.mainTitleLabel.tSetPos(totalWidth / 2, mainTitleY);
        }
        if (chart.subTitle != null) {
            chart.subTitleLabel.tSetPos(totalWidth / 2, subTitleY);
        }
        if (chart.xAxis != null) {
            chart.xAxis.resize();
        }
        if (chart.yAxes[0] != null) {
            chart.yAxes[0].resize();
        }
        if (chart.yAxes[1] != null) {
            chart.yAxes[1].resize();
        }
    }

    function calculateAdjustedMax(max) {
        if (max == null) {
            return null;
        }

        var curr = max;
        var factor = 1;
        var iters = 0;
        if (max > 0) {
            while (curr < 1 || curr > 10) {
                if (curr < 1) {
                    curr *= 10;
                    factor /= 10;
                } else {
                    curr /= 10;
                    factor *= 10;
                }
                iters += 1;
            }
        }

        if (curr <= 5) {
            curr = 5;
        } else {
            // 5 < curr <= 10
            curr = 10;
        }

        var fixedDigits = iters;
        if (factor >= 1) {
            fixedDigits = 0;
        }
        var adjustedMax = factor * curr;

        var presentationMax = adjustedMax;
        var presentationMultiplier = 1;
        if (presentationMax > 1000) {
            presentationMax = presentationMax / 1000;
            presentationMultiplier = 1000;
        }

        return { adjustedMax            : adjustedMax,
                 fixedDigits            : fixedDigits,
                 presentationMax        : presentationMax,
                 presentationMultiplier : presentationMultiplier };
    }

    function transformValue(value, formatter) {
        if (formatter != null) {
            return formatter.transform(value);
        } else {
            return value;
        }
    }

    function formatValue(value, formatter) {
        if (formatter != null) {
            return formatter.format(value);
        } else {
            return String(value);
        }
    }

    function calculateMax(chart, yAxis, seriesData) {
        var seriesNum = chart.seriesNum;

        var data = [ ];
        var formatters = [ ];
        var maxDataLen = 0;
        for (var i = 0; i < seriesNum; i += 1) {
            if (chart.seriesYAxes[i] == yAxis) {
                data.push(seriesData[i]);
                formatters.push(chart.seriesFormatters[i]);
                maxDataLen = Math.max(maxDataLen, seriesData[i].length);
            }
        }

        if (data.length == 0) {
            return null;
        }

        var max = 0;
        if (chart.isStacked) {
            for (var di = 0; di < maxDataLen; di += 1) {
                var sum = 0;
                for (var si = 0; si < data.length; si += 1) {
                    if (di < data[si].length) {
                        var value =
                            transformValue(data[si][di], formatters[si]);
                        sum += value;
                    }
                }
                max = Math.max(max, sum);
            }
        } else {
            for (var si = 0; si < data.length; si += 1) {
                for (var di = 0; di < data[si].length; di += 1) {
                    var value = transformValue(data[si][di], formatters[si]);
                    max = Math.max(max, value);
                }
            }
        }
        return max;
    }

    function updateChart(chart, seriesData) {
        updateLabels(chart);

        for (var i = 0; i < chart.seriesNum; i += 1) {
            seriesData[i] = utils.getArray(seriesData[i]);
        }

        var maxDataLen = 0;
        var dataElemNum = 0;
        for (var i = 0; i < chart.seriesNum; i += 1) {
            var len = seriesData[i].length;
            maxDataLen = Math.max(maxDataLen, len);
            dataElemNum += len;
        }
        chart.maxDataLen = maxDataLen;
        chart.dataElemNum = dataElemNum;

        chart.max[0] = calculateMax(chart, 0, seriesData);
        chart.adjMax[0] = calculateAdjustedMax(chart.max[0]);
        chart.max[1] = calculateMax(chart, 1, seriesData);
        chart.adjMax[1] = calculateAdjustedMax(chart.max[1]);

        if (chart.xAxis != null) {
            // TODO: x-axis updating not supported
        }
        if (chart.yAxes[0] != null) {
            chart.yAxes[0].update(chart.adjMax[0]);
        }
        if (chart.yAxes[1] != null) {
            chart.yAxes[1].update(chart.adjMax[1]);
        }
    }

    function updateCategoryXAxis(chart, tickXs, labels) {
        if (chart.xAxis != null) {
            chart.xAxis.updateCategoryXAxis(tickXs, labels);
        }
    }

    function bringAxesToFront(chart) {
        if (chart.xAxis != null) {
            chart.xAxis.bringToFront();
        }
        if (chart.yAxes[0] != null) {
            chart.yAxes[0].bringToFront();
        }
        if (chart.yAxes[1] != null) {
            chart.yAxes[1].bringToFront();
        }
    }

    // series : [ { Name : 'Series Name', yAxis : 0 (default) | 1 } ]
    function createBarChart(config) {
        var chart = { };

        initChart(chart, config, 'category');

        chart.bars = [ ];
        chart.barLabels = [ ];
        for (var i = 0; i < chart.seriesNum; i += 1) {
            chart.bars[i] = [ ];
        }

        function resize(totalWidth, totalHeight) {
            resizeChart(chart, totalWidth, totalHeight);
        }

        function update(seriesData, categoryXAxisLabels) {
            updateChart(chart, seriesData);

            for (var i = 0; i < chart.seriesNum; i += 1) {
                sizeArray(chart.bars[i], seriesData[i].length,
                          function(index) {
                              return chart.createRect(chart.seriesColors[i]);
                          },
                          function(bar) {
                              chart.removeObj(bar);
                          });
            }

            var seriesNum = chart.seriesNum;
            var maxDataLen = chart.maxDataLen;
            var dataElemNum = chart.dataElemNum;
            var groupNum = 0;
            var barNum = 0;
            var verticalBarNum = 0;
            var yAxesUsed = 0;

            if (chart.yAxes[0] != null) {
                yAxesUsed += 1;
            }
            if (chart.yAxes[1] != null) {
                yAxesUsed += 1;
            }
            if (chart.isStacked) {
                groupNum = maxDataLen;
                barNum = maxDataLen;
                verticalBarNum = yAxesUsed * maxDataLen;
            } else {
                groupNum = maxDataLen;
                barNum = seriesNum;
                verticalBarNum = dataElemNum;
            }

            var chartWidth = 1; // normalized
            var groupGapTotal = 0;
            var groupGap = 0;
            if (groupNum > 1 && barNum > 1) {
                groupGapTotal = chartWidth * GROUP_GAP_PERC / 100;
                groupGap = groupGapTotal / (groupNum + 1);
            }

            var barWidth = (chartWidth - groupGapTotal) / verticalBarNum;
            var barGap = barWidth * BAR_GAP_PERC / 100;
            var adjBarWidth = barWidth - 2 * barGap;

            var max = [ ];
            for (var i = 0; i < seriesNum; i += 1) {
                var yAxis = chart.seriesYAxes[i];
                max[i] = chart.adjMax[yAxis].adjustedMax;
            }

            var labelNum = 0;
            var limit = FONT_MULT_FOR_BAR_LABEL * chart.barLabelFontSize;
            if (chart.toChartWidth(barWidth) >= limit) {
                labelNum = verticalBarNum;
            }
            sizeArray(chart.barLabels, labelNum,
                      function(index) {
                          return chart.createLabel(chart.barLabelFontSize,
                                                   chart.barLabelColor,
                                                   'middle', 'super');
                      },
                      function(bar) { chart.removeObj(bar); });

            tickXs = [ ];
            if (chart.isStacked) {
                var x = groupGap;
                var labelIndex = 0;
                for (var di = 0; di < maxDataLen; di += 1) {
                    var groupStartX = x;
                    for (var yAxis = 0; yAxis < 2; yAxis += 1) {
                        if (chart.yAxes[yAxis] == null) continue;

                        var y = 0;
                        var sum = 0;
                        var barX = x + barGap;
                        for (var si = seriesNum - 1; si >= 0; si -= 1) {
                            if (chart.seriesYAxes[si] != yAxis) continue;
                            if (di >= seriesData[si].length) continue;

                            var formatter = chart.seriesFormatters[si];
                            var value = transformValue(seriesData[si][di],
                                                       formatter);
                            sum += value;
                            var barHeight = value / max[si];
                            y += barHeight;

                            chart.bars[si][di].tSetPos(chart.toChartX(barX),
                                                       chart.toChartY(y));
                            chart.bars[si][di].tSetDims(
                                chart.toChartWidth(adjBarWidth),
                                chart.toChartHeight(barHeight));
                        }

                        if (labelNum > 0) {
                            var labelStr = formatValue(sum, formatter);
                            chart.barLabels[labelIndex].tSetText(labelStr);
                            chart.barLabels[labelIndex].tSetPos(
                                chart.toChartX(barX + adjBarWidth / 2),
                                chart.toChartY(y));
                            labelIndex += 1;
                        }

                        x += barWidth;
                    }
                    var deltaX = x - groupStartX;
                    tickXs.push(groupStartX + deltaX / 2);

                    x += groupGap;
                }
            } else {
                var x = groupGap;
                var labelIndex = 0;
                for (var di = 0; di < maxDataLen; di += 1) {
                    var groupStartX = x;
                    for (var si = 0; si < seriesNum; si += 1) {
                        if (di < seriesData[si].length) {
                            var formatter = chart.seriesFormatters[si];
                            var value = transformValue(seriesData[si][di],
                                                       formatter);
                            var barHeight = value / max[si];
                            var barX = x + barGap;
                            var barY = barHeight;

                            chart.bars[si][di].tSetPos(chart.toChartX(barX),
                                                       chart.toChartY(barY));
                            chart.bars[si][di].tSetDims(
                                chart.toChartWidth(adjBarWidth),
                                chart.toChartHeight(barHeight));

                            if (labelNum > 0) {
                                var labelStr = formatValue(value, formatter);
                                chart.barLabels[labelIndex].tSetText(labelStr);
                                chart.barLabels[labelIndex].tSetPos(
                                    chart.toChartX(barX + adjBarWidth / 2),
                                    chart.toChartY(barY));
                            }

                            x += barWidth;
                            labelIndex += 1;
                        }
                    }
                    var deltaX = x - groupStartX;
                    tickXs.push(groupStartX + deltaX / 2);

                    x += groupGap;
                }
            }

            updateCategoryXAxis(chart, tickXs, categoryXAxisLabels);
            bringAxesToFront(chart);
        }

        function updateConfig(config) {
            updateAttributes(chart, config);
        }

        return { panel        : chart.div,
                 legendPanel  : (chart.legend != null) ? chart.legend.panel : null,
                 resize       : resize,
                 update       : update,
                 updateConfig : updateConfig };
    }

    return { createBarChart : createBarChart };

}();


text:
package com.osdu.mapper;

import com.osdu.model.delfi.DelfiSearchResult;
import com.osdu.model.osdu.OsduSearchObject;
import com.osdu.model.osdu.OsduSearchResult;
import org.mapstruct.DecoratedWith;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
@DecoratedWith(SearchResultMapperDecorator.class)
public interface SearchResultMapper {

  /**
   * Maps {@link DelfiSearchResult} to OSDUSearchResult.
   *
   * @param searchResult     to get actual search result data
   * @param osduSearchObject to get additional metedata information to enrich the result. OSDU
   *                         result includes some properties of the original search request like
   *                         facets or requested count/offset.
   * @return result of the search against Delfi Portal in OSDU compliant format.
   */
  @Mapping(source = "searchResult.totalCount", target = "totalHits")
  @Mapping(target = "start", ignore = true)
  OsduSearchResult delfiToOsdu(DelfiSearchResult searchResult,
      OsduSearchObject osduSearchObject);

}


text:
<!doctype HTML>

	<title>Microsoft - História & Evolução</title>
	<link rel="stylesheet" type="text/css" href="css/yuireset.css" media="all">
	<link rel="stylesheet" type="text/css" href="css/theme.css" media="all">

	<meta name="author" content="Antonio">
	<meta http-equiv="content-language" content="pt-PT">
	<meta name="description" content="Trabalho sobre a historia e evolucao da Microsoft. Do Altair Basic, MS-DOS, a passar pelo primeiro Windows ate ao ultmo o Windows 8">
	<meta name="keywords" content="Microsoft Historia Bill Gates Windows MS-DOS Office Inicio Futuro 95 98 7 8 XP">
	<meta name="robots" content="index" />
	<meta charset="UTF-8">

Home

Bill Gates

Cronologia

Inicio

MS-DOS

Windows

95 & 98

2000+

Galeria

Acerca de

Cronologia

História & Evolução - Microsoft

				MS-DOS

Primeiro IBM PC

				Em 1981 a Microsoft consegui o contracto com a IBM para desenvolver um sistema operativo para o novo IBM PC, o qual tinha falhado as negociações
				para ter o CP/M. A Microsoft comprou nessa altura o 86-DOS que era uma copia do CP/M, desenvolveu-o e lançou o MS-DOS, que foi o sistema operativo
				lançado com o novo computador IBM PC, um dos mais importantes da industria dos computadores.

				Nessa mesma altura Steve Jobs visita a Microsoft e mostra a Bill Gates o computador Macintosh. A Microsoft torna-se mais tarde um dos principais vendedores
				de software para a plataforma Mac.

				Por volta desta altura a Microsoft já gerou 24.486.000$ em lucros, e tem 220 empregados.

				MULTIPLAN

Multiplan

				A Microsoft lança em 1983 então mais uma linguagem de programação, o Microsoft C, e lançou também a sua folha de calculo o
				Microsoft MULTIPLAN, que apesar de não vender tanto como o concorrente Lotus 1-2-3, tinha ainda uma parte de mercado relativamente grande.

				Os discos rígidos começam a tornar-se padrão na indústria, com o IBM PC XT a ter uma opção de disco rígido de 10MB.

				Em 1984 com o aparecimento do Mac, a Microsoft lança os novos softwares, o Word, o Chart e o File, e Bill Gates continuou a trabalhar próximo de
				Steve Jobs para o desenvolvimento de mais software para o Mac.

				Mais tarde nesse mesmo ano foi lançado o Microsoft Excel para o Macintosh, que foi um dos programas mais revolucionários da altura, e tornando-se
				uma das principais razões para a venda de computadores da Apple com o sistema Mac.

				Conteúdo

MS-DOS

Multiplan

Copyright © António Ferreira @ ATEC Porto 2013


text:
'use strict';
{
  const sound = new Audio('/_assets/sounds/wakeup.mp3');
  let state = 'off';
  let mode = 'session';
  let timer;

  const createEvents = () => {
    let events = document.getElementsByClassName('action');
    events = Array.from(events);
    // controls = Object.values(controls)
    events.forEach(function (element) {
      element.addEventListener('click', action);
    });
  };

  const action = (e) => {
    const option = e.target.id;
    console.log(option);
    if (option === '7') {
      location.reload();
      return;
    }
    if (state === 'off') {
      switch (option) {
        case '1':
          configTime(option, -1);
          break;
        case '2':
          configTime(option, +1);
          break;
        case '3':
          configTime(option, -1);
          break;
        case '4':
          configTime(option, +1);
          break;
        case '5':
        case '6':
          start();
          break;
      }
    } else if (state === 'on') {
      start();
    }
  };

  const updateClock = () => {
    let now = document.getElementById('clock').innerText.split(':');
    let mins = parseInt(now[0]);
    let secs = parseInt(now[1]);
    if (secs === 0) {
      mins--;
      secs = 59;
    } else if (secs <= 10) {
      secs--;
      secs = '0' + secs;
    } else {
      secs--;
    }
    if (mins < 10) {
      mins = '0' + mins;
    }
    now = mins + ':' + secs;
    document.getElementById('clock').innerText = now;
    checkModeChange(now);
  };

  const checkModeChange = (now) => {
    if (now === '00:00') {
      sound.play();
      let aux;
      if (mode === 'session') {
        mode = 'break';
        aux = document.getElementById('breakMins').innerText;
        aux = aux + ':00';
        document.getElementById('clock').innerText = aux;
        document.getElementById('clock').style.color = 'lightgreen';
      } else {
        mode = 'session';
        aux = document.getElementById('sessionMins').innerText;
        aux = aux + ':00';
        document.getElementById('clock').innerText = aux;
        document.getElementById('clock').style.color = '#ddd';
      }
    }
  };

  const start = () => {
    if (state === 'off') {
      state = 'on';
      document.getElementById('5').style.display = 'none';
      document.getElementById('6').style.display = 'block';
      timer = setInterval(updateClock, 1000);
    } else {
      state = 'off';
      document.getElementById('5').style.display = 'block';
      document.getElementById('6').style.display = 'none';
      clearInterval(timer);
    }
  };

  const configTime = (option, how) => {
    let where = '';
    if (option === '1' || option === '2') {
      where = 'breakMins';
    } else if (option === '3' || option === '4') {
      where = 'sessionMins';
    }
    const old = document.getElementById(where).innerText;
    let result = parseInt(old) + how;
    if (result < 1) {
      result = '01';
    } else if (result < 10) {
      result = '0' + String(result);
    }
    if (where === 'sessionMins') {
      document.getElementById('clock').innerText = result + ':00';
    }
    document.getElementById(where).innerText = result;
  };

  window.addEventListener('load', createEvents);
}


text:
// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>

#include <linux/ethtool.h>
#include <linux/sockios.h>

#include "ethtool.h"

int ethtool_sock_fd;

__attribute__((constructor)) __ethtool_init(){
  ethtool_sock_fd = socket(AF_INET, SOCK_DGRAM, 0);

  if(ethtool_sock_fd < 0){
    fprintf(stderr, "Error: cannot open a socket for ethtool ioctl. Force abort.\n");
    exit(1);
  }
}

int get_port_speed(const char* devname){
  struct ethtool_value ethval;
  struct ethtool_cmd ethcmd;
  struct ifreq ifr;
  int ret;

  memset(&ifr, 0, sizeof(struct ifreq));
  strncpy(ifr.ifr_name, devname, strlen(devname));

  ethcmd.cmd = ETHTOOL_GSET;
  ifr.ifr_data = (caddr_t)&ethcmd;
  ret = ioctl(ethtool_sock_fd, SIOCETHTOOL, &ifr);

  if(ret == -1){
    perror("ioctl(ethtool_sock_fd, SIOCETHTOOL, &ifr)");
    return;
  }

  return ethtool_cmd_speed(&ethcmd);
}

char* get_driver_info(const char* devname){
  struct ethtool_drvinfo drvinfo;
  struct ifreq ifr;
  int ret;

  memset(&ifr, 0, sizeof(struct ifreq));
  strncpy(ifr.ifr_name, devname, strlen(devname));

  drvinfo.cmd = ETHTOOL_GDRVINFO;
  ifr.ifr_data = (caddr_t)&drvinfo;
  ret = ioctl(ethtool_sock_fd, SIOCETHTOOL, &ifr);

  if(ret == -1){
    perror("ioctl(ethtool_sock_fd, SIOCETHTOOL, &ifr)");
    return NULL;
  }

  strdup(drvinfo.driver);
}

/*
  The ioctl called in this function is not an ETHTOOL one,
  but let me just put this here as it can reuse the same socket...
*/
int set_mac_address(unsigned char mac[6], const char* devname){
  struct ifreq ifr;
  int ret;

  strncpy(ifr.ifr_name, devname, IFNAMSIZ);
  ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
  memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);

  ret = ioctl(ethtool_sock_fd, SIOCSIFHWADDR, &ifr);
  if(ret != 0){
    perror("ioctl(ethtool_sock_fd, SIOCSIFHWADDR, &ifr)");
    return -1;
  }

  return 0;
}


text:
<link rel="stylesheet" href="css/jquery-ui.min.css">

<link rel="stylesheet" href="css/chosen.min.css">

<link rel="stylesheet" href="css/pnotify.custom.min.css">

			<form id="radioPresys" class="col-lg-6 col-md-offset-3">
			    <input type="radio" id="factory" name="radioPresys" checked="checked">factory
			    <input type="radio" id="sysupgrade" name="radioPresys">sysupgrade
			</form>

	    		<select data-placeholder="Choose a modell..." class="chosen-select" id="expert_devices" style="width:350px;" tabindex="1">
	    			<option></option>
	        	</select>

				<select data-placeholder="Choose a version..." class="chosen-select" id="expert_version" style="width:100px;" tabindex="2">
	        	</select>

				<select data-placeholder="Choose a branch..." class="chosen-select" id="expert_branch" style="width:350px;" tabindex="3">
	        	</select>

			<button type="button" class="btn btn-default glyphicon glyphicon-download-alt" id="expert_download"> Download </button>