macro generate_abstract_def(signature)
  def {{signature.id}}
    fail "Abstract method \#{{signature.id}} called on #{self.class}"
  end
end

module Generate
  struct View
    property config
    property logger

    generate_abstract_def render
    generate_abstract_def log

    def initialize(@config, @logger)
    end

    def render_with_log
      log
      render
    end
  end

  struct FileView < View
    generate_abstract_def path
    generate_abstract_def to_s(io)
    generate_abstract_def full_path

    def render
      File.write(full_path, to_s)
    end

    def log
      logger.info("File #{full_path}")
    end
  end
end

macro generate_template(name, base, template, path)
  struct {{name.id}} < {{base.id}}
    ecr_file "{{__DIR__.id}}/{{template.id}}"

    def path
      {{path}}
    end
  end
end

Use abstract methods from language

module Generate
  struct View
    property config
    property logger

    abstract def render
    abstract def log

    def initialize(@config, @logger)
    end

    def render_with_log
      log
      render
    end
  end

  struct FileView < View
    abstract def path
    abstract def to_s(io)
    abstract def full_path

    def render
      File.write(full_path, to_s)
    end

    def log
      logger.info("File #{full_path}")
    end
  end
end

macro generate_template(name, base, template, path)
  struct {{name.id}} < {{base.id}}
    ecr_file "{{__DIR__.id}}/{{template.id}}"

    def path
      {{path}}
    end
  end
end


require "json"

module Discordcr
  module REST
    # A response to the Get Gateway REST API call.
    struct GatewayResponse
      JSON.mapping(
        url: String
      )
    end
  end

  struct GatewayPacket
    JSON.mapping(
      op: UInt8,
      d: Nil,
      s: UInt32 | Nil,
      t: String | Nil
    )
  end
end

Use JSON::Any for the payload type in GatewayPacket

require "json"

module Discordcr
  module REST
    # A response to the Get Gateway REST API call.
    struct GatewayResponse
      JSON.mapping(
        url: String
      )
    end
  end

  struct GatewayPacket
    JSON.mapping(
      op: UInt8,
      d: JSON::Any,
      s: UInt32 | Nil,
      t: String | Nil
    )
  end
end


require "http/websocket"

require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = gateway.url
      @websocket = HTTP::WebSocket.new(URI.parse(url))
    end
  end
end

Define a handler method for gateway messages

require "http/websocket"

require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = gateway.url
      @websocket = HTTP::WebSocket.new(URI.parse(url))
    end

    private def on_message(String)
    end
  end
end


# This is the default error serializer generated by Lucky.
# Feel free to customize it in any way you like.
class ErrorSerializer < BaseSerializer
  def initialize(
    @message : String,
    @details : String? = nil,
    @param : String? = nil # If there was a problem with a specific param
  )
  end

  def render
    {message: @message, param: @param, details: @details}
  end
end

Clarify param arg in ErrorSerializer

# This is the default error serializer generated by Lucky.
# Feel free to customize it in any way you like.
class ErrorSerializer < BaseSerializer
  def initialize(
    @message : String,
    @details : String? = nil,
    @param : String? = nil # so you can track which param (if any) caused the problem
  )
  end

  def render
    {message: @message, param: @param, details: @details}
  end
end


require "http/client"

module Discordcr
  module REST
    def request(endpoint_key : Symbol, method : String, url : String | URI, headers : HTTP::Headers | Nil, body : String | Nil)
      headers["Authorization"] = @token
      HTTP::Client.exec(method: method, url: url, headers: headers, body: body, tls: true)
    end
  end
end

Implement the Get Gateway API call

require "http/client"

require "./mappings"

module Discordcr
  module REST
    def request(endpoint_key : Symbol, method : String, url : String | URI, headers : HTTP::Headers | Nil, body : String | Nil)
      headers["Authorization"] = @token
      HTTP::Client.exec(method: method, url: url, headers: headers, body: body, tls: true)
    end

    API_BASE = "https://discordapp.com/api/v6"

    GET = "get"

    def gateway
      response = request(
        :gateway,
        GET,
        API_BASE + "/gateway",
        HTTP::Headers.new,
        nil
      )

      puts response.body

      GatewayResponse.from_json(response.body_io)
    end
  end
end


require "./converters"

module Discord
  module REST
    # A response to the Get Gateway REST API call.
    struct GatewayResponse
      JSON.mapping(
        url: String
      )
    end
  end
end

Add a mapping for the response of the prune count endpoint

require "./converters"

module Discord
  module REST
    # A response to the Get Gateway REST API call.
    struct GatewayResponse
      JSON.mapping(
        url: String
      )
    end

    # A response to the Get Guild Prune Count REST API call.
    struct PruneCountResponse
      JSON.mapping(
        pruned: UInt32
      )
    end
  end
end


module Jennifer::Model
  module OptimisticLocking
    macro with_optimistic_lock(locking_column = lock_version)
      def self.locking_column
        {{locking_column.stringify}}
      end

      def locking_column
        self.class.locking_column
      end

      {% if locking_column != "lock_version" %}
        def lock_version
          {{locking_column}}
        end

        def self._lock_version
          _{{locking_column}}
        end
      {% end %}

      def increase_lock_version!
        self.{{locking_column}} = {{locking_column}} + 1
      end

      def reset_lock_version!
        @{{locking_column}} -= 1
        @{{locking_column}}_changed = false
      end
    end
  end
end

Add documentation for the macro

module Jennifer::Model
  module OptimisticLocking
    # Add optimistic locking to model
    # By default, it uses column `lock_version : Int32` as lock
    # The column used as lock must be type `Int32` or `Int64` and the default value of 0
    # You can use a different column name as lock by passing the column name to the method.
    #
    # ```
    # class MyModel < Jennifer::Model::Base
    #   with_optimistic_lock
    #
    #   mapping(
    #     id: {type: Int32, primary: true},
    #     lock_version: {type: Int32, default: 0},
    #   )
    # end
    # ```
    # Or use a custom column name for the locking column:
    # ```
    # class MyModel < Jennifer::Model::Base
    #   with_optimistic_lock(custom_lock)
    #
    #   mapping(
    #     id: {type: Int32, primary: true},
    #     custom_lock: {type: Int32, default: 0},
    #   )
    # end
    # ```
    macro with_optimistic_lock(locking_column = lock_version)
      def self.locking_column
        {{locking_column.stringify}}
      end

      def locking_column
        self.class.locking_column
      end

      {% if locking_column != "lock_version" %}
        def lock_version
          {{locking_column}}
        end

        def self._lock_version
          _{{locking_column}}
        end
      {% end %}

      def increase_lock_version!
        self.{{locking_column}} = {{locking_column}} + 1
      end

      def reset_lock_version!
        @{{locking_column}} -= 1
        @{{locking_column}}_changed = false
      end
    end
  end
end


require "http/client"

require "./mappings"

module Discordcr
  module REST
    def request(endpoint_key : Symbol, method : String, url : String | URI, headers : HTTP::Headers | Nil, body : String | Nil)
      headers["Authorization"] = @token
      HTTP::Client.exec(method: method, url: url, headers: headers, body: body, tls: true)
    end

    API_BASE = "https://discordapp.com/api/v6"

    GET = "get"

    def gateway
      response = request(
        :gateway,
        GET,
        API_BASE + "/gateway",
        HTTP::Headers.new,
        nil
      )

      puts response.body

      GatewayResponse.from_json(response.body_io)
    end
  end
end

Use a proper SSL context instead of `true`

require "http/client"
require "openssl/ssl/context"

require "./mappings"

module Discordcr
  module REST
    SSL_CONTEXT = OpenSSL::SSL::Context::Client.new

    def request(endpoint_key : Symbol, method : String, url : String | URI, headers : HTTP::Headers | Nil, body : String | Nil)
      HTTP::Client.exec(method: method, url: url, headers: headers, body: body, tls: SSL_CONTEXT)
    end

    API_BASE = "https://discordapp.com/api/v6"

    GET = "get"

    def gateway
      response = request(
        :gateway,
        GET,
        API_BASE + "/gateway",
        HTTP::Headers.new,
        nil
      )

      puts response.body

      GatewayResponse.from_json(response.body_io)
    end
  end
end


require "mysql"
require "pool/connection"
require "http"

macro conn
  env.mysql.connection
end

macro release
  env.mysql.release
end

def mysql_connect(options, capacity = 25, timeout = 0.1)
  Kemal.config.add_handler Kemal::MySQL.new(options, capacity, timeout)
end

class HTTP::Server::Context
  @mysql : ConnectionPool(MySQL::Connection) | Nil
  property! mysql
end

class Kemal::MySQL < HTTP::Handler
  @mysql : ConnectionPool(MySQL::Connection)
  getter mysql

  def initialize(options={} of String => String, capacity = 25, timeout = 0.1)
    @mysql = ConnectionPool.new(capacity: capacity, timeout: timeout) do
      ::MySQL.connect(options["host"], options["user"], options["password"], options["db"], 3306_u16, nil)
    end
  end

  def call(context)
    context.mysql = @mysql
    call_next(context)
  end
end

Fix ConnectionPool(T) error on assigment

require "mysql"
require "pool/connection"
require "http"

macro conn
  env.mysql.connection
end

macro release
  env.mysql.release
end

def mysql_connect(options, capacity = 25, timeout = 0.1)
  Kemal.config.add_handler Kemal::MySQL.new(options, capacity, timeout)
end

class HTTP::Server::Context
  @mysql : ConnectionPool(MySQL::Connection) | Nil
  property! mysql
end

class Kemal::MySQL < HTTP::Handler
  @mysql : ConnectionPool(MySQL::Connection)
  getter mysql

  def initialize(options={} of String => String, capacity = 25, timeout = 0.1)
    @mysql = ConnectionPool(MySQL::Connection).new(capacity: capacity, timeout: timeout) do
      ::MySQL.connect(options["host"], options["user"], options["password"], options["db"], 3306_u16, nil)
    end
  end

  def call(context)
    context.mysql = @mysql
    call_next(context)
  end
end


require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = gateway.url
    end
  end
end

Create a WebSocket from the URL

require "http/websocket"

require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = gateway.url
      @websocket = HTTP::WebSocket.new(URI.parse(url))
    end
  end
end


system "rm -rf test_tables"
system "mkdir test_tables"

module Storage
  module TableManager
    @@tables = {} of String => Table

    def self.find(name)
      if table = @@tables[name]?
        table
      else
        @@tables[name] = Table.create("test_tables/" + name)
      end
    end
  end
end

at_exit do
  system "rm -rf test_tables"
end

Move from system to file_utils

require "file_utils"

FileUtils.rm_rf "test_tables"
FileUtils.mkdir_p "test_tables"

module Storage
  module TableManager
    @@tables = {} of String => Table

    def self.find(name)
      if table = @@tables[name]?
        table
      else
        @@tables[name] = Table.create("test_tables/" + name)
      end
    end
  end
end

at_exit do
  FileUtils.rm_rf "test_tables"
end


require "./environment/**"
require "./support/file_encryptor"

module Amber::Environment
  alias EnvType = String | Symbol

  macro included
    AMBER_ENV = "AMBER_ENV"
    CURRENT_ENVIRONMENT = ENV[AMBER_ENV] ||= "development"
    class_property environment_path : String = "./config/environments/"

    @@settings : Settings?

    def self.settings
      @@settings ||= Loader.new(env.to_s, environment_path).settings
    end

    def self.logger
      settings.logger
    end

    def self.env=(env : EnvType)
      ENV[AMBER_ENV] = env.to_s
      @@settings = Loader.new(env, environment_path).settings
    end

    def self.env
      @@env ||= Env.new(CURRENT_ENVIRONMENT)
    end
  end
end

Move Current Environment to a method

require "./environment/**"
require "./support/file_encryptor"

module Amber::Environment
  alias EnvType = String | Symbol

  macro included
    AMBER_ENV = "AMBER_ENV"
    class_property environment_path : String = "./config/environments/"

    @@settings : Settings?

    def self.settings
      @@settings ||= Loader.new(env.to_s, environment_path).settings
    end

    def self.logger
      settings.logger
    end

    def self.env=(env : EnvType)
      ENV[AMBER_ENV] = env.to_s
      @@settings = Loader.new(env, environment_path).settings
    end

    def self.env
      @@env ||= Env.new(current_environment)
    end

    def self.current_environment
      ENV[AMBER_ENV]? || "development"
    end
  end
end


# #######################################################################
#
# Author: Brian Hood
# Name: Crystal bindings for MonetDB
# Codename: Dagobert I
# Description:
#   Tools library
#
#
# #######################################################################

require "progress"

struct Number
  def times_with_progress(&block)
    bar = ProgressBar.new
    bar.total = self
    bar.incomplete = "."
    bar.complete = "o"
    self.times do |i|
      yield i
      bar.inc
    end
  end

  {% for method in %w(upto downto) %}
    def {{ method.id }}_with_progress(hdl)
      bar = ProgressBar.new
      bar.total = self
      bar.incomplete = "."
      bar.complete = "o"
      self.times do |i|
        yield i
        bar.inc
      end
    end
  {% end %}
end

class Timers
  property? start : Time
  property? finish : Time

  def initialize
    @start = Time.now
    @finish = Time.now
  end

  def start
    @start = Time.now
  end

  def stop
    @finish = Time.now
  end

  def stats
    duration = @finish - @start
    return "Start: #{@start} Finish: #{@finish} Duration: #{duration.to_s}"
  end
end

Fix for upto / downto

# #######################################################################
#
# Author: Brian Hood
# Name: Crystal bindings for MonetDB
# Codename: Dagobert I
# Description:
#   Tools library
#
#
# #######################################################################

require "progress"

struct Number
  def times_with_progress(&block)
    bar = ProgressBar.new
    bar.total = self
    bar.incomplete = "."
    bar.complete = "o"
    self.times do |i|
      yield i
      bar.inc
    end
  end

  {% for method in %w(upto downto) %}
    def {{ method.id }}_with_progress(num)
      bar = ProgressBar.new
      bar.total = self
      bar.incomplete = "."
      bar.complete = "o"
      self.{{ method.id }}(num) do |i|
        yield i
        bar.inc
      end
    end
  {% end %}
end

class Timers
  property? start : Time
  property? finish : Time

  def initialize
    @start = Time.now
    @finish = Time.now
  end

  def start
    @start = Time.now
  end

  def stop
    @finish = Time.now
  end

  def stats
    duration = @finish - @start
    return "Start: #{@start} Finish: #{@finish} Duration: #{duration.to_s}"
  end
end


module Mocks
  module BaseMock
    macro mock(method)
      {% method_name = method.name.stringify %}
      {% method_name = "self.#{method_name.id}" if method.receiver.stringify == "self" %}
      {% method_name = method_name.id %}

      def {{method_name}}({{method.args.argify}})
        %method = ::Mocks::Registry.for(@@__mocks_name).fetch_method({{method_name.stringify}})
        {% if method.args.empty? %}
          %result = %method.call(::Mocks::Registry::ObjectId.build(self))
        {% else %}
          %result = %method.call(::Mocks::Registry::ObjectId.build(self), {{method.args}})
        {% end %}

        if %result.call_original
          previous_def
        else
          if %result.value.is_a?(typeof(previous_def))
            %result.value as typeof(previous_def)
          else
            raise ::Mocks::UnexpectedMethodCall.new(
              {% if method.args.empty? %}
                "#{self.inspect} received unexpected method call {{method_name}}[]"
              {% else %}
                "#{self.inspect} received unexpected method call {{method_name}}#{[{{method.args.argify}}]}"
              {% end %}
            )
          end
        end
      end
    end
  end
end

Add guard statement for @@__mocks_name being nil

module Mocks
  module BaseMock
    macro mock(method)
      {% method_name = method.name.stringify %}
      {% method_name = "self.#{method_name.id}" if method.receiver.stringify == "self" %}
      {% method_name = method_name.id %}

      def {{method_name}}({{method.args.argify}})
        %mock_name = @@__mocks_name
        unless %mock_name
          raise "Assertion failed (mocks.cr): @@__mocks_name can not be nil"
        end

        %method = ::Mocks::Registry.for(%mock_name).fetch_method({{method_name.stringify}})
        {% if method.args.empty? %}
          %result = %method.call(::Mocks::Registry::ObjectId.build(self))
        {% else %}
          %result = %method.call(::Mocks::Registry::ObjectId.build(self), {{method.args}})
        {% end %}

        if %result.call_original
          previous_def
        else
          if %result.value.is_a?(typeof(previous_def))
            %result.value as typeof(previous_def)
          else
            raise ::Mocks::UnexpectedMethodCall.new(
              {% if method.args.empty? %}
                "#{self.inspect} received unexpected method call {{method_name}}[]"
              {% else %}
                "#{self.inspect} received unexpected method call {{method_name}}#{[{{method.args.argify}}]}"
              {% end %}
            )
          end
        end
      end
    end
  end
end


require "./mappings/*"

module Discord
  class Cache
    def initialize(@client : Client)
      @users = Hash(UInt64, User).new
      @channels = Hash(UInt64, Channel).new
    end

    def resolve_user(id : UInt64) : User
      @users.fetch(id) { @users[id] = @client.get_user(id) }
    end

    def resolve_channel(id : UInt64) : Channel
      @channels.fetch(id) { @channels[id] = @client.get_channel(id) }
    end

    def cache(user : User)
      @users[user.id] = user
    end

    def cache(channel : Channel)
      @channels[channel.id] = channel
    end
  end
end

Add support for guild caching

require "./mappings/*"

module Discord
  class Cache
    def initialize(@client : Client)
      @users = Hash(UInt64, User).new
      @channels = Hash(UInt64, Channel).new
      @guilds = Hash(UInt64, Guild).new
    end

    def resolve_user(id : UInt64) : User
      @users.fetch(id) { @users[id] = @client.get_user(id) }
    end

    def resolve_channel(id : UInt64) : Channel
      @channels.fetch(id) { @channels[id] = @client.get_channel(id) }
    end

    def resolve_guild(id : UInt64) : Guild
      @guilds.fetch(id) { @guilds[id] = @client.get_guild(id) }
    end

    def cache(user : User)
      @users[user.id] = user
    end

    def cache(channel : Channel)
      @channels[channel.id] = channel
    end

    def cache(guild : Guild)
      @guilds[guild.id] = guild
    end
  end
end


require "colorize"
require "./lucky_cli"
require "./generators/*"
require "./dev"
require "./ensure_process_runner_installed"

include LuckyCli::TextHelpers

args = ARGV.join(" ")

if ARGV.first? == "dev"
  LuckyCli::Dev.new.call
elsif ARGV.first? == "ensure_process_runner_installed"
  LuckyCli::EnsureProcessRunnerInstalled.new.call
elsif File.exists?("./tasks.cr")
  Process.run "crystal run ./tasks.cr --no-debug -- #{args}",
    shell: true,
    output: STDOUT,
    error: STDERR
elsif ARGV.first? == "init"
  LuckyCli::InitQuestions.run
elsif ["-v", "--version"].includes?(ARGV.first?)
  puts LuckyCli::VERSION
else
  puts <<-MISSING_TASKS_FILE

  #{"Missing tasks.cr file".colorize(:red)}

  Try this...

    #{red_arrow} Change to the directory with the tasks.cr file,
      usually your project root
    #{red_arrow} If this is a new project, run #{"lucky init".colorize(:green)} to
      create a default tasks.cr file

  MISSING_TASKS_FILE
end

Exit with the exit status of the task that ran

require "colorize"
require "./lucky_cli"
require "./generators/*"
require "./dev"
require "./ensure_process_runner_installed"

include LuckyCli::TextHelpers

args = ARGV.join(" ")

if ARGV.first? == "dev"
  LuckyCli::Dev.new.call
elsif ARGV.first? == "ensure_process_runner_installed"
  LuckyCli::EnsureProcessRunnerInstalled.new.call
elsif File.exists?("./tasks.cr")
  exit Process.run(
    "crystal run ./tasks.cr -- #{args}",
    shell: true,
    output: STDOUT,
    error: STDERR
  ).exit_status
elsif ARGV.first? == "init"
  LuckyCli::InitQuestions.run
elsif ["-v", "--version"].includes?(ARGV.first?)
  puts LuckyCli::VERSION
else
  puts <<-MISSING_TASKS_FILE

  #{"Missing tasks.cr file".colorize(:red)}

  Try this...

    #{red_arrow} Change to the directory with the tasks.cr file,
      usually your project root
    #{red_arrow} If this is a new project, run #{"lucky init".colorize(:green)} to
      create a default tasks.cr file

  MISSING_TASKS_FILE
end


require "http/web_socket"

require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = gateway.url
      url += "?v=6&encoding=json"
      @websocket = websocket = HTTP::WebSocket.new(URI.parse(url))
      websocket.on_message(&->on_message(String))
      websocket.on_close(&->on_close(String))
      websocket.run
    end

    private def on_close(message : String)
      # TODO: make more sophisticated
      puts "Closed with: " + message
    end

    private def on_message(message : String)
    end
  end
end

Use the manual initializer for WebSocket

require "http/web_socket"

require "./rest"

module Discordcr
  class Client
    include REST

    def initialize(@token : String, @client_id : UInt64)
    end

    def run
      url = URI.parse(gateway.url)
      @websocket = websocket = HTTP::WebSocket.new(
        host: url.host.not_nil!,
        path: "#{url.path}/?encoding=json&v=6",
        port: 443,
        tls: true
      )

      websocket.on_message(&->on_message(String))
      websocket.on_close(&->on_close(String))
      websocket.run
    end

    private def on_close(message : String)
      # TODO: make more sophisticated
      puts "Closed with: " + message
    end

    private def on_message(message : String)
      puts message
    end
  end
end


ENV["LUCKY_ENV"] = "test"
require "spec"
require "../src/app"
require "./support/**"

Clear db after each test

ENV["LUCKY_ENV"] = "test"
require "spec"
require "../src/app"
require "./support/**"

Spec.after_each do
  LuckyRecord::Repo.truncate
end


require "./converters"

module Discord
  # :nodoc:
  module VWS
    struct IdentifyPacket
      def initialize(server_id, user_id, session_id, token)
        @op = Discord::VoiceClient::OP_IDENTIFY
        @d = IdentifyPayload.new(server_id, user_id, session_id, token)
      end

      JSON.mapping(
        op: Int32,
        d: IdentifyPayload
      )
    end

    struct IdentifyPayload
      def initialize(@server_id, @user_id, @session_id, @token)
      end

      JSON.mapping(
        server_id: UInt64,
        user_id: UInt64,
        session_id: String,
        token: String
      )
    end

    struct SelectProtocolPacket
      def initialize(protocol, data)
        @op = Discord::VoiceClient::OP_SELECT_PROTOCOL
        @d = SelectProtocolPayload.new(protocol, data)
      end

      JSON.mapping(
        op: Int32,
        d: SelectProtocolPayload
      )
    end

    struct SelectProtocolPayload
      def initialize(@protocol, @data)
      end

      JSON.mapping(
        protocol: String,
        data: ProtocolData
      )
    end

    struct ProtocolData
      def initialize(@address, @port, @mode)
      end

      JSON.mapping(
        address: String,
        port: UInt16,
        mode: String
      )
    end

    struct ReadyPayload
      JSON.mapping(
        ssrc: Int32,
        port: Int32,
        modes: Array(String),
        heartbeat_interval: Int32
      )
    end

    struct SessionDescriptionPayload
      JSON.mapping(
        secret_key: Array(UInt8)
      )
    end

    struct SpeakingPacket
      def initialize(speaking, delay)
        @op = Discord::VoiceClient::OP_SPEAKING
        @d = SpeakingPayload.new(speaking, delay)
      end

      JSON.mapping(
        op: Int32,
        d: SpeakingPayload
      )
    end

    struct SpeakingPayload
      def initialize(@speaking, @delay)
      end

      JSON.mapping(
        speaking: Bool,
        delay: Int32
      )
    end

    struct HelloPayload
      JSON.mapping(
        heartbeat_interval: Int32
      )
    end
  end
end


# ac-library.cr by hakatashi https://github.com/google/ac-library.cr
#
# Copyright 2021 Google LLC
#
# 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
#
#      https://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.

# verify-helper: PROBLEM https://judge.yosupo.jp/problem/enumerate_primes

require "./Prime.cr"

n, a, b = read_line.split.map(&.to_i64)
ans = Array(Int64).new(1_000_000_i64)
pi = 0_i64
AtCoder::Prime.each_with_index do |prime, i|
  break if prime > n
  pi += 1
  if i >= b && (i - b) % a == 0
    ans << prime
  end
end

puts "#{pi} #{ans.size}"
puts ans.join(' ')


Add test code for faster matrix multiplication.

require "benchmark"
require "matrix"

def faster_matrix_multiply(a, b)
  raise "Dimensions don't match" unless a.columns.count == b.rows.count
  matrix = Matrix(typeof(a[0] * b[0])).new(a.rows.count, b.columns.count)
  pos = -1
  b_columns = b.columns
  initial_sum = typeof(a[0] * b[0]).cast(0.0)
  a.rows.each do |a_row|
    b_columns.each do |b_column|
      matrix[pos += 1] = typeof(a[0] * b[0]).cast((0...a_row.length).inject(0) do |memo, i|
                           memo + a_row[i] * b_column[i]
      end)
    end
  end
  matrix
end

def main()
  r = Random.new
  a = Matrix.new(1000, 1000, 0)
  b = Matrix.new(1000, 1000, 0)

  (0..999).each do |i|
    (0..999).each do |j|
      a[i,j] = r.next_int
      b[i,j] = r.next_int
    end
  end

  c = a * b
  d = faster_matrix_multiply(a, b)
  raise "Not equal!" unless c == d

  puts "New:"
  puts Benchmark.measure { faster_matrix_multiply(a, b) }
  puts "Current:"
  puts Benchmark.measure { a * b }
end

main()


require "./types.cr"

def memcpy(dst : Pointer(_), src : Pointer(_), n : USize) : Pointer
    dst_sig = dst
    dst = dst.to_byte_ptr
    src = src.to_byte_ptr
    i = 0
    while i < n
        dst[i] = src[i]
        i += 1
    end
    dst_sig
end

def memmove(dst : Pointer(_), src : Pointer(_), n : USize) : Pointer
    dst_sig = dst
    dst = dst.to_byte_ptr
    src = src.to_byte_ptr
    if src < dst
        i = n
        while i != 0
            i -= 1
            dst[i] = src[i]
        end
    else
        i = 0
        while i < n
            dst[i] = src[i]
            i += 1
        end
    end
    dst_sig
end

def memset(dst : Pointer(_), c : UInt8, n : USize) : Pointer
    ptr = dst.to_byte_ptr
    i = 0
    while i < n
        ptr[i] = c
    end
    dst
end

def memcmp(ptr_a : Pointer(_), ptr_b : Pointer(_), n : USize)
    ptr_a = ptr_a.to_byte_ptr
    ptr_b = ptr_b.to_byte_ptr
    i = 0
    while i < n
        a = ptr_a[i]
        b = ptr_b[i]
        i += 1
        return a.to_i32 - b.to_i32 if a != b
    end
    0
end


Add Crustache::Engine class for typical using

module Crustache
  class Engine
    def initialize(@basedir : String, @cache = false)
      self.initialize ViewLoader.new @basedir, @cache
    end

    def initialize(@fs : FileSystem); end

    # It renders a template loaded from `filename` with `model`
    # and it returns rendered string.
    # If `filename` is not found, it returns `nil`, but it dosen't raise an error.
    def render(filename : String, model)
      @fs.load(filename).try{|tmpl| self.render tmpl, model}
    end

    def render(filename : String, model, output : IO)
      @fs.load(filename).try{|tmpl| self.render tmpl, model, output}
    end

    # It is a strict version `Engine#render`.
    # If `filename` is not found, it raise an error.
    def render!(filename : String, model)
      @fs.load!(filename).try{|tmpl| self.render tmpl, model}
    end

    def render!(filename : String, model, output : IO)
      @fs.load!(filename).try{|tmpl| self.render tmpl, model, output}
    end

    def render(tmpl : Template, model)
      Crustache.render tmpl, model, @fs
    end

    def render(tmpl : Template, model, output : IO)
      Crustache.render tmpl, model, @fs, io
    end
  end
end


require "./spec_helper"

describe Crustache::Engine do
  describe "#initialize" do
    it "should return a new instance" do
      Crustache::Engine.new(Crustache::HashFileSystem.new).should be_truthy
      Crustache::Engine.new("", true).should be_truthy
    end
  end

  describe "#render" do
    it "should render a template" do
      engine = Crustache::Engine.new Crustache::HashFileSystem.new
      engine.render(Crustache.parse("Test {{.}}"), "Test").should eq("Test Test")
    end

    it "should render a template" do
      fs = Crustache::HashFileSystem.new
      fs.register "test", Crustache.parse "Test {{.}}"
      engine = Crustache::Engine.new fs
      engine.render("test", "Test").should eq("Test Test")
    end

    it "should render a template with output IO object" do
      fs = Crustache::HashFileSystem.new
      fs.register "test", Crustache.parse "Test {{.}}"
      engine = Crustache::Engine.new fs
      output = StringIO.new
      engine.render("test", "Test", output)
      output.to_s.should eq("Test Test")
    end
  end

  describe "#render!" do
    it "should render a template" do
      fs = Crustache::HashFileSystem.new
      fs.register "test", Crustache.parse "Test {{.}}"
      engine = Crustache::Engine.new fs
      engine.render!("test", "Test").should eq("Test Test")
    end

    it "should raise an error" do
      fs = Crustache::HashFileSystem.new
      engine = Crustache::Engine.new fs
      expect_raises do
        engine.render!("test", "Test")
      end
    end
  end
end


Add Crystal version that avoids allocating strings

gcfile = File.new("chry_multiplied.fa")
gcfile.buffer_size = ARGV[0].to_i

at = 0
gc = 0

while true
  # Peek the IO's buffer
  peek = gcfile.peek

  # If there's nothing else, we reached the end
  break if peek.empty?

  # If the line starts with '>' it's a comment
  if peek[0] === '>'
    while true
      # See where the line ends
      newline_index = peek.index('\n'.ord)

      # If we find an end, skip until past the newline and continue analyzing
      if newline_index
        gcfile.skip(newline_index + 1)
        break
      end

      # Otherwise we must continue looking for that newline,
      # so we skip the entire peek buffer and read more
      gcfile.skip(peek.size)
      peek = gcfile.peek

      # Maybe we reached the end?
      break if peek.empty?
    end

    # Here we found the newline, so we analyze the next line
    next
  end

  # This is not a comment line so we read until the next line
  while true
    # See where the line ends
    newline_index = peek.index('\n'.ord)

    # How many bytes we need to analyze: either until the newline or the entire buffer
    analyze_size = newline_index || peek.size

    # Analyze the bytes
    peek[0, analyze_size].each do |byte|
      case byte
      when 'A', 'T'
        at += 1
      when 'G', 'C'
        gc += 1
      end
    end

    # If we found a newline, we are done
    if newline_index
      gcfile.skip(newline_index + 1)
      break
    end

    # Otherwise we are still in a non-comment line
    gcfile.skip(peek.size)
    peek = gcfile.peek

    # Maybe we reached the end?
    break if peek.empty?
  end
end

gcfile.close

gcfrac = gc / (gc + at)
puts "GC fraction: #{gcfrac}"


Add StaticFileHandler with SVG mime type

class HTTP::StaticFileHandler
  private def mime_type(path)
    case File.extname(path)
    when ".txt"          then "text/plain"
    when ".htm", ".html" then "text/html"
    when ".css"          then "text/css"
    when ".js"           then "application/javascript"
    when ".svg"          then "image/svg+xml"
    when ".svgz"         then "image/svg+xml"
    else                      "application/octet-stream"
    end
  end
end


Add some more specs for create_module_mock

require "../spec_helper"

module MyModule
  def self.exists?(name)
    false
  end
end

create_module_mock MyModule do
  mock self.exists?(name)
end

create_mock File do
  mock self.exists?(name)
end

describe "create module mock macro" do
  it "does not fail with Nil errors" do
    allow(MyModule).to receive(self.exists?("hello")).and_return(true)
    MyModule.exists?("world").should eq(false)
    MyModule.exists?("hello").should eq(true)
  end

  it "does not fail with Nil errors for stdlib class" do
    allow(File).to receive(self.exists?("hello")).and_return(true)
    File.exists?("world").should eq(false)
    File.exists?("hello").should eq(true)
  end
end


Add some specs for Caoutchouc::Elasticsearch::Health

describe Caoutchouc::Elasticsearch::Health do
  describe ".from_json" do
    it "parses json correctly" do
      response = <<-EOF
        {
          "cluster_name": "elasticsearch",
          "status": "green",
          "timed_out": false,
          "number_of_nodes": 4,
          "number_of_data_nodes": 2,
          "active_primary_shards": 384,
          "active_shards": 768,
          "relocating_shards": 0,
          "initializing_shards": 0,
          "unassigned_shards": 0
        }
      EOF
      res = Caoutchouc::Elasticsearch::Health.from_json(response)
      res.status.should eq("green")
      res.active_shards.should eq(768)
    end
  end
end


<!DOCTYPE html PUBLIC "-//w3c//dtd XHTML 1.1//EN" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd">

  <title>Typo admin: <%= controller.controller_name %></title>
  <%= stylesheet_link_tag "admin.css" %>

<%= link_to "Typo admin (#{config['blog_name']})", "/admin/" %>

    <%= current_user_notice %>

<%= link_to_section "General", :controller=>"/admin/general"%>

<%= link_to_section "Articles", :controller=>"/admin/content"%>

<%= link_to_section "Users", :controller=>"/admin/users"%>

    <%= render_flash %>

  <%= @content_for_layout %>

Add nil rescues around helper functions not available to account controller (need a better way for this though)

<!DOCTYPE html PUBLIC "-//w3c//dtd XHTML 1.1//EN" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd">

  <title>Typo admin: <%= controller.controller_name %></title>
  <%= stylesheet_link_tag "admin.css" %>

<%= link_to "Typo admin (#{config['blog_name']})", "/admin/" %>

    <%= current_user_notice rescue nil %>

<%= link_to_section "General", :controller=>"/admin/general" rescue nil %>

<%= link_to_section "Articles", :controller=>"/admin/content" rescue nil %>

<%= link_to_section "Users", :controller=>"/admin/users" rescue nil %>

    <%= render_flash rescue nil %>

  <%= @content_for_layout %>


<%= subpage_display :emarketing, @subpages %>

<%= render :partial => 'referrer_sources' %>

Add more actions button for the rest of the stats

<% action_panel :more => true do |p| -%>
<% end -%>

<% more_action_panel do |p| -%>
  <% @subpages.each do |page| -%>
    <%= p.link page[0], page[3] %>
  <% end -%>
<% end -%>

<%= render :partial => 'referrer_sources' %>


<% display_class = ( @records.kind_of?(Array) ? @records.first : @records ) -%>
<tr id="<%= active_scaffold_calculations_id %>" class="active-scaffold-calculations">
  <% active_scaffold_config.list.columns.each do |column| -%>

      <% if column.calculation? -%>
        <%
        calculation = column_calculation(column)

        override_formatter = "render_#{column.name}_#{column.calculate}"
        calculation = self.method(override_formatter).call(calculation) if respond_to? override_formatter

        _erbout.concat calculation.to_s
        -%>
      <% else -%>

      <% end -%>

  <% end -%>
  <% unless active_scaffold_config.action_links.empty? -%>

  <% end -%>

Fix list calculations, _erbout has been removed

<% display_class = ( @records.kind_of?(Array) ? @records.first : @records ) -%>
<tr id="<%= active_scaffold_calculations_id %>" class="active-scaffold-calculations">
  <% active_scaffold_config.list.columns.each do |column| -%>

      <% if column.calculation? -%>
        <%
        calculation = column_calculation(column)

        override_formatter = "render_#{column.name}_#{column.calculate}"
        calculation = self.method(override_formatter).call(calculation) if respond_to? override_formatter

        -%>
        <%= calculation.to_s %>
      <% else -%>

      <% end -%>

  <% end -%>
  <% unless active_scaffold_config.action_links.empty? -%>

  <% end -%>


Hello! This site really isn't nearly finished yet, but it
    works and so we wanted to start sharing it with you.
    Things still to do:

 Finish designing the site - the current appearance is in flux.

 RSS feeds and email alerts based on search terms.

 Add things you tell us you want.

As always, if you want mySociety to do more stuff like this, please
    volunteer,
    donate,
    or commission us!

Update help notice now alerts finished.

Hello! This site really isn't nearly finished yet, but it
    works and so we wanted to start sharing it with you.
    Things still to do:

 Finish designing the site - this appearance is just placeholder.

 Add things you tell us you want.

As always, if you want mySociety to do more stuff like this, please
    volunteer,
    donate,
    or commission us!


    <%=image_tag "http://images.amazon.com/images/P/#{doc['asin_text']}.01.MZZZZZZZ" %>

        <%=link_to doc['title_text'], "http://www.amazon.com/exec/obidos/ASIN/#{doc['asin_text']}"%>

      <% doc.each do |k,v|; highlighting = response.highlighted(doc['id'], k) %>

<%=k%>:	<%= highlighting ? "...#{highlighting}..." : (v.respond_to?('join') ? v.join(',') : v.to_s)%>

      <% end %>

Adjust delicious library view for change in asin field name

    <%=image_tag "http://images.amazon.com/images/P/#{doc['asin_display']}.01.MZZZZZZZ" %>

        <%=link_to doc['title_text'], "http://www.amazon.com/exec/obidos/ASIN/#{doc['asin_display']}"%>

      <% doc.each do |k,v|; highlighting = response.highlighted(doc['id'], k) %>

<%=k%>:	<%= highlighting ? "...#{highlighting}..." : (v.respond_to?('join') ? v.join(',') : v.to_s)%>

      <% end %>


Please check the URL (i.e. the long code of letters and numbers) is copied
correctly from your email.

If you can't click on it in the email, you'll have to select and copy it from
the email.  Then paste it into your browser, into the place you would type the
address of any other webpage.

If you got the email more than a year ago, then this login link won't work any
more. Please try doing what you were doing from the beginning.

Update quite old out of date bad token text

Please check the URL (i.e. the long code of letters and numbers) is copied
correctly from your email.

If you can't click on it in the email, you'll have to select and copy it from
the email.  Then paste it into your browser, into the place you would type the
address of any other webpage.

If you got the email more than six months ago, then this login link won't work any
more. Please try doing what you were doing from the beginning.


<% @results.each do |source| %>

Results from <%= link_to source[:source], source[:url] %>

<% if source[:results] %>
<% source[:results].each do |result| %>

<%= link_to_function result[:description], "setPosition(#{result[:lat]}, #{result[:lon]}, #{result[:zoom]})" %>

<% end %>
<% else %>

<%= source[:error] %>

<% end %>
<% end %>

Add an explicit message when no results are found for a given source.

<% @results.each do |source| %>

Results from <%= link_to source[:source], source[:url] %>

<% if source[:results] %>
<% if source[:results].empty? %>

No results found

<% else %>
<% source[:results].each do |result| %>

<%= link_to_function result[:description], "setPosition(#{result[:lat]}, #{result[:lon]}, #{result[:zoom]})" %>

<% end %>
<% end %>
<% else %>

<%= source[:error] %>

<% end %>
<% end %>


<%= _('Products and Services') %>

  <% if !@empty_query %>
    <% button_bar do %>
      <%= display_map_list_button %>
    <% end %>
    <%= facets_menu(:products, @facets) %>
  <% end %>

  <%= render :partial => 'search_form', :locals => { :hint => _('Type the product, service, city or qualifier desired') } %>
  <%= render :partial => 'results_header' %>

  <%= display_results(true) %>
  <% if params[:display] != 'map' %>
    <%= pagination_links @results[:products] %>
  <% end %>

Fix for product search view's title

<%= search_page_title( @titles[:products], @category ) %>

  <% if !@empty_query %>
    <% button_bar do %>
      <%= display_map_list_button %>
    <% end %>
    <%= facets_menu(:products, @facets) %>
  <% end %>

  <%= render :partial => 'search_form', :locals => { :hint => _('Type the product, service, city or qualifier desired') } %>
  <%= render :partial => 'results_header' %>

  <%= display_results(true) %>
  <% if params[:display] != 'map' %>
    <%= pagination_links @results[:products] %>
  <% end %>


<% unless tag_details.tags_as_hash.empty? %>

    Tags:

        <%= render :partial => "tag", :collection => tag_details.tags_as_hash %>

<% end %>

Sort the tags for the databrowser output.

<% unless tag_details.tags.empty? %>

    Tags:

        <%= render :partial => "tag", :collection => tag_details.tags.sort %>

<% end %>


<%= link_to _("Quiénes somos"), help_about_path %>

<%= link_to _("Guía para solicitantes"), help_requesting_path %>

<%= link_to _("Solicitar documentos"), body_index_path, :class => 'make-request-link' %>

<%= link_to _("Buscar solicitudes"), request_list_all_url %>

Select only one tab in topnav at a time

        <li class="<%= 'selected' if params[:controller] == 'help' and params[:action] != 'requesting'%>"><%= link_to _("Quiénes somos"), help_about_path %>

        <li class="<%= 'selected' if params[:controller] == 'help' and params[:action] == 'requesting'%>"><%= link_to _("Guía para solicitantes"), help_requesting_path %>

        <li class="<%= 'selected' if params[:controller] == 'public_body' or (params[:controller] == 'request' and !['list'].include?(params[:action])) %>"><%= link_to _("Solicitar documentos"), body_index_path, :class => 'make-request-link' %>

        <li class="<%= 'selected' if params[:controller] == 'request' and ['list'].include?(params[:action]) %>"><%= link_to _("Buscar solicitudes"), request_list_all_url %>


<% content_for :head do -%>
<%= javascript_include_tag 'mephisto/dialog' %>
<% end -%>

<% content_for :action_nav do -%>

<%= link_to "Import new theme", :controller => 'themes', :action => 'import' %>

<% end -%>

<%= render :partial => "theme", :collection => site.themes %>

Fix link for importing themes so that it can be reached (instead of triggering security protection)

<% content_for :head do -%>
<%= javascript_include_tag 'mephisto/dialog' %>
<% end -%>

<% content_for :action_nav do -%>

<%= link_to "Import new theme", {:controller => 'themes', :action => 'import'}, :method => :post  %>

<% end -%>

<%= render :partial => "theme", :collection => site.themes %>


<% @title = "Preview new FOI request to '" + h(@info_request.public_body.name) + "'" %>

<% form_for(:info_request, @info_request, :html => { :id => 'preview_form' }  ) do |f| %>

Now preview your request

    <%= f.hidden_field(:title) %>

    <% fields_for :outgoing_message do |o| %>

        To: <%=h @info_request.public_body.name %>

Subject: <%=h @info_request.title %>

        <%= @outgoing_message.get_body_for_html_preview %>
        <%= o.hidden_field(:body) %>

    <% end %>

    Note: Your request and any response will be
    displayed publically on this website.

    <%= f.hidden_field(:public_body_id, { :value => @info_request.public_body_id } ) %>
    <%= hidden_field_tag(:submitted_new_request, 1) %>
    <%= hidden_field_tag(:preview, 0 ) %>
    <%= submit_tag "Re-edit this request", :name => 'reedit' %>
    <%= submit_tag "Send Freedom of Information request", :name => 'submit' %>

<% end %>

Make button say it is public

<% @title = "Preview new FOI request to '" + h(@info_request.public_body.name) + "'" %>

<% form_for(:info_request, @info_request, :html => { :id => 'preview_form' }  ) do |f| %>

Now preview your request

    <%= f.hidden_field(:title) %>

    <% fields_for :outgoing_message do |o| %>

        To: <%=h @info_request.public_body.name %>

Subject: <%=h @info_request.title %>

        <%= @outgoing_message.get_body_for_html_preview %>
        <%= o.hidden_field(:body) %>

    <% end %>

    Note: Your request and any response will be
    displayed publically on this website.

    <%= f.hidden_field(:public_body_id, { :value => @info_request.public_body_id } ) %>
    <%= hidden_field_tag(:submitted_new_request, 1) %>
    <%= hidden_field_tag(:preview, 0 ) %>
    <%= submit_tag "Re-edit this request", :name => 'reedit' %>
    <%= submit_tag "Send public Freedom of Information request", :name => 'submit' %>

<% end %>


All Public Repositories <%= if logged_in? then link_to_unless_current '[Add]', { :action => 'new', :controller => 'repo' }, :rel => 'facebox' else link_to_unless_current '[Add]', { :action => 'new', :controller => 'repo' } end %>

	<% for repo in @repos%>

<%= link_to(repo.name, :controller=>'repo', :action => 'show', :id => repo.id)%>

Description: <%= repo.desc%>

Owner: <%=link_to user_lookup(repo.user_id).username, :controller => 'user', :action => 'profile', :username => repo.user.username%>

		<% if logged_in?%>
			<% if watching_repo?(repo.id) != 0 %>
				<%=link_to 'Un-Watch', {:action => "unwatch", :repo_id => repo.id}, :method => :post %>
			<%else%>
				<%=link_to 'Watch', {:action => "watch", :repo_id => repo.id}, :method => :post %>
			<%end%>
		<%end%>

	<%end%>

Reduce lookups on the public repos page by using joins in the model

All Public Repositories <%= if logged_in? then link_to_unless_current '[Add]', { :action => 'new', :controller => 'repo' }, :rel => 'facebox' else link_to_unless_current '[Add]', { :action => 'new', :controller => 'repo' } end %>

	<% for repo in @repos%>

<%= link_to(repo.name, :controller=>'repo', :action => 'show', :id => repo.id)%>

Description: <%= repo.desc%>

Owner: <%=link_to repo.user.username, :controller => 'user', :action => 'profile', :username => repo.user.username%>

		<% if logged_in?%>
			<% if watching_repo?(repo.id) != 0 %>
				<%=link_to 'Un-Watch', {:action => "unwatch", :repo_id => repo.id}, :method => :post %>
			<%else%>
				<%=link_to 'Watch', {:action => "watch", :repo_id => repo.id}, :method => :post %>
			<%end%>
		<%end%>

	<%end%>


<%= _("You're in. Continue sending your request") %>

Add div around successful sign-in modal message so it can be themed


<% content_for "optionals" do %>

    Tags

    <% if @all_tags %>
      <% @all_tags.each do |tag| %>
        <%= link_to tag, :controller => 'trace', :action => @paging_action, :tag => tag %>

      <% end %>
    <% end %>

<% end %>

Make tag links work again.

<% content_for "optionals" do %>

    Tags

    <% if @all_tags %>
      <% @all_tags.each do |tag| %>
        <%= link_to tag, :tag => tag %>

      <% end %>
    <% end %>

<% end %>


      Search Results
      Close

Make openSidebar() work with no argument.


    Category title
    Articles
    Delete

  <% for category in @categories -%>
  <tr <%= alternate_class -%> id="category_<%= category.id -%>">
    <%= image_tag 'checked.gif', :class => "handle" %> <%= link_to category.name, :action => 'show', :id => category.id %>
    <%= link_to responses(category.articles, 'article'), :action => 'show', :id => category.id %>
    <%= link_to_destroy category %>

  <% end -%>

Remove apparently useless handle class from Category Admin checked image

    Category title
    Articles
    Delete

  <% for category in @categories -%>
  <tr <%= alternate_class -%> id="category_<%= category.id -%>">
    <%= image_tag 'checked.gif' %> <%= link_to category.name, :action => 'show', :id => category.id %>
    <%= link_to responses(category.articles, 'article'), :action => 'show', :id => category.id %>
    <%= link_to_destroy category %>

  <% end -%>


	<%= will_paginate @playlists, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_region => 'playlists' } %>

	<%= will_paginate @collages, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_params => 'collages' } %>

	<%= will_paginate @cases, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_params => 'cases' } %>

Fix user pagination on cases and collages.

	<%= will_paginate @playlists, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_region => 'playlists' } %>

	<%= will_paginate @collages, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_region => 'collages' } %>

	<%= will_paginate @cases, :container => false, :previous_label => 'Prev', :next_label => 'Next', :params => { :ajax_region => 'cases' } %>


<% if @editing -%>
  <% if logged_in? and logged_in_person.permitted?("edit_answers", @question.questionnaire) -%>
    <%= text_area_tag "answer[#{@question.id}]", value, :rows => 4 %>
  <% end -%>
<% else -%>
  <% if logged_in? and logged_in_person.permitted?("view_answers", @question.questionnaire) -%>
    <%= simple_format value %>
  <% end -%>
<% end -%>

Use the right parameter order for permitted?

<% if @editing and logged_in? and logged_in_person.permitted?(@question.questionnaire, "edit_answers") -%>
  <%= text_area_tag "answer[#{@question.id}]", value, :rows => 4 %>
<% else -%>
  <% if logged_in? and logged_in_person.permitted?(@question.questionnaire, "view_answers") -%>
    <%= simple_format value %>
  <% end -%>
<% end -%>


<%= from %> is not a known email address. Only user email addresses and
email addresses receiving notifications are allowed.
--
Message automatically generated by ClockingIT
http://<%= subdomain %>.<%= $CONFIG[:domain] %>

Fix unknown from email template

<%= @from %> is not a known email address. Only user email addresses and
email addresses receiving notifications are allowed.
--
Message automatically generated by ClockingIT
http://<%= @subdomain %>.<%= $CONFIG[:domain] %>


        Project: <%= link_to @project.name, @project_url %>

        Revision: <%= link_to @changeset.revision, @changeset_url %>

        Author: <%= h(@author) %>

        Summary: <%= @changeset.short_comments %>

        Details: <%= @changeset.long_comments %>

        Please take a moment to review this checkin.

<%= format_diff @diff %>
<%= Redmine::WikiFormatting.to_html(Setting.text_formatting, Setting.emails_footer) %>

Increase font size for diff mail


<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">

        <%# When not logged in, but mid-comment-leaving, there'll be no comment.user %>
        <%= !comment.user || (!@user.nil? && @user.id == comment.user.id) ? "You" : user_link(comment.user) %>
        left an annotation (<%= simple_date(comment.created_at || Time.now) %>)

<%= comment.get_body_for_html_display %>

        <% if !comment.id.nil? %>
            <%= link_to "Link to this", comment_url(comment) %>
            <% if !@user.nil? && @user.admin_page_links? %>
                | <%= link_to "Admin", admin_url("request/edit_comment/" + comment.id.to_s) %>
            <% end %>

        <% end %>

Use user_or_you_capital_link instead of hand-rolling

<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">

        <%# When not logged in, but mid-comment-leaving, there'll be no comment.user %>
        <%= comment.user ? user_or_you_capital_link(comment.user) : "You" %>
        left an annotation (<%= simple_date(comment.created_at || Time.now) %>)

<%= comment.get_body_for_html_display %>

        <% if !comment.id.nil? %>
            <%= link_to "Link to this", comment_url(comment) %>
            <% if !@user.nil? && @user.admin_page_links? %>
                | <%= link_to "Admin", admin_url("request/edit_comment/" + comment.id.to_s) %>
            <% end %>

        <% end %>


    <%= image_tag('/ipvtheme/images/OSF.jpg') %>
    <%= image_tag('/ipvtheme/images/otevrete.jpg') %>
    <%= image_tag('/ipvtheme/images/FOM.jpg') %>
    <%= link_to _("Contact {{site_name}}", :site_name => site_name), help_contact_url %>
|  <a href="https://twitter.com/<%= Configuration::twitter_username %>"><%= _("Follow us on twitter") %>
<%= render :partial => 'general/credits' %>

Add inner div for logos.


<%= link_to "#{image_tag('navimg/logo-trans.png')} Make and explore Freedom of Information requests", frontpage_url, :id=>'logo' %>

      another really handy site by mysociety.org

Include alt text for logo

<%= link_to "#{image_tag('navimg/logo-trans.png', :alt => 'WhatDoTheyKnow?')} Make and explore Freedom of Information requests", frontpage_url, :id=>'logo' %>

      another really handy site by mysociety.org


  <%=h @exception.original_exception.class.to_s %> in
  <%=h request.parameters["controller"].capitalize if request.parameters["controller"]%>#<%=h request.parameters["action"] %>

  Showing <%=h @exception.file_name %> where line #<%= @exception.line_number_link rescue @exception.line_number %> raised:

<%=h @exception.message %>

Extracted source (around line #<%= @exception.line_number_link rescue @exception.line_number %>):

<%=h @exception.source_extract %>

<%=h @exception.sub_template_message %>

<% @real_exception = @exception
   @exception = @exception.original_exception || @exception %>
<%= render_file(@rescues_path + "/_trace.rhtml", false) %>
<% @exception = @real_exception %>

<%= render_file(@rescues_path + "/_request_and_response.rhtml", false) %>

Fix textmate footnotes to now blowup on exceptions

  <%=h @exception.original_exception.class.to_s %> in
  <%=h request.parameters["controller"].capitalize if request.parameters["controller"]%>#<%=h request.parameters["action"] %>

  Showing <%=h @exception.file_name %> where line #<%= @exception.line_number_link rescue @exception.line_number %> raised:

<%=h @exception.message %>

Extracted source (around line #<%= @exception.line_number_link rescue @exception.line_number %>):

<%=h @exception.source_extract %>

<%=h @exception.sub_template_message %>

<% @real_exception = @exception
   @exception = @exception.original_exception || @exception %>
<%= render_file(@rescues_path + "/_trace.erb", false) %>
<% @exception = @real_exception %>

<%= render_file(@rescues_path + "/_request_and_response.erb", false) %>


<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

      <%= t('orders_cycle_plugin.views.mailer.open_cycle.hello_member_of_name') % {:name => @profile.name} %>

<%= t('orders_cycle_plugin.views.mailer.open_cycle.a_new_cycle_is_open_c') + @cycle.name %>

<%= t('orders_cycle_plugin.views.mailer.open_cycle.the_cycle_description') %>

<%= @cycle.description %>

<%= t('orders_cycle_plugin.views.mailer.open_cycle.the_administrator_let') %>

<%= @message %>

      --

    <%= @environment.name %>

Add link to order and format it better

<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

      <%= t('orders_cycle_plugin.views.mailer.open_cycle.hello_member_of_name') % {:name => @profile.name} %>

<%= t('orders_cycle_plugin.views.mailer.open_cycle.a_new_cycle_is_open_c') + @cycle.name %>

<%= @cycle.description %>

<%= t('orders_cycle_plugin.views.mailer.open_cycle.the_administrator_let') %>

<%= @message %>

<%= link_to t('orders_cycle_plugin.views.order.index.place_an_order'), {:controller => :orders_cycle_plugin_order, :action => :edit, :cycle_id => @cycle.id, :profile => @profile.identifier, :only_path => false, :host => @profile.hostname || @environment.default_hostname }, :id => 'consumer-new-order' %>

<%= @domain %>

      --

    <%= @environment.name %>


<%=@info_request.public_body.name%> <%=('has asked you to explain part of your')%> <%=@info_request.law_used_short%> <%= _('request.')%>
<%= _('To do this, first click on the link below.')%>

<%=@url%>

<%= _('You will only get an answer to your request if you follow up
with the clarification.')%>

-- <%= _('the {{site_name}} team', :site_name=>site_name) %>

Fix missing i18n string in clarification email

<%= _('{{public_body}} has asked you to explain part of your {{law_used}} request.',
    :public_body => @info_request.public_body.name,
    :law_used => @info_request.law_used_short ) %>
<%= _('To do this, first click on the link below.') %>

<%=@url%>

<%= _('You will only get an answer to your request if you follow up
with the clarification.')%>

-- <%= _('the {{site_name}} team', :site_name=>site_name) %>


<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
<% @request.env.keys.sort.each do |key| -%>
* <%= "%*-s: %s" % [max.length, key, @request.env[key].to_s.strip] %>
<% end -%>

* Process: <%= $$ %>
* Server : <%= `hostname -s`.chomp %>

Fix for "flag after width" exception notifier fail

<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
<% @request.env.keys.sort.each do |key| -%>
* <%= "%-s: %s" % [max.length, key, @request.env[key].to_s.strip] %>
<% end -%>

* Process: <%= $$ %>
* Server : <%= `hostname -s`.chomp %>


Hi <%= @reviewer_username %>,

<%= @review.developer %> would like you to do a code review of <%= @review.count_commits %> commits.

At your earliest convenience, please proceed to:

http://janus.corp.amiestreet.com:3000/review/<%= @review.id %>/show

or enter your <%= @review.project.name %> repository and do:

git fetch review review-<%= @review.id %>
git checkout remotes/review/review-<%= @review.id %>

Log of commits in this review
=============================

<%= @review.log %>

Thanks,
-ARB Notifier

Fix email to give proper git commands to checkout a review branch

Hi <%= @reviewer_username %>,

<%= @review.developer %> would like you to do a code review of <%= @review.count_commits %> commits.

At your earliest convenience, please proceed to:

http://janus.corp.amiestreet.com:3000/review/<%= @review.id %>/show

or enter your <%= @review.project.name %> repository and do:

git fetch review review-<%= @review.id %>:remotes/review/review-<%= @review.id %>
git checkout remotes/review/review-<%= @review.id %>

Log of commits in this review
=============================

<%= @review.log %>

Thanks,
-ARB Notifier


<%
task_id      = "task_#{task.id}"
details_id   = "#{task_id}_details"
links = []
task.users.each do |user|
  if user == current_user
    links << link_to(current_user.login, me_url(:action => 'tasks', :id => nil))
  else
    links << link_to_user(user, :action => 'tasks')
  end
end
-%>

      <%= friendly_date(task.updated_at) if task.updated_at? -%>

      <%= "#{links.join(', ')}:" if links.any? -%>

      <% if @upart and @upart.viewed_at? and task.created_at? %>
        <% if @upart.viewed_at < task.created_at - 1.minute %>
          <%= "(new)"  -%>
        <% elsif @upart.viewed_at < task.updated_at - 1.minute%>
          <%= "(modified)" -%>
        <% end %>
      <% end %>

      <% if task.description.any? -%>
        <%= link_to_function h(task.name), "Element.toggle('#{details_id}')" %>
      <% else -%>
        <%=h task.name %>
      <% end %>

    <div class='indent task_details' id="<%=details_id%>" style='display: none'>
      <%= task.description_html %>

Reduce delay in debouncing notification of modified tasks in task list.

<%
task_id      = "task_#{task.id}"
details_id   = "#{task_id}_details"
links = []
task.users.each do |user|
  if user == current_user
    links << link_to(current_user.login, me_url(:action => 'tasks', :id => nil))
  else
    links << link_to_user(user, :action => 'tasks')
  end
end
-%>

      <%= friendly_date(task.updated_at) if task.updated_at? -%>

      <%= "#{links.join(', ')}:" if links.any? -%>

      <% if @upart and @upart.viewed_at? and task.created_at? %>
        <% if @upart.viewed_at < task.created_at - 10.seconds %>
          <%= "(new)"  -%>
        <% elsif @upart.viewed_at < task.updated_at - 10.seconds%>
          <%= "(modified)" -%>
        <% end %>
      <% end %>

      <% if task.description.any? -%>
        <%= link_to_function h(task.name), "Element.toggle('#{details_id}')" %>
      <% else -%>
        <%=h task.name %>
      <% end %>

    <div class='indent task_details' id="<%=details_id%>" style='display: none'>
      <%= task.description_html %>


<script type="text/javascript">
  $(function() {
     $(".use-datepicker").datepicker(
            {closeText: '<%= _("Done") %>',
             prevText: '<%= _("Prev") %>',
             nextText: '<%= _("Next") %>',
             currentText: '<%= _("Today") %>',
             monthNames: <%= I18n.translate('date.month_names')[1..-1].to_json %>,
             monthNamesShort: <%= I18n.translate('date.abbr_month_names')[1..-1].to_json %>,
             dayNames: <%= I18n.translate('date.day_names').to_json %>,
             dayNamesShort: <%= I18n.translate('date.abbr_day_names').to_json %>,
             dayNamesMin: <%= I18n.translate('date.abbr_day_names').collect{|x| x[0..0]}.to_json %>,
             weekHeader: '<%= _("Wk") %>',
             dateFormat: '<%= I18n.translate('date.formats.default').sub("%Y", "yy").sub("%m", "mm").sub("%d", "dd").gsub("-", "/") %>'}
  );
  });
</script>

Fix calendar picker on request search page

<script type="text/javascript">
  $(function() {
     $(".use-datepicker").datepicker(
            {closeText: '<%= _("Done") %>',
             prevText: '<%= _("Prev") %>',
             nextText: '<%= _("Next") %>',
             currentText: '<%= _("Today") %>',
             monthNames: <%= raw I18n.translate('date.month_names')[1..-1].to_json %>,
             monthNamesShort: <%= raw I18n.translate('date.abbr_month_names')[1..-1].to_json %>,
             dayNames: <%= raw I18n.translate('date.day_names').to_json %>,
             dayNamesShort: <%= raw I18n.translate('date.abbr_day_names').to_json %>,
             dayNamesMin: <%= raw I18n.translate('date.abbr_day_names').collect{|x| x[0..0]}.to_json %>,
             weekHeader: '<%= _("Wk") %>',
             dateFormat: '<%= I18n.translate('date.formats.default').sub("%Y", "yy").sub("%m", "mm").sub("%d", "dd").gsub("-", "/") %>'}
  );
  });
</script>


<%= stylesheet_link_tag "/tuderechoasaber-theme/stylesheets/custom" %>

<% if RAILS_ENV == 'production' %>
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-431041-8']);
  _gaq.push(['_setDomainName', 'tuderechoasaber.es']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

<script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script>
<script type="text/javascript">stLight.options({publisher: "ur-7cc3d19d-c1ea-bb5b-a70d-d9b23629ea61"}); </script>

<% end %>

Improve performance by including ShareThis only in homepage

<%= stylesheet_link_tag "/tuderechoasaber-theme/stylesheets/custom" %>

<% if RAILS_ENV == 'production' %>
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-431041-8']);
  _gaq.push(['_setDomainName', 'tuderechoasaber.es']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

<% end %>

<% if params[:action] == 'frontpage' %>
<script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script>
<script type="text/javascript">stLight.options({publisher: "ur-7cc3d19d-c1ea-bb5b-a70d-d9b23629ea61"}); </script>
<% end %>


<% form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
    <%= foi_error_messages_for :user_signin %>

If you've used WhatDoTheyKnow before

    Your e-mail:
    <%= text_field 'user_signin', 'email', { :size => 20 } %>

    Password:
    <%= password_field 'user_signin', 'password', { :size => 15 } %>

    <%= link_to "Forgotten your password?", signchange_url + "?pretoken=" + h(params[:token]) %>

    <%= check_box_tag 'remember_me', "1" %>
    Remember me

    <%= hidden_field_tag 'token', params[:token], { :id => 'signin_token' } %>
    <%= submit_tag "Sign in" %>

<% end %>

Add wording to rememeber me box

<% form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
    <%= foi_error_messages_for :user_signin %>

If you've used WhatDoTheyKnow before

    Your e-mail:
    <%= text_field 'user_signin', 'email', { :size => 20 } %>

    Password:
    <%= password_field 'user_signin', 'password', { :size => 15 } %>

    <%= link_to "Forgotten your password?", signchange_url + "?pretoken=" + h(params[:token]) %>

    <%= check_box_tag 'remember_me', "1" %>
    Remember me (keeps you signed in longer;
    do not use on a public computer)

    <%= hidden_field_tag 'token', params[:token], { :id => 'signin_token' } %>
    <%= submit_tag "Sign in" %>

<% end %>


  Your Right to Know

Every citizen has the right to access information held by public authorities. By law, they have to respond. <a href="<%= help_about_path %>">Find out more about freedom of information.

Replace front page message with notice about usage for Hasadna volunteers only

  הגשת בקשות פתוחה למתנדבי הסדנא לידע ציבורי בלבד

  על פי חוק, הפטור מהאגרה ניתן רק לעמותות ופעיליהן, ולכן לצערינו הגשת בקשות דרך אתר זה ניתנת אך ורק למתנדבי הסדנא.
  ניתן להגיש בקשות גם באתר משרד המשפטים. האגרה היא בסך הכל 20 ש"ח.

  רוצים להתנדב בסדנא? קראו כאן ומלאו את השאלון.


<%
@body_class = 'change-form'
@content_class = 'colM'
@title = @object.new_record? ? "Add #{human_model.downcase}" : "Change #{human_model.downcase}"
@tools = []
@tools << link_to( "History", { :model => params[:model], :action => 'history', :id => params[:id] } ) if has_history?

admin_form_for params[:model], @object,
  :url => { :action => 'save', :model => params[:model], :id => @object.id } do |builder|

  builder.outer do
    builder.prologue do
    end
    model.active_admin_fieldsets.each do |set|
      set.build builder
    end

%>

<% unless @object.new_record? %>

<%= link_to 'Delete', { :action => 'delete', :model => params[:model], :id => @object.id }, { :class => 'deletelink', :post => true, :confirm => "Are you sure you want to delete \"#{@object.to_label}\"?" } %>

<% end %>
<input type="submit" value="Save and add another" name="_addanother"  />
<input type="submit" value="Save and continue editing" name="_continue" />
<input type="submit" value="Save" class="default" />

<%

    builder.epilogue do
    end
  end
end
%>

Use :method => :post instead of :post => true, as per deprecation.

<%
@body_class = 'change-form'
@content_class = 'colM'
@title = @object.new_record? ? "Add #{human_model.downcase}" : "Change #{human_model.downcase}"
@tools = []
@tools << link_to( "History", { :model => params[:model], :action => 'history', :id => params[:id] } ) if has_history?

admin_form_for params[:model], @object,
  :url => { :action => 'save', :model => params[:model], :id => @object.id } do |builder|

  builder.outer do
    builder.prologue do
    end
    model.active_admin_fieldsets.each do |set|
      set.build builder
    end

%>

<% unless @object.new_record? %>

<%= link_to 'Delete', { :action => 'delete', :model => params[:model], :id => @object.id }, { :class => 'deletelink', :method => :post, :confirm => "Are you sure you want to delete \"#{@object.to_label}\"?" } %>

<% end %>
<input type="submit" value="Save and add another" name="_addanother"  />
<input type="submit" value="Save and continue editing" name="_continue" />
<input type="submit" value="Save" class="default" />

<%

    builder.epilogue do
    end
  end
end
%>


  <%= required_fields_message %>

  <%= render :file => 'shared/tiny_mce' %>

    <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %>

  <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :body_label => 'Description:'} %>

    <% f.fields_for :image_builder, @article.image do |i| %>
      <%= file_field_or_thumbnail(_('Image:'), @article.image, i) %>
    <% end %>

    <%= labelled_form_field(_('Goals:'), text_area(:article, :goals, :rows => 3, :cols => 64)) %>
    <%= labelled_form_field(_('Expected Results:'), text_area(:article, :expected_results, :rows => 3, :cols => 64)) %>

Remove redundant image param of track at edition form

  <%= required_fields_message %>

  <%= render :file => 'shared/tiny_mce' %>

    <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %>

  <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :body_label => 'Description:'} %>

    <%= labelled_form_field(_('Goals:'), text_area(:article, :goals, :rows => 3, :cols => 64)) %>
    <%= labelled_form_field(_('Expected Results:'), text_area(:article, :expected_results, :rows => 3, :cols => 64)) %>


        <%= link_to 'Alaveteli', main_url('/'), :class => "brand" %>

<%= link_to 'Summary', admin_url("") %>

<%= link_to 'Timeline', admin_url("timeline") %>

<%= link_to 'Stats', admin_url("stats") %>

<%= link_to 'Debug', admin_url("debug") %>

<%= link_to 'Authorities', admin_url("body/list") %>

<%= link_to 'Requests', admin_url("request/list") %>

<%= link_to 'Users', admin_url("user/list") %>

<%= link_to 'Tracks', admin_url("track/list") %>

<%= link_to 'Log out', signout_path %>

Add navbar-inverse class to the admin navbar - the bootstrap default is now a white background. Add admin class in order to apply styles from the admin stylesheet even when the navbar is being shown to an admin user using the front end (so no admin class will be applied to the body element).


Make requests for information from the UK Government

        <% form_for(:info_request, @info_request, :url => { :controller => :new, :action => :index }, :html => { :id => 'public_body_form', :class => 'plaque' }  ) do |f| %>

Choose which public body you would like information from.

           <%= @public_bodies = PublicBody.find(:all, :order => "name")
               f.collection_select(:public_body_id, @public_bodies, :id, :name) %>

<%= submit_tag "Submit >>" %>

        <% end %>

Find information that others requested

View all information

Fix form link on front page to use new controller layout.

Make requests for information from the UK Government

        <% form_for(:info_request, @info_request, :url => { :controller => :request, :action => :new }, :html => { :id => 'public_body_form', :class => 'plaque' }  ) do |f| %>

Choose which public body you would like information from.

           <%= @public_bodies = PublicBody.find(:all, :order => "name")
               f.collection_select(:public_body_id, @public_bodies, :id, :name) %>

<%= submit_tag "Submit >>" %>

        <% end %>

Find information that others requested

View all information


Create a user account

Fill in the form and we'll send you a quick email to activate your account.

By creating an account, you agree that all work uploaded to openstreetmap.org and all data created by use of any tools which connect to openstreetmap.org is to be licensed under this Creative Commons license (by-sa).

<%= error_messages_for 'user' %>

<% form_tag :action => 'save' do %>

email:	<%= text_field('user', 'email',{:size => 50, :maxlength => 255}) %>

login name	<%= text_field('user', 'display_name',{:size => 50, :maxlength => 255}) %>

password:	<%= password_field('user', 'pass_crypt',{:size => 50, :maxlength => 255}) %>

retype password:	<%= password_field('user', 'pass_crypt_confirmation',{:size => 50, :maxlength => 255}) %>

<input type="submit" value="Signup">

<% end %>

Make field names consistent with the account editing page.

Create a user account

Fill in the form and we'll send you a quick email to activate your account.

By creating an account, you agree that all work uploaded to openstreetmap.org and all data created by use of any tools which connect to openstreetmap.org is to be licensed under this Creative Commons license (by-sa).

<%= error_messages_for 'user' %>

<% form_tag :action => 'save' do %>

Email	<%= text_field('user', 'email',{:size => 50, :maxlength => 255}) %>

Display Name	<%= text_field('user', 'display_name',{:size => 50, :maxlength => 255}) %>

Password	<%= password_field('user', 'pass_crypt',{:size => 50, :maxlength => 255}) %>

Confirm Password	<%= password_field('user', 'pass_crypt_confirmation',{:size => 50, :maxlength => 255}) %>

<input type="submit" value="Signup">

<% end %>


The Carbon Diet

Sign In

<% if flash[:notice] %>

<%=h flash[:notice] %>

<% end %>

<%= form_tag :action => 'auth' %>

Username:

<%= text_field 'user', 'login'  %>

Password:

<%= password_field 'user', 'password' %>

Remember me <%= check_box 'user', 'remember' %>

<%= submit_tag 'Log In' %>

<%= end %>

Fix to mobile login page

The Carbon Diet

Sign In

<% if flash[:notice] %>

<%=h flash[:notice] %>

<% end %>

<% form_tag :action => 'auth' do %>

Username:

<%= text_field 'user', 'login'  %>

Password:

<%= password_field 'user', 'password' %>

Remember me <%= check_box 'user', 'remember' %>

<%= submit_tag 'Log In' %>

<% end %>


        <%= link_to 'Alaveteli', main_url('/'), :class => "brand" %>

<%= link_to 'Summary', admin_url("") %>

<%= link_to 'Timeline', admin_url("timeline") %>

<%= link_to 'Stats', admin_url("stats") %>

<%= link_to 'Debug', admin_url("debug") %>

<%= link_to 'Authorities', admin_url("body/list") %>

<%= link_to 'Requests', admin_url("request/list") %>

<%= link_to 'Users', admin_url("user/list") %>

<%= link_to 'Tracks', admin_url("track/list") %>

<%= link_to 'Log out', signout_path %>

Add extra div to get namespacing of admin navbar classes right.


<% content_for :left_menu do %>
<%= link_to_function "Map key", "showKey();" %>
<% end %>

Use the z13 key for z13 and over.


<tr class="inbox-row<%= "-unread" if not message_summary.message_read? %>">
  <%= link_to message_summary.sender.display_name , :controller => 'user', :action => message_summary.sender.display_name %>

    <% if message_summary.title.nil? or message_summary.title == '' %>
      <%= link_to '(no subject)' , :controller => 'message', :action => 'read', :message_id => message_summary.id  %>
    <% else %>
      <%= link_to  message_summary.title , :controller => 'message', :action => 'read', :message_id => message_summary.id  %>
    <% end %>

  <%= message_summary.sent_on %>
  <% if message_summary.message_read? %>
    <%= button_to 'Mark as unread', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'unread' %>
  <% else %>
    <%= button_to 'Mark as read', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'read' %>
  <% end %>
  <%= button_to 'Reply', :controller => 'message', :action => 'new', :user_id => message_summary.from_user_id %>

Revert SteveC's edit as blank title are now banned.

<tr class="inbox-row<%= "-unread" if not message_summary.message_read? %>">
  <%= link_to message_summary.sender.display_name , :controller => 'user', :action => message_summary.sender.display_name %>
  <%= link_to  message_summary.title , :controller => 'message', :action => 'read', :message_id => message_summary.id  %>
  <%= message_summary.sent_on %>
  <% if message_summary.message_read? %>
    <%= button_to 'Mark as unread', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'unread' %>
  <% else %>
    <%= button_to 'Mark as read', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'read' %>
  <% end %>
  <%= button_to 'Reply', :controller => 'message', :action => 'new', :user_id => message_summary.from_user_id %>


Hi,

Someone (hopefully you) would like to create an account over at
   <%= SERVER_URL %>.

If this is you, please click the link below to confirm that account.

<%= @url %>"><%= @url %>

Fix typo in HTML version of account confirmation message.

Hi,

Someone (hopefully you) would like to create an account over at
   <%= SERVER_URL %>.

If this is you, please click the link below to confirm that account.

<a href="<%= @url %>"><%= @url %>


<html>
  <head>
    <title>Amie Street Reviews</title>
    <%= stylesheet_link_tag 'arb.css' %>
    <%= javascript_include_tag :defaults %>
  </head>
  <body>

<%= yield %>

  </body>
</html>

Change stylesheet to be media "all" so that print/save to pdf keeps formatting

<html>
  <head>
    <title>Amie Street Reviews</title>
    <%= stylesheet_link_tag 'arb.css', :media => 'all' %>
    <%= javascript_include_tag :defaults %>
  </head>
  <body>

<%= yield %>

  </body>
</html>


<%= error_messages_for 'page' %>

  Location:

  /page/ <%= text_field 'page', 'name', :size => 16  %>

  Title:

  <%= text_field 'page', 'title', :size => 20  %>

  Content:

  <%= text_area 'page', 'body', :rows => 25, :cols => 65  %>

Textfilter: <%= select 'page', 'text_filter', text_filter_options %>

Fix minor typo on pages admin page

<%= error_messages_for 'page' %>

  Location:

  /pages/ <%= text_field 'page', 'name', :size => 16  %>

  Title:

  <%= text_field 'page', 'title', :size => 20  %>

  Content:

  <%= text_area 'page', 'body', :rows => 25, :cols => 65  %>

Textfilter: <%= select 'page', 'text_filter', text_filter_options %>


<%= link_to 'Back', :action => 'show_observation', :id => @comment.observation %>
<% if check_permission(@comment.user_id) %>
	| <%= link_to 'Edit', :action => 'edit_comment', :id => @comment %>
	| <%= link_to 'Destroy', :action => 'destroy_comment', :id => @comment %>
<% end %>

Comment on <%= h @comment.observation.unique_name %>

Created: <%= @comment.created.to_formatted_s(:db) %>

By: <%= @comment.user.unique_name %>

Summary: <%= @comment.summary %>

Comment: <%= textilize @comment.comment %>

Switch Back link to Goto Observsation

<%= link_to 'Goto Observation', :action => 'show_observation', :id => @comment.observation %>
<% if check_permission(@comment.user_id) %>
	| <%= link_to 'Edit', :action => 'edit_comment', :id => @comment %>
	| <%= link_to 'Destroy', :action => 'destroy_comment', :id => @comment %>
<% end %>

Comment on <%= h @comment.observation.unique_name %>

Created: <%= @comment.created.to_formatted_s(:db) %>

By: <%= @comment.user.unique_name %>

Summary: <%= @comment.summary %>

Comment: <%= textilize @comment.comment %>


<% if not Company.owner.homepage.nil? %>
            <a href="<%= Company.owner.homepage %>"><%= Company.owner.name %>
<% else %>
            <%= Company.owner.name %>
<% end %>

<%= product_signature %>

Add DryIcons credit per license

<% if not Company.owner.homepage.nil? %>
            <a href="<%= Company.owner.homepage %>"><%= Company.owner.name %>
<% else %>
            <%= Company.owner.name %>
<% end %>

<%= product_signature %>. Icons by DryIcons.


<%=_('To let everyone know, follow this link and then select the appropriate box.')%>

<%=@url%>

<%= _('Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on',:info_request=>@info_request.title)%>
<%= @info_request.public_body.name %>.

-- <%= _('the {{site_name}} team', :site_name=>site_name) %>

Revert "Let everyone know, not just us"

<%=_('To let us know, follow this link and then select the appropriate box.')%>

<%=@url%>

<%= _('Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on',:info_request=>@info_request.title)%>
<%= @info_request.public_body.name %>.

-- <%= _('the {{site_name}} team', :site_name=>site_name) %>


  <%= browse_people_menu %>

  <%= browse_communities_menu %>

  <%= browse_contents_menu %>

<%= _('Events') %>

Change base theme according to search refactor

  <%= search_people_menu %>

  <%= search_communities_menu %>

  <%= search_contents_menu %>

<%= _('Events') %>


 Would you like to work with the team that built this site? We’re recruiting.

Add class not-for-print to recruitment ad


<%= _('Select the groups where you want to publish your article') %>

<% if !@failed.blank? %>

<%=_("There were errors with the following communities: ")%>

    <% @failed.each do |error, communities|%>
       <%= error %>:

        <% communities.each do |community| %>

 <%= community %>

        <% end %>

    <% end %>

<% end %>

<% form_tag do%>
 <%= hidden_field_tag :back_to, @back_to %>
 <% @groups.each do |group| %>
    <%= labelled_check_box group.name, 'marked_groups[][group_id]', group.id, @marked_groups.include?(group) %>

    <%= labelled_text_field _('Title') + ': ', 'marked_groups[][name]', @article.name, :style => 'width: 100%' %>

  <% end %>

  <% button_bar do %>
    <%= submit_button 'spread', _('Publish') %>
    <%= button :cancel, _('Cancel'), :back %>
  <% end %>
<% end %>

Revert "Adding cancel button in Publish screen"

<%= _('Select the groups where you want to publish your article') %>

<% if !@failed.blank? %>

<%=_("There were errors with the following communities: ")%>

    <% @failed.each do |error, communities|%>
       <%= error %>:

        <% communities.each do |community| %>

 <%= community %>

        <% end %>

    <% end %>

<% end %>

<% form_tag do%>
 <%= hidden_field_tag :back_to, @back_to %>
 <% @groups.each do |group| %>
    <%= labelled_check_box group.name, 'marked_groups[][group_id]', group.id, @marked_groups.include?(group) %>

    <%= labelled_text_field _('Title') + ': ', 'marked_groups[][name]', @article.name, :style => 'width: 100%' %>

  <% end %>

  <% button_bar do %>
    <%= submit_button 'spread', _('Publish') %>
  <% end %>
<% end %>


	<%= h(example.description) %>
  <div class="failure" id="failure-<%= counter %>">

Failure/Error:
        <%= h read_failed_line(exception, example).strip.gsub(/\n/, '
') %>

%        exception.message.split("\n").each do |line|
        <%= h line %>

%        end
%        example.example_group.ancestors.push(example.example_group).each do |group|
%          if group.metadata[:shared_group_name]
            Shared Example Group: "<%= h group.metadata[:shared_group_name] %>" called from
                        "<%= backtrace_line(group.metadata[:example_group][:location]) %>
%            break
%          end
%        end

%     format_backtrace(exception.backtrace, example).each do |backtrace_info|
        <%= backtrace_info %>

%     end

  <%= extra %>

% unless log_messages.nil? || log_messages.empty?

<%= log_messages.join("\n") %>

% end

Fix shared-group formatting for RSpec 2.12.2.

	<%= h(example.description) %>
  <div class="failure" id="failure-<%= counter %>">

Failure/Error:
        <%= h read_failed_line(exception, example).strip.gsub(/\n/, '
') %>

%        exception.message.split("\n").each do |line|
        <%= h line %>

%        end
%        if group = find_shared_group( example )
            Shared Example Group: "<%= h group.metadata[:shared_group_name] %>" called from
                        "<%= backtrace_line(group.metadata[:example_group][:location]) %>
%        end

%     format_backtrace(exception.backtrace, example).each do |backtrace_info|
        <%= backtrace_info %>

%     end

  <%= extra %>

% unless log_messages.nil? || log_messages.empty?

<%= log_messages.join("\n") %>

% end


<% @page_title = 'Skapar ny sida' -%>

Skapa ny sida

<% form_for :page do |page| -%>

Titel
<%= page.text_field :title, :maxlength => 35, :size => 35  %>
<%= error_message_on @page, :title %>

Innehåll
<%= page.text_area :content, :cols => 84, :rows => 20  %>

  <%= submit_tag 'Skapa sida' %>
	eller
  <%= link_to 'Avbryt', :action => 'list' %>

Kommentar
<%= page.text_field :comment, :maxlength => 74, :size => 50 %>

Sidbeskrivning
<%= page.text_area :description, :cols => 50, :rows => 3 %>

Formatering
<%= page.select :markup, markups_available %>

<% end -%>

Move the comment box for the create page too


	  Wiki
	  Forum
	  Sign up!
	  Explore
	  Home

Fix link of logo on portal pages

	  Wiki
	  Forum
	  Sign up!
	  Explore
	  Home


<% if logged_in? and logged_in_person.permitted?("edit", @question.questionnaire) -%>
  <% if @editing -%>
    <%= text_area_tag "answer[#{@question.id}]", value, :rows => 4 %>
  <% else -%>
    <%= simple_format value %>
  <% end -%>
<% end -%>

Fix view permissioning on annotation fields - you don't need to be a questionnaire editor to see them

<% if @editing -%>
  <% if logged_in? and logged_in_person.permitted?("edit_answers", @question.questionnaire) -%>
    <%= text_area_tag "answer[#{@question.id}]", value, :rows => 4 %>
  <% end -%>
<% else -%>
  <% if logged_in? and logged_in_person.permitted?("view_answers", @question.questionnaire) -%>
    <%= simple_format value %>
  <% end -%>
<% end -%>


<h4> </h4>
<%
	# This assumes that the association is included as a column in the active_scaffold_config.columns collection
	associated_columns = []
	associated_columns = params[:associations].split(" ") unless params[:associations].nil?
	unless associated_columns.empty?
		parent_id = params[:id]
		associated_columns.each do | column_name |
			association = active_scaffold_config.columns[column_name].association
			controller, controller_path = active_scaffold_controller_for(association.klass, params[:controller])
			table_name = association.table_name
			table_name = association.options[:join_table] if association.macro == :has_and_belongs_to_many
			primary_key = table_name + "." + association.primary_key_name
%>
		<%= render :active_scaffold => controller_path, :constraints => { primary_key.to_sym => parent_id}, :label => active_scaffold_config_for(association.klass).label + _("FOR") + active_scaffold_config.label, :options => {:association => column_name, :association_macro => association.macro, :parent_model => association.active_record} %>
<%
		end
  end
%>

Support :has_many :through nested scaffolds.

<h4> </h4>
<%
	# This assumes that the association is included as a column in the active_scaffold_config.columns collection
	associated_columns = []
	associated_columns = params[:associations].split(" ") unless params[:associations].nil?
	unless associated_columns.empty?
		parent_id = params[:id]
		associated_columns.each do | column_name |
			association = active_scaffold_config.columns[column_name].association
			controller, controller_path = active_scaffold_controller_for(association.klass, params[:controller])
			table_name = association.table_name
			table_name = association.options[:join_table] if association.macro == :has_and_belongs_to_many
			table_name = association.through_reflection.table_name if association.options[:through]
			primary_key = table_name + "." + association.primary_key_name
%>
		<%= render :active_scaffold => controller_path, :constraints => { primary_key.to_sym => parent_id}, :label => active_scaffold_config_for(association.klass).label + _("FOR") + active_scaffold_config.label, :options => {:association => column_name, :association_macro => association.macro, :parent_model => association.active_record} %>
<%
		end
  end
%>


Diff is <%= @diff.inspect %>

<% @diff.chunks.each do |chunk| %>

      Src file:
      <%=h chunk.src_files.join(", ") %>

      Dst file:
      <%=h chunk.dst_file %>

  <% chunk.lines.each do |line| %>

      <% line.line_numbers.each do |n| %>
        <%=h n.nil? ? "-" : n %>
      <% end %>

<%=h line.line.chomp %>

  <% end %>

  Chunk: <%= chunk %>

<% end %>

Fix display of empty lines

Diff is <%= @diff.inspect %>

<% @diff.chunks.each do |chunk| %>

      Src file:
      <%=h chunk.src_files.join(", ") %>

      Dst file:
      <%=h chunk.dst_file %>

  <% chunk.lines.each do |line| %>

      <% line.line_numbers.each do |n| %>
        <%=h n.nil? ? "-" : n %>
      <% end %>

        <% if line.line.empty? %>

        <% else %>

<%=h line.line %>

        <% end %>

  <% end %>

  Chunk: <%= chunk %>

<% end %>


<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">

        <%# When not logged in, but mid-comment-leaving, there'll be no comment.user %>
        <%= !comment.user || (!@user.nil? && @user.id == comment.user.id) ? "You" : user_link(comment.user) %>
        left an annotation (<%= simple_date(comment.created_at || Time.now) %>)

<%= comment.get_body_for_html_display %>

        <% if !comment.id.nil? %>
            <%= link_to "Link to this", comment_url(comment) %>
            <% if !@user.nil? && @user.admin_page_links? %>
                | <%= link_to "Admin", admin_url("request/edit_comment/" + comment.id.to_s) %>
            <% end %>

        <% end %>

Use user_or_you_capital_link instead of hand-rolling

<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">

        <%# When not logged in, but mid-comment-leaving, there'll be no comment.user %>
        <%= comment.user ? user_or_you_capital_link(comment.user) : "You" %>
        left an annotation (<%= simple_date(comment.created_at || Time.now) %>)

<%= comment.get_body_for_html_display %>

        <% if !comment.id.nil? %>
            <%= link_to "Link to this", comment_url(comment) %>
            <% if !@user.nil? && @user.admin_page_links? %>
                | <%= link_to "Admin", admin_url("request/edit_comment/" + comment.id.to_s) %>
            <% end %>

        <% end %>


<%= @outgoing_message.body.strip %>

-------------------------------------------------------------------
Is <%= @info_request.public_body.request_email%> the wrong address for Freedom
of Information requests to <%= @info_request.public_body.name%>? If so please
let us know by emailing <%=@contact_email%>. We'll make sure future ones go to
the right place.
-------------------------------------------------------------------

Make sure there isn't a full stop immediately after our email, in case some mail clients include it in the address

<%= @outgoing_message.body.strip %>

-------------------------------------------------------------------
Is <%= @info_request.public_body.request_email%> the wrong address for Freedom
of Information requests to <%= @info_request.public_body.name%>? If so please
let us know by emailing <%=@contact_email%> - we'll make sure future ones go to
the right place.
-------------------------------------------------------------------


  <%= _('Textile markup quick reference') %>
  <%= link_to(_('(show)'), '#', :id => 'textile-quickref-show') %>
  <%= link_to(_('(hide)'), '#', :id => 'textile-quickref-hide', :style => 'display: none') %>

<%= _('Simple formatting:') %> _<%= _('italics') %>_ *<%= _('bold') %>*, -<%= _('striked')%>-.

<%= _('Links:') %> "Noosfero":http://noosfero.org/

<%= _('Images:') %> !http://example.com/image.png!

<%= _('Bullet lists:') %>

* <%= _('first item') %>
* <%= _('second item') %>

<%= _('Numbered lists:') %>

# <%= _('first item') %>
# <%= _('second item') %>

<%= _('See also a more complete Textile Reference') % 'http://redcloth.org/hobix.com/textile/' %>

Add syntax for code to textile quick reference

  <%= _('Textile markup quick reference') %>
  <%= link_to(_('(show)'), '#', :id => 'textile-quickref-show') %>
  <%= link_to(_('(hide)'), '#', :id => 'textile-quickref-hide', :style => 'display: none') %>

<%= _('Simple formatting:') %> _<%= _('italics') %>_ *<%= _('bold') %>*, -<%= _('striked')%>-.

<%= _('Links:') %> "Noosfero":http://noosfero.org/

<%= _('Images:') %> !http://example.com/image.png!

<%= _('Bullet lists:') %>

* <%= _('first item') %>
* <%= _('second item') %>

<%= _('Numbered lists:') %>

# <%= _('first item') %>
# <%= _('second item') %>

<%= h(_('For code, use HTML tags
 and , and indent the code inside them:')) %>

<pre>
<code>
  a.gsub!( /</, '' )
</code>
</pre>

<%= _('See also a more complete Textile Reference.') % 'http://redcloth.org/hobix.com/textile/' %>


<% user_id = params[:user_id] || @user_id %>
<% display_name = User.find_by_id(user_id).display_name %>

Send a new message to <%= h(display_name) %>

<% if params[:display_name] %>

Writing a new message to <%= h(params[:display_name]) %>

TODO: drop down box of your friends

<%end%>

<%= error_messages_for 'message' %>

<% form_for :message, :url => { :action => "new", :user_id => user_id } do |f| %>

      Subject
      <%= f.text_field :title, :size => 60, :value => @title %>

      Body
      <%= f.text_area :body, :cols => 80, :value => @body %>

      <%= submit_tag 'Send', :action => 'new' %>

<% end %>

<%= link_to 'Back to inbox', :controller => 'message', :action => 'inbox', :display_name => @user.display_name %>

Remove bogus action attribute from the submit button - it should have no effect as there is no such attribute defined, but Opera seems to decide that it should post the form to that URL instead of the one give on the form element.

<% user_id = params[:user_id] || @user_id %>
<% display_name = User.find_by_id(user_id).display_name %>

Send a new message to <%= h(display_name) %>

<% if params[:display_name] %>

Writing a new message to <%= h(params[:display_name]) %>

TODO: drop down box of your friends

<%end%>

<%= error_messages_for 'message' %>

<% form_for :message, :url => { :action => "new", :user_id => user_id } do |f| %>

      Subject
      <%= f.text_field :title, :size => 60, :value => @title %>

      Body
      <%= f.text_area :body, :cols => 80, :value => @body %>

      <%= submit_tag 'Send' %>

<% end %>

<%= link_to 'Back to inbox', :controller => 'message', :action => 'inbox', :display_name => @user.display_name %>


<%= render :file => 'shared/tiny_mce' %>

<%= labelled_form_field(_('Text'), text_area(:article, 'body', :cols => 40, :style => 'width:99%')) %>

Fix use of tinymce on enterprise homepage

<%= render :file => 'shared/tiny_mce' %>

<%= labelled_form_field(_('Text'), text_area(:article, 'body', :cols => 40, :style => 'width:99%', :class => 'mceEditor')) %>


<% content_for :left_menu do %>
<%= link_to_function "Map key", "showKey();" %>
<% end %>

Use correct key for z15 and greater.


The following teams are associated with this organisation.

<% for team in @teams %>

<%= link_to team.title,  team_url(:team => team) %>
<% end %>

<% if authorised? %>

More

<%= link_to 'New team...', new_team_url %>

<% end %>

All done?

<%= link_to 'Return to home', home_url %>

Handle when no teams to list for organisation.

  <% if @teams.empty? -%>

There are no teams yet.

  <% else -%>

The following teams are associated with this organisation.

<% for team in @teams %>

<%= link_to team.title,  team_url(:team => team) %>
<% end %>

  <% end -%>

<% if authorised? %>

More

<%= link_to 'New team...', new_team_url %>

<% end %>

All done?

<%= link_to 'Return to home', home_url %>


    <%= generate_assets_menu %>

Fix the assets menu in scarletred theme


<% @title = "Unclassified responses" %>

<%=@title%>

Classify responses that are still unclassified <%=InfoRequest::OLD_AGE_IN_DAYS.inspect %> after response:

<% for @request in @info_requests %>

        <%= request_both_links(@request) %>
        – <%=simple_date(@request.get_last_response_event.created_at)%>

<% end %>

Add pagination to old unclassified requests.

<% @title = "Unclassified responses" %>

<%=@title%>

Classify responses that are still unclassified <%=InfoRequest::OLD_AGE_IN_DAYS.inspect %> after response:

<% for @request in @info_requests %>

        <%= request_both_links(@request) %>
        – <%=simple_date(@request.get_last_response_event.created_at)%>

<% end %>

<%= will_paginate(@info_requests, :class => "paginator") %>


<% article = article_common %>

<%= render :partial => 'article_author', :object => article %>
<%= render :partial => 'article_description', :object => article %>
<%= render :partial => 'article_tags', :object => article.tags %>
<%= render :partial => 'article_categories', :object => article.categories %>
<%= render :partial => 'article_last_change', :object => article %>

Add option to remove description

<% article = article_common %>
<% show_description = true if show_description.nil? %>

<%= render :partial => 'article_author', :object => article %>
<%= render :partial => 'article_description', :object => article if show_description %>
<%= render :partial => 'article_tags', :object => article.tags %>
<%= render :partial => 'article_categories', :object => article.categories %>
<%= render :partial => 'article_last_change', :object => article %>


<%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %>
<% remote_form_for(@product,
                   :loading => "small_loading('product-description-form')",
                   :update => 'product-description',
                   :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'description'},
                   :html => {:id => 'product-description-form', :method => 'post'}) do |f| %>

  <%= labelled_form_field(_('Description:'), f.text_area(:description, :rows => 15, :style => 'width: 90%;', :class => 'mceEditor')) %>
  <% button_bar do %>
    <%= submit_button :save, _('Save') %>
    <%= cancel_edit_product_link(@product, 'description') %>
  <% end %>

<% end %>

Save to tinymce on ajax form

<%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %>
<% remote_form_for(@product,
                   :loading => "small_loading('product-description-form')",
                   :before => ("tinymce.editors[0].save()" unless Rails.env == 'test'),
                   :update => 'product-description',
                   :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'description'},
                   :html => {:id => 'product-description-form', :method => 'post'}) do |f| %>

  <%= labelled_form_field(_('Description:'), f.text_area(:description, :rows => 15, :style => 'width: 90%;', :class => 'mceEditor')) %>
  <% button_bar do %>
    <%= submit_button :save, _('Save') %>
    <%= cancel_edit_product_link(@product, 'description') %>
  <% end %>

<% end %>


<% content_for :left_menu do %>
<%= link_to_function t('site.key.map_key'), "showKey();" %>
<% end %>

Update key when the zoom changes, even if the language is not english.