text:
<?php

use Symfony\Component\Translation\MessageCatalogue;

$catalogue = new MessageCatalogue('ca', array (
  'validators' =>
  array (
    'This value should be false.' => 'Aquest valor hauria de ser fals.',
    'This value should be true.' => 'Aquest valor hauria de ser cert.',
    'This value should be of type {{ type }}.' => 'Aquest valor hauria de ser del tipus {{ type }}.',
    'This value should be blank.' => 'Aquest valor hauria d\'estar buit.',
    'The value you selected is not a valid choice.' => 'El valor seleccionat no és una opció vàlida.',
    'You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.' => 'Ha de seleccionar almenys {{ limit }} opció.|Ha de seleccionar almenys {{ limit }} opcions.',
    'You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.' => 'Ha de seleccionar com a màxim {{ limit }} opció.|Ha de seleccionar com a màxim {{ limit }} opcions.',
    'One or more of the given values is invalid.' => 'Un o més dels valors facilitats són incorrectes.',
    'This field was not expected.' => 'Aquest camp no s\'esperava.',
    'This field is missing.' => 'Aquest camp està desaparegut.',
    'This value is not a valid date.' => 'Aquest valor no és una data vàlida.',
    'This value is not a valid datetime.' => 'Aquest valor no és una data i hora vàlida.',
    'This value is not a valid email address.' => 'Aquest valor no és una adreça d\'email vàlida.',
    'The file could not be found.' => 'No s\'ha pogut trobar l\'arxiu.',
    'The file is not readable.' => 'No es pot llegir l\'arxiu.',
    'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.' => 'L\'arxiu és massa gran ({{ size }} {{ suffix }}). La grandària màxima permesa és {{ limit }} {{ suffix }}.',
    'The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.' => 'El tipus mime de l\'arxiu no és vàlid ({{ type }}). Els tipus mime vàlids són {{ types }}.',
    'This value should be {{ limit }} or less.' => 'Aquest valor hauria de ser {{ limit }} o menys.',
    'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.' => 'Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcter o menys.|Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcters o menys.',
    'This value should be {{ limit }} or more.' => 'Aquest valor hauria de ser {{ limit }} o més.',
    'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.' => 'Aquest valor és massa curt. Hauria de tenir {{ limit }} caràcters o més.',
    'This value should not be blank.' => 'Aquest valor no hauria d\'estar buit.',
    'This value should not be null.' => 'Aquest valor no hauria de ser null.',
    'This value should be null.' => 'Aquest valor hauria de ser null.',
    'This value is not valid.' => 'Aquest valor no és vàlid.',
    'This value is not a valid time.' => 'Aquest valor no és una hora vàlida.',
    'This value is not a valid URL.' => 'Aquest valor no és una URL vàlida.',
    'The two values should be equal.' => 'Els dos valors haurien de ser iguals.',
    'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.' => 'L\'arxiu és massa gran. El tamany màxim permés és {{ limit }} {{ suffix }}.',
    'The file is too large.' => 'L\'arxiu és massa gran.',
    'The file could not be uploaded.' => 'No es pot pujar l\'arxiu.',
    'This value should be a valid number.' => 'Aquest valor hauria de ser un nombre vàlid.',
    'This file is not a valid image.' => 'L\'arxiu no és una imatge vàlida.',
    'This is not a valid IP address.' => 'Això no és una adreça IP vàlida.',
    'This value is not a valid language.' => 'Aquest valor no és un idioma vàlid.',
    'This value is not a valid locale.' => 'Aquest valor no és una localització vàlida.',
    'This value is not a valid country.' => 'Aquest valor no és un país vàlid.',
    'This value is already used.' => 'Aquest valor ja s\'ha utilitzat.',
    'The size of the image could not be detected.' => 'No s\'ha pogut determinar la grandària de la imatge.',
    'The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.' => 'L\'amplària de la imatge és massa gran ({{ width }}px). L\'amplària màxima permesa són {{ max_width }}px.',
    'The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.' => 'L\'amplària de la imatge és massa petita ({{ width }}px). L\'amplària mínima requerida són {{ min_width }}px.',
    'The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.' => 'L\'altura de la imatge és massa gran ({{ height }}px). L\'altura màxima permesa són {{ max_height }}px.',
    'The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.' => 'L\'altura de la imatge és massa petita ({{ height }}px). L\'altura mínima requerida són {{ min_height }}px.',
    'This value should be the user\'s current password.' => 'Aquest valor hauria de ser la contrasenya actual de l\'usuari.',
    'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.' => 'Aquest valor hauria de tenir exactament {{ limit }} caràcter.|Aquest valor hauria de tenir exactament {{ limit }} caràcters.',
    'The file was only partially uploaded.' => 'L\'arxiu va ser només pujat parcialment.',
    'No file was uploaded.' => 'Cap arxiu va ser pujat.',
    'No temporary folder was configured in php.ini.' => 'Cap carpeta temporal va ser configurada en php.ini.',
    'Cannot write temporary file to disk.' => 'No es va poder escriure l\'arxiu temporal en el disc.',
    'A PHP extension caused the upload to fail.' => 'Una extensió de PHP va fer que la pujada fallara.',
    'This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.' => 'Aquesta col·lecció ha de contenir {{ limit }} element o més.|Aquesta col·lecció ha de contenir {{ limit }} elements o més.',
    'This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.' => 'Aquesta col·lecció ha de contenir {{ limit }} element o menys.|Aquesta col·lecció ha de contenir {{ limit }} elements o menys.',
    'This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.' => 'Aquesta col·lecció ha de contenir exactament {{ limit }} element.|Aquesta col·lecció ha de contenir exactament {{ limit }} elements.',
    'Invalid card number.' => 'Número de targeta invàlid.',
    'Unsupported card type or invalid card number.' => 'Tipus de targeta no suportada o número de targeta invàlid.',
    'This is not a valid International Bank Account Number (IBAN).' => 'Això no és un nombre de compte bancari internacional (IBAN) vàlid.',
    'This value is not a valid ISBN-10.' => 'Aquest valor no és un ISBN-10 vàlid.',
    'This value is not a valid ISBN-13.' => 'Aquest valor no és un ISBN-13 vàlid.',
    'This value is neither a valid ISBN-10 nor a valid ISBN-13.' => 'Aquest valor no és ni un ISBN-10 vàlid ni un ISBN-13 vàlid.',
    'This value is not a valid ISSN.' => 'Aquest valor no és un ISSN vàlid.',
    'This value is not a valid currency.' => 'Aquest valor no és una divisa vàlida.',
    'This value should be equal to {{ compared_value }}.' => 'Aquest valor hauria de ser igual a {{ compared_value }}.',
    'This value should be greater than {{ compared_value }}.' => 'Aquest valor hauria de ser més gran a {{ compared_value }}.',
    'This value should be greater than or equal to {{ compared_value }}.' => 'Aquest valor hauria de ser major o igual a {{ compared_value }}.',
    'This value should be identical to {{ compared_value_type }} {{ compared_value }}.' => 'Aquest valor hauria de ser idèntic a {{ compared_value_type }} {{ compared_value }}.',
    'This value should be less than {{ compared_value }}.' => 'Aquest valor hauria de ser menor a {{ compared_value }}.',
    'This value should be less than or equal to {{ compared_value }}.' => 'Aquest valor hauria de ser menor o igual a {{ compared_value }}.',
    'This value should not be equal to {{ compared_value }}.' => 'Aquest valor no hauria de ser igual a {{ compared_value }}.',
    'This value should not be identical to {{ compared_value_type }} {{ compared_value }}.' => 'Aquest valor no hauria de idèntic a {{ compared_value_type }} {{ compared_value }}.',
    'The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.' => 'La proporció de l\'imatge és massa gran ({{ ratio }}). La màxima proporció permesa és {{ max_ratio }}.',
    'The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.' => 'La proporció de l\'imatge és massa petita ({{ ratio }}). La mínima proporció permesa és {{ max_ratio }}.',
    'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.' => 'L\'imatge és quadrada({{ width }}x{{ height }}px). Les imatges quadrades no estan permeses.',
    'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.' => 'L\'imatge està orientada horitzontalment ({{ width }}x{{ height }}px). Les imatges orientades horitzontalment no estan permeses.',
    'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.' => 'L\'imatge està orientada verticalment ({{ width }}x{{ height }}px). Les imatges orientades verticalment no estan permeses.',
    'An empty file is not allowed.' => 'No està permès un fixter buit.',
    'This form should not contain extra fields.' => 'Aquest formulari no hauria de contenir camps addicionals.',
    'The uploaded file was too large. Please try to upload a smaller file.' => 'L\'arxiu pujat és massa gran. Per favor, pugi un arxiu més petit.',
    'The CSRF token is invalid. Please try to resubmit the form.' => 'El token CSRF no és vàlid. Per favor, provi d\'enviar novament el formulari.',
    'fos_user.username.already_used' => 'El nom d\'usuari ja està sent utilitzat',
    'fos_user.username.blank' => 'Si us plau, introdueixi un nom d\'usuari',
    'fos_user.username.short' => '[-Inf,Inf]El nom d\'usuari és massa curt',
    'fos_user.username.long' => '[-Inf,Inf]El nom d\'usuari és massa llarg',
    'fos_user.email.already_used' => 'L\'adreça de correu ja està sent utilitzada',
    'fos_user.email.blank' => 'Si us plau, introdueixi una adreça de correu',
    'fos_user.email.short' => '[-Inf,Inf]L\'adreça de correu és massa curta',
    'fos_user.email.long' => '[-Inf,Inf]L\'adreça de correu és massa llarga',
    'fos_user.email.invalid' => 'L\'adreça de correu no és vàlida',
    'fos_user.password.blank' => 'Si us plau, introdueixi una contrasenya',
    'fos_user.password.short' => '[-Inf,Inf]La contrasenya és massa curta',
    'fos_user.password.mismatch' => 'Les dues contrasenyes no coincideixen',
    'fos_user.new_password.blank' => 'Si us plau, introdueixi una nova contrasenya',
    'fos_user.new_password.short' => '[-Inf,Inf]La nova contrasenya és massa curta',
    'fos_user.current_password.invalid' => 'La contrasenya no és vàlida',
    'fos_user.group.blank' => 'Si us plau, introdueix un nom de grup',
    'fos_user.group.short' => '[-Inf,Inf]El nom de grup és massa curt',
    'fos_user.group.long' => '[-Inf,Inf]El nom de grup és massa llarg',
  ),
  'security' =>
  array (
    'An authentication exception occurred.' => 'Ha succeït un error d\'autenticació.',
    'Authentication credentials could not be found.' => 'No s\'han trobat les credencials d\'autenticació.',
    'Authentication request could not be processed due to a system problem.' => 'La solicitud d\'autenticació no s\'ha pogut processar per un problema del sistema.',
    'Invalid credentials.' => 'Credencials no vàlides.',
    'Cookie has already been used by someone else.' => 'La cookie ja ha estat utilitzada per una altra persona.',
    'Not privileged to request the resource.' => 'No té privilegis per solicitar el recurs.',
    'Invalid CSRF token.' => 'Token CSRF no vàlid.',
    'Digest nonce has expired.' => 'El vector d\'inicialització (digest nonce) ha expirat.',
    'No authentication provider found to support the authentication token.' => 'No s\'ha trobat un proveïdor d\'autenticació que suporti el token d\'autenticació.',
    'No session available, it either timed out or cookies are not enabled.' => 'No hi ha sessió disponible, ha expirat o les cookies no estan habilitades.',
    'No token could be found.' => 'No s\'ha trobat cap token.',
    'Username could not be found.' => 'No s\'ha trobat el nom d\'usuari.',
    'Account has expired.' => 'El compte ha expirat.',
    'Credentials have expired.' => 'Les credencials han expirat.',
    'Account is disabled.' => 'El compte està deshabilitat.',
    'Account is locked.' => 'El compte està bloquejat.',
  ),
  'FOSUserBundle' =>
  array (
    'group.edit.submit' => 'Actualitza el grup',
    'group.show.name' => 'Nom del grup',
    'group.new.submit' => 'Crea el grup',
    'group.flash.updated' => 'S\'ha actualitzat el grup',
    'group.flash.created' => 'S\'ha creat el grup',
    'group.flash.deleted' => 'S\'ha eliminat el grup',
    'security.login.username' => 'Nom d\'usuari',
    'security.login.password' => 'Contrasenya',
    'security.login.remember_me' => 'Recorda\'m',
    'security.login.submit' => 'Entra',
    'profile.show.username' => 'Nom d\'usuari',
    'profile.show.email' => 'Correu electrònic',
    'profile.edit.submit' => 'Actualitza',
    'profile.flash.updated' => 'S\'ha actualitzat el perfil',
    'change_password.submit' => 'Canvia la contrasenya',
    'change_password.flash.success' => 'S\'ha canviat la contrasenya',
    'registration.check_email' => 'S\'ha enviat un correu electrònic a %email%. Conté un enllaç d\'activació que heu de clicar per activar el compte.',
    'registration.confirmed' => 'Enhorabona %username%, el vostre compte s\'ha activat.',
    'registration.back' => 'Torna a la pàgina original.',
    'registration.submit' => 'Registra',
    'registration.flash.user_created' => 'S\'ha creat l\'usuari correctament',
    'registration.email.subject' => 'Benvingut %username%!',
    'registration.email.message' => 'Hola %username%!

Per finalitzar l\'activació del seu compte - si us plau visiteu %confirmationUrl%

Atentament,
L\'equip.
',
    'resetting.password_already_requested' => 'La contrasenya per l\'usuari ja ha estat sol·licitada en les últimes 24 hores.',
    'resetting.check_email' => 'S\'ha enviat un correu electrònic a %email%. Conté un enllaç que heu de clicar per restablir la contrasenya.',
    'resetting.request.invalid_username' => 'El nom d\'usuari o correu electrònic "%username%" no existeix.',
    'resetting.request.username' => 'Nom d\'usuari o correu electrònic',
    'resetting.request.submit' => 'Restableix la contrasenya',
    'resetting.reset.submit' => 'Canvia la contrasenya',
    'resetting.flash.success' => 'S\'ha restablert la contrasenya correctament',
    'resetting.email.subject' => 'Restablir la contrasenya',
    'resetting.email.message' => 'Hola %username%!

Per restablir la contrasenya - si us plau visiteu %confirmationUrl%

Atentament,
L\'equip.
',
    'layout.logout' => 'Tanca la sessió',
    'layout.login' => 'Entra',
    'layout.register' => 'Registrar-se',
    'layout.logged_in_as' => 'Heu iniciat sessió com a %username%',
    'form.group_name' => 'Nom del grup',
    'form.username' => 'Nom d\'usuari',
    'form.email' => 'Correu electrònic',
    'form.current_password' => 'Contrasenya actual',
    'form.password' => 'Contrasenya',
    'form.password_confirmation' => 'Verificació',
    'form.new_password' => 'Nova contrasenya',
    'form.new_password_confirmation' => 'Verificació',
  ),
  'SonataCoreBundle' =>
  array (
    'link_add' => 'Afegeix',
    'label_type_yes' => 'sí',
    'label_type_no' => 'no',
    'sonata_core_template_box_file_found_in' => 'Aquest arxiu és pot trobar a',
    'label_type_equals' => 'és igual a',
    'label_type_not_equals' => 'no és igual a',
    'date_range_start' => 'Data inicial',
    'date_range_end' => 'Data final',
    'aliceblue' => 'aliceblue',
    'antiquewhite' => 'antiquewhite',
    'aqua' => 'aqua',
    'aquamarine' => 'aquamarine',
    'azure' => 'azure',
    'beige' => 'beige',
    'bisque' => 'bisque',
    'black' => 'Negre',
    'blanchedalmond' => 'blanchedalmond',
    'blue' => 'Blau',
    'blueviolet' => 'blueviolet',
    'brown' => 'Marró',
    'burlywood' => 'burlywood',
    'cadetblue' => 'cadetblue',
    'chartreuse' => 'chartreuse',
    'chocolate' => 'Xocolata',
    'coral' => 'Corall',
    'cornflowerblue' => 'cornflowerblue',
    'cornsilk' => 'cornsilk',
    'crimson' => 'crimson',
    'cyan' => 'cyan',
    'darkblue' => 'Blau fosc',
    'darkcyan' => 'darkcyan',
    'darkgoldenrod' => 'darkgoldenrod',
    'darkgray' => 'Gris fosc',
    'darkgreen' => 'darkgreen',
    'darkkhaki' => 'darkkhaki',
    'darkmagenta' => 'darkmagenta',
    'darkolivegreen' => 'darkolivegreen',
    'darkorange' => 'darkorange',
    'darkorchid' => 'darkorchid',
    'darkred' => 'Vermell fosc',
    'darksalmon' => 'Salmó fosc',
    'darkseagreen' => 'darkseagreen',
    'darkslateblue' => 'darkslateblue',
    'darkslategray' => 'darkslategray',
    'darkturquoise' => 'darkturquoise',
    'darkviolet' => 'Lila fosc',
    'deeppink' => 'deeppink',
    'deepskyblue' => 'deepskyblue',
    'dimgray' => 'dimgray',
    'dodgerblue' => 'dodgerblue',
    'firebrick' => 'firebrick',
    'floralwhite' => 'floralwhite',
    'forestgreen' => 'forestgreen',
    'fuchsia' => 'Fúcsia',
    'gainsboro' => 'gainsboro',
    'ghostwhite' => 'ghostwhite',
    'gold' => 'Or',
    'goldenrod' => 'goldenrod',
    'gray' => 'Gris',
    'green' => 'Verd',
    'greenyellow' => 'greenyellow',
    'honeydew' => 'honeydew',
    'hotpink' => 'hotpink',
    'indianred' => 'indianred',
    'indigo' => 'indigo',
    'ivory' => 'Ivori',
    'khaki' => 'khaki',
    'lavender' => 'lavender',
    'lavenderblush' => 'lavenderblush',
    'lawngreen' => 'lawngreen',
    'lemonchiffon' => 'lemonchiffon',
    'lightblue' => 'lightblue',
    'lightcoral' => 'lightcoral',
    'lightcyan' => 'lightcyan',
    'lightgoldenrodyellow' => 'lightgoldenrodyellow',
    'lightgray' => 'Gris clar',
    'lightgreen' => 'Verd clar',
    'lightpink' => 'Rosa clar',
    'lightsalmon' => 'Salmó clar',
    'lightseagreen' => 'lightseagreen',
    'lightskyblue' => 'lightskyblue',
    'lightslategray' => 'lightslategray',
    'lightsteelblue' => 'lightsteelblue',
    'lightyellow' => 'Groc clar',
    'lime' => 'Llima',
    'limegreen' => 'limegreen',
    'linen' => 'linen',
    'magenta' => 'Magenta',
    'maroon' => 'Granat',
    'mediumaquamarine' => 'mediumaquamarine',
    'mediumblue' => 'mediumblue',
    'mediumorchid' => 'mediumorchid',
    'mediumpurple' => 'mediumpurple',
    'mediumseagreen' => 'mediumseagreen',
    'mediumslateblue' => 'mediumslateblue',
    'mediumspringgreen' => 'mediumspringgreen',
    'mediumturquoise' => 'mediumturquoise',
    'mediumvioletred' => 'mediumvioletred',
    'midnightblue' => 'midnightblue',
    'mintcream' => 'mintcream',
    'mistyrose' => 'mistyrose',
    'moccasin' => 'moccasin',
    'navajowhite' => 'navajowhite',
    'navy' => 'navy',
    'oldlace' => 'oldlace',
    'olive' => 'Oliva',
    'olivedrab' => 'olivedrab',
    'orange' => 'Taronja',
    'orangered' => 'orangered',
    'orchid' => 'orchid',
    'palegoldenrod' => 'palegoldenrod',
    'palegreen' => 'palegreen',
    'paleturquoise' => 'paleturquoise',
    'palevioletred' => 'palevioletred',
    'papayawhip' => 'papayawhip',
    'peachpuff' => 'peachpuff',
    'peru' => 'peru',
    'pink' => 'Rosa',
    'plum' => 'plum',
    'powderblue' => 'powderblue',
    'purple' => 'Porpra',
    'rebeccapurple' => 'rebeccapurple',
    'red' => 'Vermell',
    'rosybrown' => 'rosybrown',
    'royalblue' => 'royalblue',
    'saddlebrown' => 'saddlebrown',
    'salmon' => 'Salmó',
    'sandybrown' => 'sandybrown',
    'seagreen' => 'seagreen',
    'seashell' => 'seashell',
    'sienna' => 'sienna',
    'silver' => 'Plata',
    'skyblue' => 'skyblue',
    'slateblue' => 'slateblue',
    'slategray' => 'slategray',
    'snow' => 'Neu',
    'springgreen' => 'springgreen',
    'steelblue' => 'steelblue',
    'tan' => 'tan',
    'teal' => 'teal',
    'thistle' => 'thistle',
    'tomato' => 'tomato',
    'turquoise' => 'Turquesa',
    'violet' => 'Violeta',
    'wheat' => 'Blat',
    'white' => 'Blanc',
    'whitesmoke' => 'whitesmoke',
    'yellow' => 'Groc',
    'yellowgreen' => 'yellowgreen',
  ),
  'SonataAdminBundle' =>
  array (
    'sonata_administration' => 'Administració',
    'action_delete' => 'Elimina',
    'btn_batch' => 'D\'acord',
    'btn_create' => 'Crea',
    'btn_create_and_edit_again' => 'Crea',
    'btn_create_and_create_a_new_one' => 'Crea i afegeix-ne un altre',
    'btn_create_and_return_to_list' => 'Crea i tanca',
    'btn_filter' => 'Filtra',
    'btn_update' => 'Actualitza',
    'btn_update_and_edit_again' => 'Actualitza',
    'btn_update_and_return_to_list' => 'Actualitza i tanca',
    'link_delete' => 'Elimina',
    'link_action_create' => 'Afegeix',
    'link_action_list' => 'Torna a la llista',
    'link_action_show' => 'Mostra',
    'link_action_edit' => 'Edita',
    'link_add' => 'Afegeix',
    'link_list' => 'Llista',
    'link_reset_filter' => 'Restableix',
    'title_create' => 'Crea',
    'title_dashboard' => 'Tauler',
    'title_edit' => 'Edita "%name%"',
    'title_list' => 'Llista',
    'link_next_pager' => 'Següent',
    'link_previous_pager' => 'Anterior',
    'link_first_pager' => 'Primer',
    'link_last_pager' => 'Últim',
    'Admin' => 'Administració',
    'link_expand' => 'expandeix/contrau',
    'no_result' => 'No s\'han trobat resultats.',
    'confirm_msg' => 'Esteu segur?',
    'action_edit' => 'Edita',
    'action_show' => 'Mostra',
    'all_elements' => 'Tots els elements',
    'flash_batch_empty' => 'Acció interrompuda. No hi ha elements seleccionats.',
    'flash_create_success' => 'S\'ha creat correctament l\'element.',
    'flash_create_error' => 'S\'ha produït un error durant la creació de l\'element.',
    'flash_edit_success' => 'S\'ha actualitzat correctament l\'element.',
    'flash_edit_error' => 'S\'ha produït un error durant l\'actualització de l\'element.',
    'flash_batch_delete_success' => 'S\'han eliminat correctament els elements seleccionats.',
    'flash_batch_delete_error' => 'S\'ha produït un error durant l\'eliminació dels elements seleccionats.',
    'flash_delete_error' => 'S\'ha produït un error durant l\'eliminació de l\'element.',
    'flash_delete_success' => 'S\'ha eliminat correctament l\'element.',
    'breadcrumb.link_dashboard' => '<i class="fa fa-home"></i>',
    'title_delete' => 'Confirma l\'eliminació',
    'message_delete_confirmation' => 'Esteu segur que voleu eliminar l\'element seleccionat?',
    'btn_delete' => 'Sí, elimina',
    'title_batch_confirmation' => 'Confirma l\'acció per lots',
    'message_batch_confirmation' => 'Esteu segur que voleu confirmar aquesta acció i executar-la per tots els elements seleccionats?|[1,+Inf[Esteu segur que voleu confirmar aquesta acció i executar-la per tots els %count% elements seleccionats?',
    'message_batch_all_confirmation' => 'message_batch_all_confirmation',
    'btn_execute_batch_action' => 'Sí, executa',
    'label_type_yes' => 'sí',
    'label_type_no' => 'no',
    'label_type_contains' => 'conté',
    'label_type_not_contains' => 'no conté',
    'label_type_equals' => 'és igual a',
    'label_type_not_equals' => 'no és igual a',
    'label_type_equal' => '=',
    'label_type_greater_equal' => '>=',
    'label_type_greater_than' => '>',
    'label_type_less_equal' => '<=',
    'label_type_less_than' => '<',
    'label_date_type_equal' => '=',
    'label_date_type_greater_equal' => '>=',
    'label_date_type_greater_than' => '>',
    'label_date_type_less_equal' => '<=',
    'label_date_type_less_than' => '<',
    'label_date_type_null' => 'està buit',
    'label_date_type_not_null' => 'no està buit',
    'label_date_type_between' => 'entre',
    'label_date_type_not_between' => 'no entre',
    'label_filters' => 'Filtres',
    'delete_or' => 'o',
    'link_action_history' => 'Revisions',
    'td_action' => 'Acció',
    'td_revision' => 'Revisions',
    'td_timestamp' => 'Data',
    'td_username' => 'Autor',
    'label_view_revision' => 'Mostrar revisió',
    'list_results_count' => '1 resultat|%count% resultats',
    'label_export_download' => 'Exportar',
    'loading_information' => 'S\'està carregant informació…',
    'btn_preview' => 'Vista prèvia',
    'btn_preview_approve' => 'Aprovar',
    'btn_preview_decline' => 'Cancel·lar',
    'label_per_page' => 'Per pàgina',
    'list_select' => 'Seleccionar',
    'confirm_exit' => 'Tens canvis sense guardar',
    'link_edit_acl' => 'Editar ACL',
    'btn_update_acl' => 'Actualitzar ACL',
    'flash_acl_edit_success' => 'ACL actualitzada correctament.',
    'link_action_acl' => 'ACL',
    'short_object_description_placeholder' => 'Cap selecció',
    'title_search_results' => 'Resultats de la cerca: %query%',
    'search_placeholder' => 'Cercar',
    'no_results_found' => 'No s\'han trobat resultats',
    'add_new_entry' => 'afegir nova entrada',
    'link_actions' => 'Accions',
    'noscript_warning' => 'Javascript està desconnectat al seu navegador web. Algunes característiques no funcionaran correctament.',
    'message_form_group_empty' => 'No hi ha camps disponibles.',
  ),
));

$catalogueFr = new MessageCatalogue('fr', array (
  'validators' =>
  array (
    'This value should be false.' => 'Cette valeur doit être fausse.',
    'This value should be true.' => 'Cette valeur doit être vraie.',
    'This value should be of type {{ type }}.' => 'Cette valeur doit être de type {{ type }}.',
    'This value should be blank.' => 'Cette valeur doit être vide.',
    'The value you selected is not a valid choice.' => 'Cette valeur doit être l\'un des choix proposés.',
    'You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.' => 'Vous devez sélectionner au moins {{ limit }} choix.|Vous devez sélectionner au moins {{ limit }} choix.',
    'You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.' => 'Vous devez sélectionner au maximum {{ limit }} choix.|Vous devez sélectionner au maximum {{ limit }} choix.',
    'One or more of the given values is invalid.' => 'Une ou plusieurs des valeurs soumises sont invalides.',
    'This field was not expected.' => 'Ce champ n\'a pas été prévu.',
    'This field is missing.' => 'Ce champ est manquant.',
    'This value is not a valid date.' => 'Cette valeur n\'est pas une date valide.',
    'This value is not a valid datetime.' => 'Cette valeur n\'est pas une date valide.',
    'This value is not a valid email address.' => 'Cette valeur n\'est pas une adresse email valide.',
    'The file could not be found.' => 'Le fichier n\'a pas été trouvé.',
    'The file is not readable.' => 'Le fichier n\'est pas lisible.',
    'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.' => 'Le fichier est trop volumineux ({{ size }} {{ suffix }}). Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}.',
    'The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.' => 'Le type du fichier est invalide ({{ type }}). Les types autorisés sont {{ types }}.',
    'This value should be {{ limit }} or less.' => 'Cette valeur doit être inférieure ou égale à {{ limit }}.',
    'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.' => 'Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractères.',
    'This value should be {{ limit }} or more.' => 'Cette valeur doit être supérieure ou égale à {{ limit }}.',
    'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.' => 'Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractères.',
    'This value should not be blank.' => 'Cette valeur ne doit pas être vide.',
    'This value should not be null.' => 'Cette valeur ne doit pas être nulle.',
    'This value should be null.' => 'Cette valeur doit être nulle.',
    'This value is not valid.' => 'Cette valeur n\'est pas valide.',
    'This value is not a valid time.' => 'Cette valeur n\'est pas une heure valide.',
    'This value is not a valid URL.' => 'Cette valeur n\'est pas une URL valide.',
    'The two values should be equal.' => 'Les deux valeurs doivent être identiques.',
    'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.' => 'Le fichier est trop volumineux. Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}.',
    'The file is too large.' => 'Le fichier est trop volumineux.',
    'The file could not be uploaded.' => 'Le téléchargement de ce fichier est impossible.',
    'This value should be a valid number.' => 'Cette valeur doit être un nombre.',
    'This file is not a valid image.' => 'Ce fichier n\'est pas une image valide.',
    'This is not a valid IP address.' => 'Cette adresse IP n\'est pas valide.',
    'This value is not a valid language.' => 'Cette langue n\'est pas valide.',
    'This value is not a valid locale.' => 'Ce paramètre régional n\'est pas valide.',
    'This value is not a valid country.' => 'Ce pays n\'est pas valide.',
    'This value is already used.' => 'Cette valeur est déjà utilisée.',
    'The size of the image could not be detected.' => 'La taille de l\'image n\'a pas pu être détectée.',
    'The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.' => 'La largeur de l\'image est trop grande ({{ width }}px). La largeur maximale autorisée est de {{ max_width }}px.',
    'The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.' => 'La largeur de l\'image est trop petite ({{ width }}px). La largeur minimale attendue est de {{ min_width }}px.',
    'The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.' => 'La hauteur de l\'image est trop grande ({{ height }}px). La hauteur maximale autorisée est de {{ max_height }}px.',
    'The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.' => 'La hauteur de l\'image est trop petite ({{ height }}px). La hauteur minimale attendue est de {{ min_height }}px.',
    'This value should be the user\'s current password.' => 'Cette valeur doit être le mot de passe actuel de l\'utilisateur.',
    'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.' => 'Cette chaine doit avoir exactement {{ limit }} caractère.|Cette chaine doit avoir exactement {{ limit }} caractères.',
    'The file was only partially uploaded.' => 'Le fichier a été partiellement transféré.',
    'No file was uploaded.' => 'Aucun fichier n\'a été transféré.',
    'No temporary folder was configured in php.ini.' => 'Aucun répertoire temporaire n\'a été configuré dans le php.ini.',
    'Cannot write temporary file to disk.' => 'Impossible d\'écrire le fichier temporaire sur le disque.',
    'A PHP extension caused the upload to fail.' => 'Une extension PHP a empêché le transfert du fichier.',
    'This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.' => 'Cette collection doit contenir {{ limit }} élément ou plus.|Cette collection doit contenir {{ limit }} éléments ou plus.',
    'This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.' => 'Cette collection doit contenir {{ limit }} élément ou moins.|Cette collection doit contenir {{ limit }} éléments ou moins.',
    'This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.' => 'Cette collection doit contenir exactement {{ limit }} élément.|Cette collection doit contenir exactement {{ limit }} éléments.',
    'Invalid card number.' => 'Numéro de carte invalide.',
    'Unsupported card type or invalid card number.' => 'Type de carte non supporté ou numéro invalide.',
    'This is not a valid International Bank Account Number (IBAN).' => 'Le numéro IBAN (International Bank Account Number) saisi n\'est pas valide.',
    'This value is not a valid ISBN-10.' => 'Cette valeur n\'est pas un code ISBN-10 valide.',
    'This value is not a valid ISBN-13.' => 'Cette valeur n\'est pas un code ISBN-13 valide.',
    'This value is neither a valid ISBN-10 nor a valid ISBN-13.' => 'Cette valeur n\'est ni un code ISBN-10, ni un code ISBN-13 valide.',
    'This value is not a valid ISSN.' => 'Cette valeur n\'est pas un code ISSN valide.',
    'This value is not a valid currency.' => 'Cette valeur n\'est pas une devise valide.',
    'This value should be equal to {{ compared_value }}.' => 'Cette valeur doit être égale à {{ compared_value }}.',
    'This value should be greater than {{ compared_value }}.' => 'Cette valeur doit être supérieure à {{ compared_value }}.',
    'This value should be greater than or equal to {{ compared_value }}.' => 'Cette valeur doit être supérieure ou égale à {{ compared_value }}.',
    'This value should be identical to {{ compared_value_type }} {{ compared_value }}.' => 'Cette valeur doit être identique à {{ compared_value_type }} {{ compared_value }}.',
    'This value should be less than {{ compared_value }}.' => 'Cette valeur doit être inférieure à {{ compared_value }}.',
    'This value should be less than or equal to {{ compared_value }}.' => 'Cette valeur doit être inférieure ou égale à {{ compared_value }}.',
    'This value should not be equal to {{ compared_value }}.' => 'Cette valeur ne doit pas être égale à {{ compared_value }}.',
    'This value should not be identical to {{ compared_value_type }} {{ compared_value }}.' => 'Cette valeur ne doit pas être identique à {{ compared_value_type }} {{ compared_value }}.',
    'The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.' => 'Le rapport largeur/hauteur de l\'image est trop grand ({{ ratio }}). Le rapport maximal autorisé est {{ max_ratio }}.',
    'The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.' => 'Le rapport largeur/hauteur de l\'image est trop petit ({{ ratio }}). Le rapport minimal attendu est {{ min_ratio }}.',
    'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.' => 'L\'image est carrée ({{ width }}x{{ height }}px). Les images carrées ne sont pas autorisées.',
    'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.' => 'L\'image est au format paysage ({{ width }}x{{ height }}px). Les images au format paysage ne sont pas autorisées.',
    'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.' => 'L\'image est au format portrait ({{ width }}x{{ height }}px). Les images au format portrait ne sont pas autorisées.',
    'An empty file is not allowed.' => 'Un fichier vide n\'est pas autorisé.',
    'The host could not be resolved.' => 'Le nom de domaine n\'a pas pu être résolu.',
    'This value does not match the expected {{ charset }} charset.' => 'Cette valeur ne correspond pas au jeu de caractères {{ charset }} attendu.',
    'This form should not contain extra fields.' => 'Ce formulaire ne doit pas contenir des champs supplémentaires.',
    'The uploaded file was too large. Please try to upload a smaller file.' => 'Le fichier téléchargé est trop volumineux. Merci d\'essayer d\'envoyer un fichier plus petit.',
    'The CSRF token is invalid. Please try to resubmit the form.' => 'Le jeton CSRF est invalide. Veuillez renvoyer le formulaire.',
    'fos_user.username.already_used' => 'Le nom d\'utilisateur est déjà utilisé',
    'fos_user.username.blank' => 'Entrez un nom d\'utilisateur s\'il vous plait',
    'fos_user.username.short' => '[-Inf,Inf]Le nom d\'utilisateur est trop court',
    'fos_user.username.long' => '[-Inf,Inf]Le nom d\'utilisateur est trop long',
    'fos_user.email.already_used' => 'L\'adresse e-mail est déjà utilisée',
    'fos_user.email.blank' => 'Entrez une adresse e-mail s\'il vous plait',
    'fos_user.email.short' => '[-Inf,Inf]L\'adresse e-mail est trop courte',
    'fos_user.email.long' => '[-Inf,Inf]L\'adresse e-mail est trop longue',
    'fos_user.email.invalid' => 'L\'adresse e-mail est invalide',
    'fos_user.password.blank' => 'Entrez un mot de passe s\'il vous plait',
    'fos_user.password.short' => '[-Inf,Inf]Le mot de passe est trop court',
    'fos_user.password.mismatch' => 'Les deux mots de passe ne sont pas identiques',
    'fos_user.new_password.blank' => 'Entrez un nouveau mot de passe s\'il vous plait',
    'fos_user.new_password.short' => '[-Inf,Inf]Le nouveau mot de passe est trop court',
    'fos_user.current_password.invalid' => 'Le mot de passe est invalide',
    'fos_user.group.blank' => 'Entrez un nom s\'il vous plait',
    'fos_user.group.short' => '[-Inf,Inf]Le nom est trop court',
    'fos_user.group.long' => '[-Inf,Inf]Le nom est trop long',
  ),
  'security' =>
  array (
    'An authentication exception occurred.' => 'Une exception d\'authentification s\'est produite.',
    'Authentication credentials could not be found.' => 'Les identifiants d\'authentification n\'ont pas pu être trouvés.',
    'Authentication request could not be processed due to a system problem.' => 'La requête d\'authentification n\'a pas pu être executée à cause d\'un problème système.',
    'Invalid credentials.' => 'Identifiants invalides.',
    'Cookie has already been used by someone else.' => 'Le cookie a déjà été utilisé par quelqu\'un d\'autre.',
    'Not privileged to request the resource.' => 'Privilèges insuffisants pour accéder à la ressource.',
    'Invalid CSRF token.' => 'Jeton CSRF invalide.',
    'Digest nonce has expired.' => 'Le digest nonce a expiré.',
    'No authentication provider found to support the authentication token.' => 'Aucun fournisseur d\'authentification n\'a été trouvé pour supporter le jeton d\'authentification.',
    'No session available, it either timed out or cookies are not enabled.' => 'Aucune session disponible, celle-ci a expiré ou les cookies ne sont pas activés.',
    'No token could be found.' => 'Aucun jeton n\'a pu être trouvé.',
    'Username could not be found.' => 'Le nom d\'utilisateur n\'a pas pu être trouvé.',
    'Account has expired.' => 'Le compte a expiré.',
    'Credentials have expired.' => 'Les identifiants ont expiré.',
    'Account is disabled.' => 'Le compte est désactivé.',
    'Account is locked.' => 'Le compte est bloqué.',
  ),
  'messages' =>
  array (
    'Symfony2 is great' => 'J\'aime Symfony2',
  ),
  'FOSUserBundle' =>
  array (
    'group.edit.submit' => 'Mettre à jour le groupe',
    'group.show.name' => 'Nom du groupe',
    'group.new.submit' => 'Créer le groupe',
    'group.flash.updated' => 'Le groupe a été mis à jour',
    'group.flash.created' => 'Le groupe a été créé',
    'group.flash.deleted' => 'Le groupe a été supprimé',
    'security.login.username' => 'Nom d\'utilisateur',
    'security.login.password' => 'Mot de passe',
    'security.login.remember_me' => 'Se souvenir de moi',
    'security.login.submit' => 'Connexion',
    'profile.show.username' => 'Nom d\'utilisateur',
    'profile.show.email' => 'Adresse e-mail',
    'profile.edit.submit' => 'Mettre à jour',
    'profile.flash.updated' => 'Le profil a été mis à jour',
    'change_password.submit' => 'Modifier le mot de passe',
    'change_password.flash.success' => 'Le mot de passe a été modifié',
    'registration.check_email' => 'Un e-mail a été envoyé à l\'adresse %email%. Il contient un lien d\'activation sur lequel il vous faudra cliquer afin d\'activer votre compte.',
    'registration.confirmed' => 'Félicitations %username%, votre compte est maintenant activé.',
    'registration.back' => 'Retour à la page d\'origine.',
    'registration.submit' => 'Enregistrer',
    'registration.flash.user_created' => 'L\'utilisateur a été créé avec succès',
    'registration.email.subject' => 'Bienvenue %username% !',
    'registration.email.message' => 'Bonjour %username% !

Pour valider votre compte utilisateur, merci de vous rendre sur %confirmationUrl%

Cordialement,
L\'équipe.
',
    'resetting.password_already_requested' => 'Un nouveau mot de passe a déjà été demandé pour cet utilisateur dans les dernières 24 heures.',
    'resetting.check_email' => 'Un e-mail a été envoyé à l\'adresse %email%. Il contient un lien sur lequel il vous faudra cliquer afin de réinitialiser votre mot de passe.',
    'resetting.request.invalid_username' => 'Le nom d\'utilisateur ou l\'adresse e-mail "%username%" n\'existe pas.',
    'resetting.request.username' => 'Nom d\'utilisateur ou adresse e-mail',
    'resetting.request.submit' => 'Réinitialiser le mot de passe',
    'resetting.reset.submit' => 'Modifier le mot de passe',
    'resetting.flash.success' => 'Le mot de passe a été réinitialisé avec succès',
    'resetting.email.subject' => 'Réinitialisation de votre mot de passe',
    'resetting.email.message' => 'Bonjour %username% !

Pour réinitialiser votre mot de passe, merci de vous rendre sur %confirmationUrl%

Cordialement,
L\'équipe.
',
    'layout.logout' => 'Déconnexion',
    'layout.login' => 'Connexion',
    'layout.register' => 'Inscription',
    'layout.logged_in_as' => 'Connecté en tant que %username%',
    'form.group_name' => 'Nom du groupe',
    'form.username' => 'Nom d\'utilisateur',
    'form.email' => 'Adresse e-mail',
    'form.current_password' => 'Mot de passe actuel',
    'form.password' => 'Mot de passe',
    'form.password_confirmation' => 'Vérification',
    'form.new_password' => 'Nouveau mot de passe',
    'form.new_password_confirmation' => 'Vérification',
  ),
  'SonataCoreBundle' =>
  array (
    'link_add' => 'Ajouter',
    'label_type_yes' => 'oui',
    'label_type_no' => 'non',
    'sonata_core_template_box_file_found_in' => 'Ce fichier est localisé à l\'emplacement',
    'label_type_equals' => 'Est égal à',
    'label_type_not_equals' => 'Ne contient pas',
    'date_range_start' => 'Du',
    'date_range_end' => 'Au',
    'aliceblue' => 'AliceBlue',
    'antiquewhite' => 'AntiqueWhite',
    'aqua' => 'Aqua',
    'aquamarine' => 'Aquamarine',
    'azure' => 'Azure',
    'beige' => 'Beige',
    'bisque' => 'Bisque',
    'black' => 'Black',
    'blanchedalmond' => 'BlanchedAlmond',
    'blue' => 'Blue',
    'blueviolet' => 'BlueViolet',
    'brown' => 'Brown',
    'burlywood' => 'BurlyWood',
    'cadetblue' => 'CadetBlue',
    'chartreuse' => 'Chartreuse',
    'chocolate' => 'Chocolate',
    'coral' => 'Coral',
    'cornflowerblue' => 'CornflowerBlue',
    'cornsilk' => 'Cornsilk',
    'crimson' => 'Crimson',
    'cyan' => 'Cyan',
    'darkblue' => 'DarkBlue',
    'darkcyan' => 'DarkCyan',
    'darkgoldenrod' => 'DarkGoldenRod',
    'darkgray' => 'DarkGray',
    'darkgreen' => 'DarkGreen',
    'darkkhaki' => 'DarkKhaki',
    'darkmagenta' => 'DarkMagenta',
    'darkolivegreen' => 'DarkOliveGreen',
    'darkorange' => 'DarkOrange',
    'darkorchid' => 'DarkOrchid',
    'darkred' => 'DarkRed',
    'darksalmon' => 'DarkSalmon',
    'darkseagreen' => 'DarkSeaGreen',
    'darkslateblue' => 'DarkSlateBlue',
    'darkslategray' => 'DarkSlateGray',
    'darkturquoise' => 'DarkTurquoise',
    'darkviolet' => 'DarkViolet',
    'deeppink' => 'DeepPink',
    'deepskyblue' => 'DeepSkyBlue',
    'dimgray' => 'DimGray',
    'dodgerblue' => 'DodgerBlue',
    'firebrick' => 'FireBrick',
    'floralwhite' => 'FloralWhite',
    'forestgreen' => 'ForestGreen',
    'fuchsia' => 'Fuchsia',
    'gainsboro' => 'Gainsboro',
    'ghostwhite' => 'GhostWhite',
    'gold' => 'Gold',
    'goldenrod' => 'GoldenRod',
    'gray' => 'Gray',
    'green' => 'Green',
    'greenyellow' => 'GreenYellow',
    'honeydew' => 'HoneyDew',
    'hotpink' => 'HotPink',
    'indianred' => 'IndianRed',
    'indigo' => 'Indigo',
    'ivory' => 'Ivory',
    'khaki' => 'Khaki',
    'lavender' => 'Lavender',
    'lavenderblush' => 'LavenderBlush',
    'lawngreen' => 'LawnGreen',
    'lemonchiffon' => 'LemonChiffon',
    'lightblue' => 'LightBlue',
    'lightcoral' => 'LightCoral',
    'lightcyan' => 'LightCyan',
    'lightgoldenrodyellow' => 'LightGoldenRodYellow',
    'lightgray' => 'LightGray',
    'lightgreen' => 'LightGreen',
    'lightpink' => 'LightPink',
    'lightsalmon' => 'LightSalmon',
    'lightseagreen' => 'LightSeaGreen',
    'lightskyblue' => 'LightSkyBlue',
    'lightslategray' => 'LightSlateGray',
    'lightsteelblue' => 'LightSteelBlue',
    'lightyellow' => 'LightYellow',
    'lime' => 'Lime',
    'limegreen' => 'LimeGreen',
    'linen' => 'Linen',
    'magenta' => 'Magenta',
    'maroon' => 'Maroon',
    'mediumaquamarine' => 'MediumAquaMarine',
    'mediumblue' => 'MediumBlue',
    'mediumorchid' => 'MediumOrchid',
    'mediumpurple' => 'MediumPurple',
    'mediumseagreen' => 'MediumSeaGreen',
    'mediumslateblue' => 'MediumSlateBlue',
    'mediumspringgreen' => 'MediumSpringGreen',
    'mediumturquoise' => 'MediumTurquoise',
    'mediumvioletred' => 'MediumVioletRed',
    'midnightblue' => 'MidnightBlue',
    'mintcream' => 'MintCream',
    'mistyrose' => 'MistyRose',
    'moccasin' => 'Moccasin',
    'navajowhite' => 'NavajoWhite',
    'navy' => 'Navy',
    'oldlace' => 'OldLace',
    'olive' => 'Olive',
    'olivedrab' => 'OliveDrab',
    'orange' => 'Orange',
    'orangered' => 'OrangeRed',
    'orchid' => 'Orchid',
    'palegoldenrod' => 'PaleGoldenRod',
    'palegreen' => 'PaleGreen',
    'paleturquoise' => 'PaleTurquoise',
    'palevioletred' => 'PaleVioletRed',
    'papayawhip' => 'PapayaWhip',
    'peachpuff' => 'PeachPuff',
    'peru' => 'Peru',
    'pink' => 'Pink',
    'plum' => 'Plum',
    'powderblue' => 'PowderBlue',
    'purple' => 'Purple',
    'rebeccapurple' => 'RebeccaPurple',
    'red' => 'Red',
    'rosybrown' => 'RosyBrown',
    'royalblue' => 'RoyalBlue',
    'saddlebrown' => 'SaddleBrown',
    'salmon' => 'Salmon',
    'sandybrown' => 'SandyBrown',
    'seagreen' => 'SeaGreen',
    'seashell' => 'SeaShell',
    'sienna' => 'Sienna',
    'silver' => 'Silver',
    'skyblue' => 'SkyBlue',
    'slateblue' => 'SlateBlue',
    'slategray' => 'SlateGray',
    'snow' => 'Snow',
    'springgreen' => 'SpringGreen',
    'steelblue' => 'SteelBlue',
    'tan' => 'Tan',
    'teal' => 'Teal',
    'thistle' => 'Thistle',
    'tomato' => 'Tomato',
    'turquoise' => 'Turquoise',
    'violet' => 'Violet',
    'wheat' => 'Wheat',
    'white' => 'White',
    'whitesmoke' => 'WhiteSmoke',
    'yellow' => 'Yellow',
    'yellowgreen' => 'YellowGreen',
  ),
  'SonataAdminBundle' =>
  array (
    'sonata_administration' => 'Administration',
    'action_delete' => 'Supprimer',
    'btn_batch' => 'OK',
    'btn_create' => 'Créer',
    'btn_create_and_edit_again' => 'Créer',
    'btn_create_and_create_a_new_one' => 'Créer et ajouter',
    'btn_create_and_return_to_list' => 'Créer et retourner à la liste',
    'btn_filter' => 'Filtrer',
    'btn_update' => 'Mettre à jour',
    'btn_update_and_edit_again' => 'Mettre à jour',
    'btn_update_and_return_to_list' => 'Mettre à jour et fermer',
    'link_delete' => 'Supprimer',
    'link_action_create' => 'Ajouter',
    'link_action_list' => 'Retourner à la liste',
    'link_action_show' => 'Afficher',
    'link_action_edit' => 'Editer',
    'link_add' => 'Ajouter',
    'link_list' => 'Liste',
    'link_reset_filter' => 'Effacer',
    'title_create' => 'Créer',
    'title_dashboard' => 'Tableau de bord',
    'title_edit' => 'Éditer "%name%"',
    'title_list' => 'Liste',
    'link_next_pager' => 'Suivant',
    'link_previous_pager' => 'Précédent',
    'link_first_pager' => 'Première',
    'link_last_pager' => 'Dernière',
    'Admin' => 'Admin',
    'link_expand' => 'Étendre/Réduire',
    'no_result' => 'Aucun résultat',
    'confirm_msg' => 'Êtes-vous sûr ?',
    'action_edit' => 'Éditer',
    'action_show' => 'Afficher',
    'all_elements' => 'Tous les éléments',
    'flash_batch_empty' => 'Action interrompue. Aucun élément n\'a été séléctionné.',
    'flash_create_success' => 'L\'élément "%name%" a été créé avec succès.',
    'flash_create_error' => 'Une erreur est intervenue lors de la création de l\'élément "%name%".',
    'flash_edit_success' => 'L\'élément "%name%" a été mis à jour avec succès.',
    'flash_edit_error' => 'Une erreur est intervenue lors de la mise à jour de l\'élément "%name%".',
    'flash_batch_delete_success' => 'Les éléments séléctionnés ont été supprimés avec succès.',
    'flash_batch_delete_error' => 'Une erreur est intervenue lors de la suppression des éléments séléctionnés.',
    'flash_delete_error' => 'Une erreur est intervenue lors de la suppression de l\'élément "%name%".',
    'flash_delete_success' => 'L\'élément "%name%" a été supprimé avec succès.',
    'breadcrumb.link_dashboard' => '<i class="fa fa-home"></i>',
    'title_delete' => 'Confirmation de suppression',
    'message_delete_confirmation' => 'Êtes-vous sûr de vouloir supprimer l\'élément "%object%" sélectionné?',
    'btn_delete' => 'Oui, supprimer',
    'title_batch_confirmation' => 'Confirmation d\'un traitement par lots: \'%action%\'',
    'message_batch_confirmation' => 'Êtes-vous sûr de vouloir confirmer cette action et de l\'exécuter pour l\'élément sélectionné?|Êtes-vous sûr de vouloir confirmer cette action et de l\'exécuter pour les %count% éléments sélectionnés?',
    'message_batch_all_confirmation' => 'Êtes-vous sûr de vouloir confirmer cette action et de l\'exécuter pour tous les éléments?',
    'btn_execute_batch_action' => 'Oui, exécuter',
    'label_type_yes' => 'oui',
    'label_type_no' => 'non',
    'label_type_contains' => 'contient',
    'label_type_not_contains' => 'ne contient pas',
    'label_type_equals' => 'est égal à',
    'label_type_not_equals' => 'n\'est pas égal à',
    'label_type_equal' => '=',
    'label_type_greater_equal' => '>=',
    'label_type_greater_than' => '>',
    'label_type_less_equal' => '<=',
    'label_type_less_than' => '<',
    'label_date_type_equal' => '=',
    'label_date_type_greater_equal' => '>=',
    'label_date_type_greater_than' => '>',
    'label_date_type_less_equal' => '<=',
    'label_date_type_less_than' => '<',
    'label_date_type_null' => 'est vide',
    'label_date_type_not_null' => 'n\'est pas vide',
    'label_date_type_between' => 'est entre',
    'label_date_type_not_between' => 'n\'est pas entre',
    'label_filters' => 'Filtres',
    'delete_or' => 'ou',
    'link_action_history' => 'Révisions',
    'td_action' => 'Action',
    'td_revision' => 'Révisions',
    'td_timestamp' => 'Date',
    'td_username' => 'Auteur',
    'label_view_revision' => 'Afficher la révision',
    'list_results_count' => '1 résultat|%count% résultats',
    'label_export_download' => 'Export',
    'loading_information' => 'Chargement des informations…',
    'btn_preview' => 'Prévisualiser',
    'btn_preview_approve' => 'Accepter',
    'btn_preview_decline' => 'Refuser',
    'label_per_page' => 'Par page',
    'list_select' => 'Sélectionner',
    'confirm_exit' => 'Vous avez effectué des modifications non sauvegardées.',
    'link_edit_acl' => 'Editer les permissions',
    'btn_update_acl' => 'Mettre à jour les permissions',
    'flash_acl_edit_success' => 'Les permissions ont été mises à jour avec succès.',
    'link_action_acl' => 'Permissions',
    'short_object_description_placeholder' => 'Aucune sélection',
    'title_search_results' => 'Résultats de recherche: %query%',
    'search_placeholder' => 'Rechercher',
    'no_results_found' => 'pas de résultats',
    'add_new_entry' => 'rajouter un élément',
    'link_actions' => 'Liste d\'actions',
    'noscript_warning' => 'Certaines fonctionnalités ne fonctionnent sans JavaScript; merci de l\'activer sur votre navigateur.',
    'message_form_group_empty' => 'Pas de champs disponibles.',
  ),
));
$catalogue->addFallbackCatalogue($catalogueFr);

return $catalogue;


text:
// @(#)BatteryTable.java   12/2003
// Copyright (c) 1998-2003, Distributed Real-time Computing Lab (DRCL)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
// 3. Neither the name of "DRCL" nor the names of its contributors may be used
//    to endorse or promote products derived from this software without specific
//    prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package drcl.inet.sensorsim;

import drcl.comp.*;

/** This class implements the table that specifies the capacity of a battery as a function of its current.
*
* @author Ahmed Sobeih
* @version 1.0, 12/19/2003
*/
public class BatteryTable extends drcl.DrclObj
{
	public static final int MAX_TABLE_SIZE = 25;
	public static final int CURRENT = 0;
	public static final int CAPACITY = 1;
	public static final int SEC_IN_HOUR = 3600;
	public static final int MAX_CAPACITY = 10;

	double maxCapacity ; // in mAh
	double curCapacity ;

	double [] [] data = new double [2] [MAX_TABLE_SIZE];

	public BatteryTable()
	{
		for ( int i = 0 ; i < MAX_TABLE_SIZE; i++ )
		{
			data[CURRENT][i] = 0.0 ;
			data[CAPACITY][i] = 0.0 ;
		}
	}

	/** Sets the maximum capacity */
	public void setMaxCapacity(double a)
	{
		maxCapacity = a ; // in mAh
		curCapacity = a ;
	}

	/** Gets the current capacity */
	public double getCurCapacity()
	{
		return curCapacity ;
	}

	/** Computes the new value of the capacity based on a given value for current and after a certain given time duration */
	public double computeNewCapacity(double current, double duration)
	{
		double newCap;
		double effCap = getCapacity(current);
		newCap = curCapacity - (current*duration/SEC_IN_HOUR)/effCap;
		curCapacity = newCap;
		return ( curCapacity );
	}

	/** Gets the interpolated capacity at a given value of current */
	public double getCapacity(double current)
	{
		int i;
		for (i=0; i < MAX_TABLE_SIZE; i++) {
			if ( data[CURRENT][i] >= current )
				break;
		} // end for

		if ( i == 0 )  // current smaller than 0.1
			return 1.0 ;

		if ( i >= MAX_TABLE_SIZE ) // current out of range
			return 0.0 ;

		// find the interpolated capacity
		double midPoint, capRange;
		midPoint = (current - data[CURRENT][i-1]) / ( data[CURRENT][i] - data[CURRENT][i-1] ) ;
		capRange = data[CAPACITY][i]-data[CAPACITY][i-1];
		return ((capRange*midPoint)+data[CAPACITY][i-1]);
	}

	/** Inputs an entry in the table */
	public int inputData(int i, double current, double capacity)
	{
		if ( (i < 0) || (i >= MAX_TABLE_SIZE) )
		{
			return -1 ;
		}
		else
		{
			data[CURRENT][i] = current ;
			data[CAPACITY][i] = capacity ;
			return 1 ;
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
package com.kneelawk.stree.core.infoProviders;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import com.kneelawk.stree.core.IntSTreeNode;
import com.kneelawk.stree.core.STreeNode;

public class IntSTreeNodeInfoProvider implements STreeInfoProvider {

	public static final IntSTreeNodeInfoProvider INSTANCE = new IntSTreeNodeInfoProvider();

	protected IntSTreeNodeInfoProvider() {
	}

	@Override
	public void write(STreeNode objectToWrite, DataOutput streamToWriteTo)
			throws IOException {
		IntSTreeNode node = (IntSTreeNode) objectToWrite;
		streamToWriteTo.writeInt(node.getValue());
	}

	@Override
	public IntSTreeNode read(DataInput streamToReadFrom) throws IOException {
		return new IntSTreeNode(streamToReadFrom.readInt());
	}

	@Override
	public byte getSTreeID() {
		return 8;
	}

}


text:
package org.ng200.openolympus.cerberus.compilers;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;
import org.ng200.openolympus.cerberus.exceptions.CompilationException;
import org.ng200.openolympus.cerberus.exceptions.CompilerError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GNUCompiler implements Compiler {
	private static final Logger logger = LoggerFactory
			.getLogger(GNUCompiler.class);
	private List<String> arguments = new ArrayList<>();

	public GNUCompiler() {
	}

	@Override
	public void addArgument(final String argument) {
		this.arguments.add(argument);
	}

	public List<String> getArguments() {
		return arguments;
	}

	public void setArguments(List<String> arguments) {
		this.arguments = arguments;
	}

	@Override
	public void compile(final List<Path> inputFiles, final Path outputFile,
			final Map<String, Object> additionalParameters)
			throws CompilationException {
		GNUCompiler.logger.debug("Compiling {} to {} using GCC", inputFiles,
				outputFile);

		final CommandLine commandLine = new CommandLine("g++");
		commandLine.setSubstitutionMap(additionalParameters);

		this.arguments.forEach((arg) -> commandLine.addArgument(arg));

		commandLine.addArgument("-w"); // Prohibit warnings because they screw
		// up error detection

		commandLine.addArgument("-o");
		commandLine.addArgument(MessageFormat.format("\"{0}\"", outputFile
				.toAbsolutePath().toString())); // Set outuput file

		inputFiles.forEach((file) -> commandLine.addArguments(MessageFormat
				.format("\"{0}\"", file.toAbsolutePath().toString()))); // Add
		// input
		// files

		GNUCompiler.logger.debug("Running GCC with arguments: {}",
				Arrays.asList(commandLine.getArguments()));

		final DefaultExecutor executor = new DefaultExecutor();
		executor.setExitValues(new int[] {
				0,
				1
		});

		final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
		executor.setStreamHandler(new PumpStreamHandler(null, errorStream, null));

		executor.setWatchdog(new ExecuteWatchdog(20000));// 20 seconds to
		// compile
		int result;
		try {
			result = executor.execute(commandLine);
		} catch (final IOException e) {
			GNUCompiler.logger.error("Could not execute GCC: {}", e);
			throw new CompilationException("Could not execute GCC", e);
		}

		switch (result) {
		case 0:
			return;
		case 1:
			try {
				String errorString = errorStream
						.toString(StandardCharsets.UTF_8.name());

				final Pattern pattern = Pattern.compile(
						"^("
								+ inputFiles
										.stream()
										.map(file -> Pattern.quote(file
												.toAbsolutePath().toString()))
										.collect(Collectors.joining("|"))
								+ "):", Pattern.MULTILINE);
				errorString = pattern.matcher(errorString).replaceAll("");

				GNUCompiler.logger.debug("Compilation error: {}", errorString);
				throw new CompilerError("gcc.wrote.stderr", errorString);
			} catch (final UnsupportedEncodingException e) {
				throw new CompilationException(
						"Unsupported encoding! The compiler should output UTF-8!",
						e);
			}
		}
	}
}


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <title>Quick Tips #1 - Centralizando Elementos</title>
    <meta name="description" content="" />

    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="shortcut icon" href="https://heliomsolivas.github.io/favicon.ico">

    <link rel="stylesheet" type="text/css" href="//heliomsolivas.github.io/themes/casper/assets/css/screen.css?v=1500605742854" />
    <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />

    <link rel="canonical" href="https://heliomsolivas.github.io/2017/01/12/Quick-Tips-1-Centralizando-Elementos.html" />
    <meta name="referrer" content="origin" />

    <meta property="og:site_name" content="madlife :)" />
    <meta property="og:type" content="article" />
    <meta property="og:title" content="Quick Tips #1 - Centralizando Elementos" />
    <meta property="og:description" content="Eae galeras, voltando 2017 e a promessa de fazer mais posts pro blog retorna, vou fazer uma série chamada Quick Tips mostrando e explicando alguns snippets ou técnicas que tenho utilizado com frequência. O problema Algo que sempre acontece quando você está lá feliz fazendo o front-end é precisar centralizar" />
    <meta property="og:url" content="https://heliomsolivas.github.io/2017/01/12/Quick-Tips-1-Centralizando-Elementos.html" />
    <meta property="article:published_time" content="2017-01-12T00:00:00.000Z" />
    <meta property="article:tag" content="css" />
    <meta property="article:tag" content=" vertical-align" />
    <meta property="article:tag" content=" centralizando" />
    <meta property="article:tag" content=" tips" />
    <meta property="article:tag" content=" css tips" />

    <meta name="twitter:card" content="summary" />
    <meta name="twitter:title" content="Quick Tips #1 - Centralizando Elementos" />
    <meta name="twitter:description" content="Eae galeras, voltando 2017 e a promessa de fazer mais posts pro blog retorna, vou fazer uma série chamada Quick Tips mostrando e explicando alguns snippets ou técnicas que tenho utilizado com frequência. O problema Algo que sempre acontece quando você está lá feliz fazendo o front-end é precisar centralizar" />
    <meta name="twitter:url" content="https://heliomsolivas.github.io/2017/01/12/Quick-Tips-1-Centralizando-Elementos.html" />

    <meta name="generator" content="HubPress" />
    <link rel="alternate" type="application/rss+xml" title="madlife :)" href="https://heliomsolivas.github.io/rss/" />
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/atom-one-dark.min.css">

Quick Tips #1 - Centralizando Elementos

                <time class="post-date" datetime="2017-01-12">12 January 2017</time>  on css,  vertical-align,  centralizando,  tips,  css tips

Eae galeras, voltando 2017 e a promessa de fazer mais posts pro blog retorna, vou fazer uma série chamada Quick Tips mostrando e explicando alguns snippets ou técnicas que tenho utilizado com frequência.

O problema

Algo que sempre acontece quando você está lá feliz fazendo o front-end é precisar centralizar um elemento, tanto horizontal como verticalmente. O exemplo abaixo seria o caso de um footer, com um logotipo a esquerda, o link do site no meio e a direita os ícones das redes sociais. Então vamos a montagem:

<footer>
  <!-- Imagem Responsiva -->
  <div class="block block-1">
    <div class="wrapper-img">
    	<img src="http://www.parsely.com/static/img/parsely-green-leaf-m.png">
    </div>
  </div>

  <!-- Texto -->
  <div class="block block-2">
    <div class="wrapper-texto">
    	<p>Meu footer</p>
    </div>
  </div>

  <!-- Redes Sociais -->
  <div class="block block-3">
    <div class="wrapper-social">
      <i class="fa fa-facebook-official" aria-hidden="true"></i>
    </div>

    <div class="wrapper-social">
      <i class="fa fa-twitter" aria-hidden="true"></i>
    </div>
  </div>
</footer>

E vamos adicionar um CSS pra dar uma cara melhor para o footer.

*{
  box-sizing:border-box;
  margin:0;
  padding:0;
}
html,body{
  height:100%;
}
footer{
  height:40%;
  background:#fff;
  width:100%;
  border-bottom: 1px solid #EBEBEE;
}
.block{
  height:100%;
  float:left;
  width:33.3%;
}
.block-1 .wrapper-img{
  height:100%;
  position:relative;
}
.block-1 .wrapper-img img{
  max-width:100%;
  max-height:80%;
}
.block-2 .wrapper-texto{
 position:relative;
  width:100%;
  height:100%;
}
.block-2 .wrapper-texto p{
  color:#fff;
  top: 50%;
  height:20px;
  width:100%;
  text-align:center;
  color:#59A846;
}
.block-3{
  text-align:center;
}
.fa{
  font-size:26px;
  color:#59A846;
  margin:0 2px;
}

Centralizando os elementos

Uma das técnicas para centralizar uma imagem é criar uma div pai relativa e a filha absoluta setando tudo pra 0.

<!--Filha-->
.block-1 .wrapper-img img{
 position:absolute;
 left:0;
 right:0;
 top:0;
 bottom:0;
 margin: auto;
}

No caso do segundo bloco, onde está localizado nosso texto, utilizaremos novamente uma div pai relativa e a filha absoluta com o top: 50% + uma margem negativa com a altura do texto. A centralização horizontal fica por conta do text-align:center;

<!--Filha-->
.block-2 .wrapper-texto p{
 position: absolute;
 color:#fff;
 top: 50%;
 height:20px;
 margin-top:-10px;
 width:100%;
 text-align:center;
 color:#59A846;
}

E por fim no terceiro bloco vamos criar um pseudo-elemento after ou before do bloco 3 para centralizar os pais dos ícones, utilizando o display:inline-block e o vertical-align:middle.

.block-3:before{
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}
.wrapper-social{
  display: inline-block;
  vertical-align: middle;
}

Como resultado final

Bom por hoje é só isso, qualquer dúvida é só comentar aqui que pretendo responder, o exemplo completo se encontra no meu - Codepen. Valeu! :)

                Hélio Marcondes's Picture

Hélio Marcondes

Read more posts by this author.

                    Cruzeiro, São Paulo
                    heliomsolivas.github.io

Share this post

                    Twitter

                    Facebook

                    Google+

          Please enable JavaScript to view the comments powered by Disqus.
          comments powered by Disqus

madlife :) © 2017

Proudly published with HubPress


text:
angular.module('authService', [])
//Auth Factory
.factory('Auth', function($http, $q, AuthToken) {
    var authFactory = {};
    //Login function
    authFactory.login = function(username, password) {
        return $http.post('/api/login', {
            username: username,
            password: password
        })
        .success(function(data) {
            AuthToken.setToken(data.token);
            return data;
        })
    }
    //Log out the user
    authFactory.logout = function() {
        AuthToken.setToken();
    }
    //Check if user has token
    authFactory.isLoggedIn = function() {
        if(AuthToken.getToken()) {
            return true;
        } else {
            return false;
        }
    }
    //Get the user infromation
    authFactory.getUser = function() {
        if(AuthToken.getToken()) {
            return $http.get('/api/me');
        } else {
            return $q.reject({ message: "User has no token" });
        }
    }
    //Return the factory
    return authFactory;
})
//Our Token Factory
.factory('AuthToken', function($window) {
    var authTokenFactory = {};

    authTokenFactory.getToken = function() {
        return $window.localStorage.getItem('token');
    }

    authTokenFactory.setToken = function(token) {
        if(token) {
            $window.localStorage.setItem('token', token);
        } else {
            $window.localStorage.removeItem('token');
        }
    }
    //Return authTokenFactory
    return authTokenFactory;
})
//Check for Authentication and make sure it is in the headers
.factory('AuthInterceptor', function($q, $location, AuthToken) {
    var interceptorFactory = {};
    //intercept token requests
    interceptorFactory.request = function(config) {
        var token = AuthToken.getToken();
        //If the token exists add it to headers
        if(token) {
            config.headers['x-access-token'] = token;
        }
        //Return the config
        return config;
    }
    //Error checking in case the token is not present
    interceptorFactory.responseError = function(response) {
        //If the user is not logged in the user will be redirected to the login page.
        if(response.status === 403) {
            $location.path('/');
        }

        return $q.reject(response);
    }

    return interceptorFactory;
});


text:
<?php
namespace Phalcon\Common;

class ArrayHelper
{

    /**
     * pick spec fileds from the data source
     *
     * @param array $source
     * @param array $fields
     * @param array $alias
     * @return array $mappedData
     */
    public static function pick($source, $fields, $alias = [])
    {
        if (! is_array($source))
        {
            throw new CommonException('source must be array!');
        }
        $mappedData = [];
        foreach ($fields as $filed)
        {
            if (isset($source[$filed]))
            {
                $mappedData[$filed] = $source[$filed];
                /*
                 * alias key
                 */
                if (isset($alias[$filed]))
                {
                    $mappedData[$alias[$filed]] = $source[$filed];
                }
            }
        }
        return $mappedData;
    }
}


text:
var Modularizer = module.exports = {};

var shelljs  = require('shelljs');
var path     = require('path');
var fs       = require('fs');
var async    = require('async');
var p        = path;
var readline = require('readline');

var Configuration = require('./Configuration.js');
var cst           = require('../constants.js');
var CLI           = require('./CLI.js');
var Common        = require('./Common');
var UX            = require('./CLI/CliUx.js');

var MODULE_CONF_PREFIX = 'module-db';

function startModule(opts, cb) {
  /** SCRIPT
   * Open file and make the script detection smart
   */

  if (!opts.cmd) throw new Error('module package.json not defined');
  if (!opts.development_mode) opts.development_mode = false;

  var package_json = require(opts.cmd);

  /**
   * Script file detection
   * 1- *apps* field (default pm2 json configuration)
   * 2- *bin* field
   * 3- *main* field
   */
  if (!package_json.apps) {
    package_json.apps = {};

    if (package_json.bin) {
      var bin = Object.keys(package_json.bin)[0];

      package_json.apps.script = package_json.bin[bin];
    }
    else if (package_json.main) {
      package_json.apps.script = package_json.main;
    }
  }

  /**
   * Verify that the module is valid
   * If not, delete
   */
  if (isValidModule(package_json) === false) {
    if (!opts.development_mode) shelljs.rm('-rf', opts.proc_path);
    Common.printError(cst.PREFIX_MSG_MOD + 'Module uninstalled');
    return cb({msg:'Invalid module'});
  }

  // Start the module
  CLI.start(package_json, {
    cwd               : opts.proc_path,
    watch             : opts.development_mode,
    force_name        : package_json.name,
    started_as_module : true
  }, function(err, data) {
    if (err) return cb(err);
    return cb(null, data);
  });
};

function installModule(module_name, cb) {
  var proc_path = '',
      cmd  = '',
      conf = {},
      development_mode = false;

  if (module_name == '.') {
    /**
     * Development mode
     */
    Common.printOut(cst.PREFIX_MSG_MOD + 'Installing local module in DEVELOPMENT MODE with WATCH auto restart');
    development_mode = true;
    proc_path = process.cwd();

    cmd = p.join(proc_path, cst.DEFAULT_MODULE_JSON);

    startModule({
      cmd : cmd,
      development_mode : development_mode,
      proc_path : proc_path
    }, function(err, dt) {
      if (err) return cb(err);
      Common.printOut(cst.PREFIX_MSG_MOD + 'Module successfully installed and launched');
      Common.printOut(cst.PREFIX_MSG_MOD + ': To configure module use');
      Common.printOut(cst.PREFIX_MSG_MOD + ': $ pm2 conf <key> <value>');
      return cb(null, cmd);
    });
  }
  else {
    /**
     * Production mode
     */

    Common.printOut(cst.PREFIX_MSG_MOD + 'Processing...');
    var inter = setInterval(function() {
      process.stdout.write('.');
    }, 500);

    // Redirecting error output to /dev/null
    // This is a ugly hack
    shelljs.exec('npm install ' + module_name + ' --prefix ' + cst.PM2_ROOT_PATH + ' 2> /dev/null', function(code) {
      clearInterval(inter);

      if (code != 0) {
        Common.printError(cst.PREFIX_MSG_MOD_ERR + 'Unknown module');
        return cb({msg:'Unknown module'});
      }

      Common.printOut(cst.PREFIX_MSG_MOD + 'Module downloaded');

      if (module_name.match(/^(.+\/)?([^\/]+)\.tgz($|\?)/)) {
        module_name = module_name.match(/^(.+\/)?([^\/]+)\.tgz($|\?)/)[2];
        if (module_name.match(/^(.+)-[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9_]+\.[0-9]+)?$/)) {
          module_name = module_name.match(/^(.+)-[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9_]+\.[0-9]+)?$/)[1];
        }
      }
      else if (module_name.indexOf('/') != -1)
        module_name = module_name.split('/')[1];

      //pm2 install module@2.1.0-beta
      if(module_name.indexOf('@') != -1)
        module_name = module_name.split('@')[0]

      proc_path = p.join(cst.PM2_ROOT_PATH, 'node_modules', module_name);

      cmd = p.join(proc_path, cst.DEFAULT_MODULE_JSON);

      Configuration.set(MODULE_CONF_PREFIX + ':' + module_name, 'true', function(err, data) {
        startModule({
          cmd : cmd,
          development_mode : development_mode,
          proc_path : proc_path
        }, function(err, dt) {
          if (err) return cb(err);
          Common.printOut(cst.PREFIX_MSG_MOD + 'Module successfully installed and launched');
          Common.printOut(cst.PREFIX_MSG_MOD + ': To configure module do');
          Common.printOut(cst.PREFIX_MSG_MOD + ': $ pm2 conf <key> <value>');
          return cb(null, cmd);
        });
      });

    });
  }
}

function uninstallModule(module_name, cb) {
  var proc_path = p.join(cst.PM2_ROOT_PATH, 'node_modules', module_name);

  Configuration.unsetSync(MODULE_CONF_PREFIX + ':' + module_name);

  CLI.deleteModule(module_name, function(err, data) {
    if (err) {
      Common.printError(err);

      if (module_name != '.') {
        console.log(proc_path);
        shelljs.rm('-r', proc_path);
      }

      return cb(err);
    }

    if (module_name != '.') {
      shelljs.rm('-r', proc_path);
    }

    return cb();
  });
}

/**
 * List modules on the old way
 */
var listModules = function() {
  var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');
  var ret = [];

  shelljs.config.silent = true;
  var modules = shelljs.ls(module_folder);
  shelljs.config.silent = false;

  modules.forEach(function(module_name) {
    if (module_name.indexOf('pm2-') > -1)
      ret.push(module_name);
  });

  return ret;
};

/**
 * List modules based on internal database
 */
var listModulesV2 = Modularizer.listModules = function() {
  var config = Configuration.getSync(MODULE_CONF_PREFIX);

  if (!config) {
    var modules_already_installed = listModules();

    modules_already_installed.forEach(function(module_name) {
      Configuration.setSync(MODULE_CONF_PREFIX + ':' + module_name, true);
    });
    return modules_already_installed;
  }

  return Object.keys(config);
};

Modularizer.getAdditionalConf = function(app_name) {
  if (!app_name) throw new Error('No app_name defined');

  var module_conf = Configuration.getAllSync();

  var additional_env = {};

  if (!module_conf[app_name]) {
    additional_env = {};
    additional_env[app_name] = {};
  }
  else {
    additional_env = Common.clone(module_conf[app_name]);
    additional_env[app_name] = JSON.stringify(module_conf[app_name]);
  }
  return additional_env;
};

Modularizer.launchAll = function(cb) {
  var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');

  var modules = listModulesV2();

  async.eachLimit(modules, 1, function(module, next) {
    var pmod = p.join(module_folder, module, cst.DEFAULT_MODULE_JSON);

    Common.printOut(cst.PREFIX_MSG_MOD + 'Starting module ' + module);

    startModule({
      cmd : pmod,
      development_mode : false,
      proc_path : p.join(module_folder, module)
    }, function(err, dt) {
      if (err) console.error(err);
      return next();
    });

  }, function() {
    return cb ? cb(null) : false;
  });
};

Modularizer.install = function(module_name, cb) {
  Common.printOut(cst.PREFIX_MSG_MOD + 'Installing module ' + module_name);

  if (moduleExist(module_name) === true) {
    /**
     * Update
     */
    Common.printOut(cst.PREFIX_MSG_MOD + 'Module already installed. Updating.');

    uninstallModule(module_name, function(err) {
      if (err) return cb({msg : 'Problem when uninstalling module', err : err});
      return installModule(module_name, cb);
    });

    return false;
  }

  /**
   * Install
   */
  installModule(module_name, cb);
};

/**
 * Uninstall module
 */
Modularizer.uninstall = function(module_name, cb) {
  Common.printOut(cst.PREFIX_MSG_MOD + 'Uninstalling module ' + module_name);

  //if (moduleExist(module_name) === false && module_name != '.') {
  //Common.printError(cst.PREFIX_MSG_MOD_ERR + 'Module unknown.');
  //return cb({msg:'Module unknown'});
  //}
  if (module_name == 'all') {
    var modules = listModulesV2();
    async.forEachLimit(modules, 1, function(module, next) {
      uninstallModule(module, next);
    }, cb);
    return false;
  }

  uninstallModule(module_name, cb);
};

/**
 * Publish a module
 */
Modularizer.publish = function(cb) {
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  var semver = require('semver');

  var package_file = p.join(process.cwd(), 'package.json');

  var package_json = require(package_file);

  package_json.version = semver.inc(package_json.version, 'minor');
  Common.printOut(cst.PREFIX_MSG_MOD + 'Incrementing module to: %s@%s',
                  package_json.name,
                  package_json.version);

  rl.question("Write & Publish? [Y/N]", function(answer) {
    if (answer != "Y")
      return cb();

    fs.writeFile(package_file, JSON.stringify(package_json, null, 2), function(err, data) {
      if (err) return cb(err);

      Common.printOut(cst.PREFIX_MSG_MOD + 'Publishing module - %s@%s',
                      package_json.name,
                      package_json.version);

      shelljs.exec('npm publish', function(code) {
        Common.printOut(cst.PREFIX_MSG_MOD + 'Module - %s@%s successfully published',
                        package_json.name,
                        package_json.version);

        Common.printOut(cst.PREFIX_MSG_MOD + 'Pushing module on Git');
        shelljs.exec('git add . ; git commit -m "' + package_json.version + '"; git push origin master', function(code) {

          Common.printOut(cst.PREFIX_MSG_MOD + 'Installable with pm2 install %s', package_json.name);
          return cb(null, package_json);
        });
      });
    });

  });
};

Modularizer.generateSample = function(app_name, cb) {
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  function samplize(module_name) {
    var cmd1 = 'git clone https://github.com/pm2-hive/sample-module.git ' + module_name + '; cd ' + module_name + '; rm -rf .git';
    var cmd2 = 'cd ' + module_name + ' ; sed -i "s:sample-module:'+ module_name  +':g" package.json';
    var cmd3 = 'cd ' + module_name + ' ; npm install';

    Common.printOut(cst.PREFIX_MSG_MOD + 'Getting sample app');
    shelljs.exec(cmd1, function(err) {
      if (err) Common.printError(cst.PREFIX_MSG_MOD_ERR + err.message);
      shelljs.exec(cmd2, function(err) {
        console.log('');
        shelljs.exec(cmd3, function(err) {
          console.log('');
          Common.printOut(cst.PREFIX_MSG_MOD + 'Module sample created in folder: ', path.join(process.cwd(), module_name));
          console.log('');
          Common.printOut('Start module in development mode:');
          Common.printOut('$ cd ' + module_name + '/');
          Common.printOut('$ pm2 install . ');
          console.log('');

          Common.printOut('Module Log: ');
          Common.printOut('$ pm2 logs ' + module_name);
          console.log('');
          Common.printOut('Uninstall module: ');
          Common.printOut('$ pm2 uninstall ' + module_name);
          console.log('');
          Common.printOut('Force restart: ');
          Common.printOut('$ pm2 restart ' + module_name);
          return cb ?  cb() : false;
        });
      });
    });
  }

  if (app_name) return samplize(app_name);

  rl.question(cst.PREFIX_MSG_MOD + "Module name: ", function(module_name) {
    samplize(module_name);
  });

};

function isValidModule(conf) {
  var valid = true;

  if (!conf.apps) {
    Common.printError(cst.PREFIX_MSG_MOD_ERR + 'apps attribute indicating the script to launch is not defined in the package.json');
    return false;
  }

  if (Array.isArray(conf.apps)) {
    conf.apps.forEach(function(app) {
      if (!app.script)
        valid = false;
    });
  }
  else {
    if (!conf.apps.script)
      valid = false;
  }

  return valid;
};

function moduleExist(module_name) {
  var modules = getModuleInstalled();

  if (module_name.indexOf('/') > -1)
    module_name = module_name.split('/')[1];

  return modules.indexOf(module_name) > -1 ? true : false;
};

function getModuleInstalled() {
  shelljs.config.silent = true;
  var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');
  var modules       = shelljs.ls('-A', module_folder);
  shelljs.config.silent = false;
  return modules;
}


text:
title: CCRC Weather Station
layout: post
category: projects
work-type: DIY
date: 2015-09-21
tags: [raspberry pi, ffmpeg, shell, diy]
image-sm: thumb-2015-09-21-ccrc-weather-station.jpg
image: thumb-2015-09-21-ccrc-weather-station.jpg
alt: image-alt
project-date: 2014—2015
description: Raspberry Pi + camera + enthusiast weather station + really tall building = epic weather data
---

Sometime last year, the idea of collecting weather observations at UNSW popped up. This sort of data is useful to people for many reasons beyond curiosity: UNSW staff can use it to predict power loads, lecturers can use it to give climatology students practice data sets for eductional purposes, and of course anyone can use it to plan their day.

This project is actually fairly simple to put together; most of the tricky stuff comes from trying to make it reliably work 16 stories up, in a place beyond the reach of UNSW's Wi-Fi. The station itself—an [Oregon WMR200](http://shop.australiangeographic.com.au/oregon-weather-station-wmr200.html)—wirelessly transmits to a data logger, which in turns sends the data over USB to a [Raspberry Pi](http://www.raspberrypi.org/). The PI runs the free [weewx](http://www.weewx.com) software to collect observations and send them over a wired connection to the CCRC's network storage and to public weather sites like [Weather Underground](http://www.wunderground.com/personal-weather-station/dashboard?ID=INEWSOUT602) and the Met Office's [Weather Observations Website](http://bom-wow.metoffice.gov.uk/graphdata?requestedAction=REQUEST&siteID=919586001) (where you can view or download the data right now!).

Since we were going to the effort of installing a computer up there, we decided to give it some eyes. We plugged a [camera](http://www.raspberrypi.org/camera) into the Pi and wrote a script that take a picture every few seconds during the day (and less often at night, since it needs a bit of time to expose properly).

The Pi isn't really powerful to do anything too magical with those images itself, but since we have more powerful servers at the CCRC, they do the legwork of deleting those images (we keep a rolling record so that we don't end up with terabytes of old images), uploading them to [Flickr](http://www.flickr.com/photos/ccrc_weather/) and rendering timelapse videos to send to [YouTube](https://www.youtube.com/channel/UCeiNSkPn47gxultHDuJZEYw) each day. We can also render videos on demand, which is great for studying storms!

This project has been a long time coming, and it wouldn't have happened without the hard work of CCRC stduent Ryan Batehup, who built the excellent box that houses the station and went up on the roof week after week with the long-suffering and incredibly helpful Ben Crankshaw from UNSW's Facilities Management, who advised us on the roof installation and facilitated the whole process.

There are still lots of things we want to do with this station, and we're making tweaks as we think of them. If you have any ideas for it or there's any recent weather that you'd like to see on camera, [tweet at me](https://twitter.com/intent/tweet?text=@rensa_co&related=rensa_co) or [drop me an email](mailto:j.goldie@unsw.edu.au)! We're pretty open to ideas :)

**January 2016 update:** small update to the CCRC weather station! I mean, I'm pretty happy with it, but the end result is physically small: the timelapse videos now have timestamps. The reason is that it's storm season in Sydney at the moment, and the videos coming out of the weather station are getting a lot of attention. A pair of videos of a recent storm picked up about 21 000 views between them:

I'd like a bit more of the benefit of that to go back to the CCRC—but as well as that, it would be useful to see how quickly time is moving during the shot, as the night shots have long exposures and hence run at a different speed to the day ones.

I had a few requirements, though. I wanted to be able to do this:

- using the existing image series, which is stored within a base directory using a `/images/YYYY-MM-DD/HH/YYYY-MM-DD-HHMM-SS.jpg` structure, and
- without preprocessing the images (ie. altering the original images or making copies of them).

Basically, I was being stubborn about this because I thought `ffmpeg` should be able to handle it.

The existing code (which is [now on Github](https://github.com/rensa/ccrc-weather-station-uploads)—I'm working on getting the code that sits on the station itself up at a later date) already uses [ffmpeg](https://ffmpeg.org/) to stitch the image sequence together. Because the images aren't taken at regular intervals (though the station tries very hard), this script uses ffmpeg's concat filter, which accepts a list of image paths, to render the video. Originally, that file list looked like this (but with absolute paths):

{% highlight shell linenos=table %}
file 'images/2016-01-31/06/2016-01-31-0630-37.jpg'
file 'images/2016-01-31/06/2016-01-31-0630-41.jpg'
file 'images/2016-01-31/06/2016-01-31-0630-44.jpg'
{% endhighlight %}

But the concat filter can also be used to pass other custom frame metadata, like:

{% highlight shell linenos=table %}
file 'images/2016-01-31/06/2016-01-31-0630-37.jpg'
file_packet_metadata dt=2016-01-31-0630-37
file 'images/2016-01-31/06/2016-01-31-0630-41.jpg'
file_packet_metadata dt=2016-01-31-0630-41
file 'images/2016-01-31/06/2016-01-31-0630-44.jpg'
file_packet_metadata dt=2016-01-31-0630-44
{% endhighlight %}

And _that_ metadata can be accessed by subsequent filters. For example, in the weather station script, we use the shell's `find` to build up the list of images, then loop through the list to add the metadata (which is essentially just the date-time used in the file name). Finally, `ffmpeg`'s `drawtext` filter access this using `text='%{metadata\\:dt}`, where `dt` is the metadata key we've specified. [This](https://github.com/rensa/ccrc-weather-station-uploads/blob/master/custom-youtube.sh) is how it comes together:

{% highlight shell linenos=table %}
# get the list of files in the matching date-time range
find "$DATA_DIR"/images -type f -mmin -"$VID_START" -mmin +"$VID_END" >custom-list.txt

# transform file list to prep for ffmpeg (including adding metadata)line-by-line
IMG_PATH="$DATA_DIR"/images
EXT=".jpg"
while read FULLNAME; do
    # extract date-time part of filename
    if [[ $FULLNAME =~ [0-9]{4}.[0-9]{2}.[0-9]{2}.[0-9]{4}.[0-9]{2} ]]; then
        DT="${BASH_REMATCH[0]}"
    fi

    printf "file \'$FULLNAME\'\nfile_packet_metadata dt=$DT\n" >>custom-list2.txt
done <custom-list.txt
mv custom-list2.txt custom-list.txt

# render the video
nice -n 20 ffmpeg/ffmpeg -threads 6 -f concat -r "$FRAME_RATE" \
    -i custom-list.txt \
    -i waltz-flowers-tchaikovsky.mp3 \
    -threads 6 \
    -vf "crop=2592:1458:0:450, \
        drawtext=fontfile=RobotoCondensed-Italic.ttf:\
            fontsize=48:\
            fontcolor=0xFFFFFF:\
            shadowcolor=0x00000088:\
            shadowx=5:\
            shadowy=5:\
            text='%{metadata\\:dt}':\
            x=20:\
            y=h-32-106-th, \
        drawtext=fontfile=RobotoCondensed-Regular.ttf:\
            fontsize=48:\
            fontcolor=0xFFFFFF:\
            shadowcolor=0x00000088:\
            shadowx=5:\
            shadowy=5:\
            text='Climate Change Research Centre':\
            x=20:\
            y=h-32-48-th, \
        drawtext=fontfile=RobotoCondensed-Regular.ttf:\
            fontsize=48:\
            fontcolor=0xFFFFFF:\
            shadowcolor=0x00000088:\
            shadowx=5:\
            shadowy=5:\
            text='Sydney, Australia':\
            x=20:\
            y=h-32-th" \
    -shortest "$DATA_DIR"/videos/custom-"$TODAY.mov"
{% endhighlight %}

The result works really well:


text:
package io.smartcat.berserker.rategenerator;

/**
 * Rate generator which uses triangle wave to generate rate.
 */
public class TriangleRateGenerator extends PeriodicRateGenerator {

    private final double leftSide;
    private final double minValue;
    private final double maxValue;

    /**
     * Constructs rate generator with specified periodInSeconds, leftSide,
     * lowerValue and upperValue.
     *
     * @param periodInSeconds Period in seconds, must be positive number.
     * @param leftSide Percentage of the period where function is in ascending slope from minValue to
     *            maxValue. Other part of period is in descending slope from maxValue to
     *            minValue, must be in range [0,1).
     * @param minValue Minimum value of the triangle function, must be positive number.
     * @param maxValue Maximum value of the triangle function, must be positive number.
     */
    public TriangleRateGenerator(long periodInSeconds, double leftSide, double minValue, double maxValue) {
        super(periodInSeconds);
        if (leftSide < 0 || leftSide >= 1) {
            throw new IllegalArgumentException("Left side must be in range [0, 1).");
        }
        if (minValue <= 0) {
            throw new IllegalArgumentException("Min value must be positive number.");
        }
        if (maxValue <= 0) {
            throw new IllegalArgumentException("Max value must be positive number.");
        }
        this.leftSide = leftSide;
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    @Override
    protected double rateFunction(double value) {
        if (value < leftSide) {
            return ((maxValue - minValue) * value / leftSide) + minValue;
        } else {
            return ((maxValue - minValue) * (1 - value) / (1 - leftSide)) + minValue;
        }
    }
}


text:
require 'rails_helper'

RSpec.describe Team, :type => :model do
  before do
    @team = Team.new(name: 'team_x1', description: 'description of x')
  end

  subject { @team }

  it { should respond_to(:name) }
  it { should respond_to(:description) }
  it { should respond_to(:members) }

  it 'should be invalid' do
    expect(@team.valid?).to eq(false)
  end

  it 'should be valid if team has one member' do
    @team.save!(validate: false)
    @team.members.create(target_type: 'Staff', target_id: 1)
    expect(@team.members.count).to eq(1)
    expect(@team.valid?).to eq(true)
  end

  it 'should be invalid if team has no member' do
    @team.save!(validate: false)
    expect(@team.members.count).to eq(0)
    expect(@team.valid?).to eq(false)

    @team.members.create(target_type: 'Staff', target_id: 1)
    expect(@team.members.count).to eq(1)
    expect(@team.valid?).to eq(true)
  end
end


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="ForegroundLayout">
    <!-- Defines the drawable to draw over the content.
         This can be used as an overlay. -->
    <attr name="fv_foreground" format="reference|color"/>
    <!-- Defines whether the foreground drawable should be drawn inside the padding.
         This property is turned false by default. -->
    <attr name="fv_foregroundInsidePadding" format="boolean"/>

    <!-- Extra feature: Retrieve the default background and set it as the foreground.
         You can get the default background selector of your theme and set it as your
         foreground selector if you want. -->
    <attr name="fv_backgroundAsForeground" format="boolean"/>

  </declare-styleable>

</resources>


text:
<?php

require_once 'Single.php';

$single1 = Single::getInstance();
var_dump($single1);
$single2 = Single::getInstance();
var_dump($single2);