diff --git a/VERSION b/VERSION
index 3062913c..62353f59 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.4.1-alpha.2+timestamp.2013.01.16.11.22.49
+Version 2.4.1-alpha.2+timestamp.2013.01.17.11.00.19
diff --git a/applications/admin/languages/es.py b/applications/admin/languages/es.py
index 99b23604..53eb9368 100644
--- a/applications/admin/languages/es.py
+++ b/applications/admin/languages/es.py
@@ -3,154 +3,28 @@
'!langcode!': 'es',
'!langname!': 'Español',
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"actualice" es una expresión opcional como "campo1=\'nuevo_valor\'". No se puede actualizar o eliminar resultados de un JOIN',
-'%Y-%m-%d': '%Y-%m-%d',
-'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s %%{row} deleted': '%s filas eliminadas',
'%s %%{row} updated': '%s filas actualizadas',
+'%Y-%m-%d': '%Y-%m-%d',
+'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'(something like "it-it")': '(algo como "it-it")',
+'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
'A new version of web2py is available': 'Hay una nueva versión de web2py disponible',
'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s',
-'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.',
-'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.',
-'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que se ejecuta!',
'About': 'acerca de',
'About application': 'Acerca de la aplicación',
-'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro',
-'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro',
-'Administrator Password:': 'Contraseña del Administrador:',
-'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?',
-'Are you sure you want to delete plugin "%s"?': '¿Está seguro que quiere eliminar el plugin "%s"?',
-'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"',
-'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
-'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?',
-'Available databases and tables': 'Bases de datos y tablas disponibles',
-'Cannot be empty': 'No puede estar vacío',
-'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.',
-'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:',
-'Change Password': 'Cambie Contraseña',
-'Change admin password': 'cambie contraseña admin',
-'Check to delete': 'Marque para eliminar',
-'Checking for upgrades...': 'Buscando actulizaciones...',
-'Clean': 'limpiar',
-'Click row to expand traceback': 'Click row to expand traceback',
-'Client IP': 'IP del Cliente',
-'Compile': 'compilar',
-'Controllers': 'Controladores',
-'Count': 'Count',
-'Create': 'crear',
-'Create new application using the Wizard': 'Create new application using the Wizard',
-'Create new simple application': 'Cree una nueva aplicación',
-'Current request': 'Solicitud en curso',
-'Current response': 'Respuesta en curso',
-'Current session': 'Sesión en curso',
-'DESIGN': 'DISEÑO',
-'Date and Time': 'Fecha y Hora',
-'Delete': 'Elimine',
-'Delete:': 'Elimine:',
-'Deploy on Google App Engine': 'Instale en Google App Engine',
-'Description': 'Descripción',
-'Design for': 'Diseño para',
-'E-mail': 'Correo electrónico',
-'EDIT': 'EDITAR',
-'Edit': 'editar',
-'Edit Profile': 'Editar Perfil',
-'Edit application': 'Editar aplicación',
-'Edit current record': 'Edite el registro actual',
-'Editing Language file': 'Editando archivo de lenguaje',
-'Editing file': 'Editando archivo',
-'Editing file "%s"': 'Editando archivo "%s"',
-'Enterprise Web Framework': 'Armazón Empresarial para Internet',
-'Error': 'Error',
-'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
-'Errors': 'errores',
-'Exception instance attributes': 'Atributos de la instancia de Excepción',
-'File': 'File',
-'First name': 'Nombre',
-'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
-'Group ID': 'ID de Grupo',
-'Hello World': 'Hola Mundo',
-'Help': 'ayuda',
-'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Si el reporte anterior contiene un número de tiquete este indica un falla en la ejecución del controlador, antes de cualquier intento de ejecutat doctests. Esto generalmente se debe a un error en la indentación o un error por fuera del código de la función.\r\nUn titulo verde indica que todas las pruebas pasaron (si existen). En dicho caso los resultados no se muestran.',
-'Import/Export': 'Importar/Exportar',
-'Install': 'instalar',
-'Installed applications': 'Aplicaciones instaladas',
-'Internal State': 'Estado Interno',
-'Invalid Query': 'Consulta inválida',
-'Invalid action': 'Acción inválida',
-'Invalid email': 'Correo inválido',
-'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados',
-'Languages': 'Lenguajes',
-'Last name': 'Apellido',
-'Last saved on:': 'Guardado en:',
-'License for': 'Licencia para',
-'Login': 'Inicio de sesión',
-'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa',
-'Logout': 'fin de sesión',
-'Lost Password': 'Contraseña perdida',
-'Models': 'Modelos',
-'Modules': 'Módulos',
-'NO': 'NO',
-'Name': 'Nombre',
-'New Record': 'Registro nuevo',
-'No databases in this application': 'No hay bases de datos en esta aplicación',
-'Origin': 'Origen',
-'Original/Translation': 'Original/Traducción',
-'Overwrite installed app': 'sobreescriba aplicación instalada',
-'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí',
-'Pack all': 'empaquetar todo',
-'Pack compiled': 'empaquete compiladas',
-'Password': 'Contraseña',
-'Peeking at file': 'Visualizando archivo',
-'Plugin "%s" in application': 'Plugin "%s" en aplicación',
-'Plugins': 'Plugins',
-'Powered by': 'Este sitio usa',
-'Query:': 'Consulta:',
-'Record ID': 'ID de Registro',
-'Register': 'Registrese',
-'Registration key': 'Contraseña de Registro',
-'Remove compiled': 'eliminar compiladas',
-'Resolve Conflict file': 'archivo Resolución de Conflicto',
-'Role': 'Rol',
-'Rows in table': 'Filas en la tabla',
-'Rows selected': 'Filas seleccionadas',
-'Saved file hash:': 'Hash del archivo guardado:',
-'Site': 'sitio',
-'Static files': 'Archivos estáticos',
-'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
-'TM': 'MR',
-'Table name': 'Nombre de la tabla',
-'Testing application': 'Probando aplicación',
-'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
-'There are no controllers': 'No hay controladores',
-'There are no models': 'No hay modelos',
-'There are no modules': 'No hay módulos',
-'There are no static files': 'No hay archivos estáticos',
-'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado',
-'There are no views': 'No hay vistas',
-'This is the %(filename)s template': 'Esta es la plantilla %(filename)s',
-'Ticket': 'Tiquete',
-'Timestamp': 'Timestamp',
-'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]',
-'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones',
-'Unable to download': 'No es posible la descarga',
-'Unable to download app': 'No es posible descargar la aplicación',
-'Unable to download app because:': 'No es posible descargar la aplicación porque:',
-'Unable to download because': 'No es posible descargar porque',
-'Uninstall': 'desinstalar',
-'Update:': 'Actualice:',
-'Upload & install packed application': 'Suba e instale aplicación empaquetada',
-'Upload existing application': 'Suba esta aplicación',
-'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, y ~(...) para NOT, para crear consultas más complejas.',
-'User ID': 'ID de Usuario',
-'Version': 'Versión',
-'Views': 'Vistas',
-'Welcome to web2py': 'Bienvenido a web2py',
-'YES': 'SI',
'additional code for your application': 'código adicional para su aplicación',
+'Additional code for your application': 'Additional code for your application',
'admin disabled because no admin password': ' por falta de contraseña',
'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE',
'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña',
+'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro',
+'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro',
+'Admin language': 'Admin language',
+'administrative interface': 'administrative interface',
+'Administrator Password:': 'Contraseña del Administrador:',
+'An error occured, please %s the page': 'An error occured, please %s the page',
'and rename it (required):': 'y renombrela (requerido):',
'and rename it:': ' y renombrelo:',
'appadmin': 'appadmin',
@@ -158,47 +32,115 @@
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
'application compiled': 'aplicación compilada',
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
+'are not used': 'are not used',
+'are not used yet': 'are not used yet',
+'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?',
+'Are you sure you want to delete plugin "%s"?': '¿Está seguro que quiere eliminar el plugin "%s"?',
+'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
+'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"',
+'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
+'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?',
'arguments': 'argumentos',
+'at char %s': 'at char %s',
+'at line %s': 'at line %s',
+'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.',
+'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.',
+'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que se ejecuta!',
+'Autocomplete': 'Autocomplete',
+'Available databases and tables': 'Bases de datos y tablas disponibles',
'back': 'atrás',
+'breakpoint': 'breakpoint',
+'breakpoints': 'breakpoints',
'browse': 'buscar',
'cache': 'cache',
'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados',
+'Cannot be empty': 'No puede estar vacío',
+'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.',
+'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:',
'cannot create file': 'no es posible crear archivo',
'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"',
+'Change admin password': 'cambie contraseña admin',
+'Change Password': 'Cambie Contraseña',
'check all': 'marcar todos',
+'Check to delete': 'Marque para eliminar',
+'Checking for upgrades...': 'Buscando actulizaciones...',
+'Clean': 'limpiar',
'click here for online examples': 'haga clic aquí para ver ejemplos en línea',
'click here for the administrative interface': 'haga clic aquí para usar la interfaz administrativa',
+'Click row to expand traceback': 'Click row to expand traceback',
'click to check for upgrades': 'haga clic para buscar actualizaciones',
'click to open': 'click to open',
+'Client IP': 'IP del Cliente',
'code': 'código',
+'Code listing': 'Code listing',
+'collapse/expand all': 'collapse/expand all',
'commit (mercurial)': 'commit (mercurial)',
+'Compile': 'compilar',
'compiled application removed': 'aplicación compilada removida',
+'continue': 'continue',
+'Controllers': 'Controladores',
'controllers': 'controladores',
+'Count': 'Count',
+'Create': 'crear',
'create file with filename:': 'cree archivo con nombre:',
+'Create new application using the Wizard': 'Create new application using the Wizard',
'create new application:': 'nombre de la nueva aplicación:',
+'Create new simple application': 'Cree una nueva aplicación',
'created by': 'creado por',
'crontab': 'crontab',
+'Current request': 'Solicitud en curso',
+'Current response': 'Respuesta en curso',
+'Current session': 'Sesión en curso',
'currently saved or': 'actualmente guardado o',
'customize me!': 'Adaptame!',
'data uploaded': 'datos subidos',
'database': 'base de datos',
'database %s select': 'selección en base de datos %s',
'database administration': 'administración base de datos',
+'Date and Time': 'Fecha y Hora',
'db': 'db',
+'Debug': 'Debug',
'defines tables': 'define tablas',
+'Delete': 'Elimine',
'delete': 'eliminar',
'delete all checked': 'eliminar marcados',
'delete plugin': 'eliminar plugin',
+'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)',
+'Delete:': 'Elimine:',
+'Deploy on Google App Engine': 'Instale en Google App Engine',
+'Description': 'Descripción',
'design': 'modificar',
+'DESIGN': 'DISEÑO',
+'Design for': 'Diseño para',
'direction: ltr': 'direction: ltr',
+'docs': 'docs',
'done!': 'listo!',
+'download layouts': 'download layouts',
+'download plugins': 'download plugins',
+'E-mail': 'Correo electrónico',
+'EDIT': 'EDITAR',
+'Edit': 'editar',
+'Edit application': 'Editar aplicación',
'edit controller': 'editar controlador',
+'Edit current record': 'Edite el registro actual',
+'Edit Profile': 'Editar Perfil',
'edit views:': 'editar vistas:',
+'Editing file': 'Editando archivo',
+'Editing file "%s"': 'Editando archivo "%s"',
+'Editing Language file': 'Editando archivo de lenguaje',
+'Enterprise Web Framework': 'Armazón Empresarial para Internet',
+'Error': 'Error',
+'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
+'Errors': 'errores',
+'Exception instance attributes': 'Atributos de la instancia de Excepción',
'export as csv file': 'exportar como archivo CSV',
'exposes': 'expone',
+'exposes:': 'exposes:',
'extends': 'extiende',
+'failed to compile file because:': 'failed to compile file because:',
'failed to reload module': 'recarga del módulo ha fallado',
'failed to reload module because:': 'no es posible recargar el módulo por:',
+'File': 'File',
'file "%(filename)s" created': 'archivo "%(filename)s" creado',
'file "%(filename)s" deleted': 'archivo "%(filename)s" eliminado',
'file "%(filename)s" uploaded': 'archivo "%(filename)s" subido',
@@ -208,76 +150,211 @@
'file does not exist': 'archivo no existe',
'file saved on %(time)s': 'archivo guardado %(time)s',
'file saved on %s': 'archivo guardado %s',
+'filter': 'filter',
+'Find Next': 'Find Next',
+'Find Previous': 'Find Previous',
+'First name': 'Nombre',
+'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
+'Globals##debug': 'Globals',
+'graph model': 'graph model',
+'Group ID': 'ID de Grupo',
+'Hello World': 'Hola Mundo',
+'Help': 'ayuda',
'htmledit': 'htmledit',
+'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Si el reporte anterior contiene un número de tiquete este indica un falla en la ejecución del controlador, antes de cualquier intento de ejecutat doctests. Esto generalmente se debe a un error en la indentación o un error por fuera del código de la función.\r\nUn titulo verde indica que todas las pruebas pasaron (si existen). En dicho caso los resultados no se muestran.',
+'Import/Export': 'Importar/Exportar',
'includes': 'incluye',
'insert new': 'inserte nuevo',
'insert new %s': 'inserte nuevo %s',
+'Install': 'instalar',
+'Installed applications': 'Aplicaciones instaladas',
+'Interaction at %s line %s': 'Interaction at %s line %s',
+'Interactive console': 'Interactive console',
'internal error': 'error interno',
+'Internal State': 'Estado Interno',
+'Invalid action': 'Acción inválida',
+'Invalid email': 'Correo inválido',
'invalid password': 'contraseña inválida',
+'Invalid Query': 'Consulta inválida',
'invalid request': 'solicitud inválida',
'invalid ticket': 'tiquete inválido',
+'Key bindings': 'Key bindings',
'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado',
+'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados',
'languages': 'lenguajes',
+'Languages': 'Lenguajes',
'languages updated': 'lenguajes actualizados',
+'Last name': 'Apellido',
+'Last saved on:': 'Guardado en:',
+'License for': 'Licencia para',
'loading...': 'cargando...',
+'Locals##debug': 'Locals',
+'Login': 'Inicio de sesión',
'login': 'inicio de sesión',
+'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa',
+'Logout': 'fin de sesión',
+'Lost Password': 'Contraseña perdida',
'manage': 'manage',
'merge': 'combinar',
+'Models': 'Modelos',
'models': 'modelos',
+'Modules': 'Módulos',
'modules': 'módulos',
+'Name': 'Nombre',
'new application "%s" created': 'nueva aplicación "%s" creada',
'new plugin installed': 'nuevo plugin instalado',
+'New Record': 'Registro nuevo',
'new record inserted': 'nuevo registro insertado',
+'next': 'next',
'next 100 rows': '100 filas siguientes',
+'NO': 'NO',
+'No databases in this application': 'No hay bases de datos en esta aplicación',
+'No Interaction yet': 'No Interaction yet',
'no match': 'no encontrado',
+'or alternatively': 'or alternatively',
'or import from csv file': 'o importar desde archivo CSV',
'or provide app url:': 'o provea URL de la aplicación:',
'or provide application url:': 'o provea URL de la aplicación:',
+'Origin': 'Origen',
+'Original/Translation': 'Original/Traducción',
+'Overwrite installed app': 'sobreescriba aplicación instalada',
+'Pack all': 'empaquetar todo',
+'Pack compiled': 'empaquete compiladas',
'pack plugin': 'empaquetar plugin',
+'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí',
+'Password': 'Contraseña',
'password changed': 'contraseña cambiada',
+'Peeking at file': 'Visualizando archivo',
+'Please': 'Please',
'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" eliminado',
+'Plugin "%s" in application': 'Plugin "%s" en aplicación',
+'plugins': 'plugins',
+'Plugins': 'Plugins',
+'Plural-Forms:': 'Plural-Forms:',
+'Powered by': 'Este sitio usa',
'previous 100 rows': '100 filas anteriores',
+'Private files': 'Private files',
+'private files': 'private files',
+'Query:': 'Consulta:',
'record': 'registro',
'record does not exist': 'el registro no existe',
'record id': 'id de registro',
+'Record ID': 'ID de Registro',
+'refresh': 'refresh',
+'Register': 'Registrese',
+'Registration key': 'Contraseña de Registro',
+'reload': 'reload',
+'Remove compiled': 'eliminar compiladas',
+'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s',
+'Replace': 'Replace',
+'Replace All': 'Replace All',
+'Resolve Conflict file': 'archivo Resolución de Conflicto',
'restore': 'restaurar',
+'return': 'return',
'revert': 'revertir',
+'Role': 'Rol',
+'Rows in table': 'Filas en la tabla',
+'Rows selected': 'Filas seleccionadas',
+'rules are not defined': 'rules are not defined',
+"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')",
+'Save': 'Save',
'save': 'guardar',
+'Save file:': 'Save file:',
+'Save via Ajax': 'Save via Ajax',
+'Saved file hash:': 'Hash del archivo guardado:',
'selected': 'seleccionado(s)',
'session expired': 'sesión expirada',
+'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s',
'shell': 'shell',
+'Site': 'sitio',
'some files could not be removed': 'algunos archivos no pudieron ser removidos',
+'Start searching': 'Start searching',
'state': 'estado',
'static': 'estáticos',
+'Static': 'Static',
+'Static files': 'Archivos estáticos',
+'step': 'step',
+'stop': 'stop',
'submit': 'enviar',
+'successful': 'successful',
+'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
'table': 'tabla',
+'Table name': 'Nombre de la tabla',
'test': 'probar',
+'Testing application': 'Probando aplicación',
+'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
+'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos',
+'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
+'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas',
+'There are no controllers': 'No hay controladores',
+'There are no models': 'No hay modelos',
+'There are no modules': 'No hay módulos',
+'There are no plugins': 'There are no plugins',
+'There are no private files': 'There are no private files',
+'There are no static files': 'No hay archivos estáticos',
+'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado',
+'There are no views': 'No hay vistas',
+'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app',
+'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí',
+'This is the %(filename)s template': 'Esta es la plantilla %(filename)s',
+'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.',
+'Ticket': 'Tiquete',
+'Timestamp': 'Timestamp',
+'TM': 'MR',
'to previous version.': 'a la versión previa.',
+'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]',
+'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:',
+'to use the debugger!': 'to use the debugger!',
+'toggle breakpoint': 'toggle breakpoint',
+'Toggle Fullscreen': 'Toggle Fullscreen',
'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación',
+'Translation strings for the application': 'Translation strings for the application',
'try': 'intente',
'try something like': 'intente algo como',
+'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.',
+'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones',
'unable to create application "%s"': 'no es posible crear la aplicación "%s"',
'unable to delete file "%(filename)s"': 'no es posible eliminar el archivo "%(filename)s"',
'unable to delete file plugin "%(plugin)s"': 'no es posible eliminar plugin "%(plugin)s"',
+'Unable to download': 'No es posible la descarga',
+'Unable to download app': 'No es posible descargar la aplicación',
+'Unable to download app because:': 'No es posible descargar la aplicación porque:',
+'Unable to download because': 'No es posible descargar porque',
'unable to parse csv file': 'no es posible analizar el archivo CSV',
'unable to uninstall "%s"': 'no es posible instalar "%s"',
'unable to upgrade because "%s"': 'no es posible actualizar porque "%s"',
'uncheck all': 'desmarcar todos',
+'Uninstall': 'desinstalar',
'update': 'actualizar',
'update all languages': 'actualizar todos los lenguajes',
+'Update:': 'Actualice:',
'upgrade web2py now': 'actualize web2py ahora',
+'Upload': 'Upload',
+'Upload & install packed application': 'Suba e instale aplicación empaquetada',
'upload application:': 'subir aplicación:',
+'Upload existing application': 'Suba esta aplicación',
'upload file:': 'suba archivo:',
'upload plugin file:': 'suba archivo de plugin:',
+'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, y ~(...) para NOT, para crear consultas más complejas.',
+'User ID': 'ID de Usuario',
'variables': 'variables',
+'Version': 'Versión',
'versioning': 'versiones',
+'Versioning': 'Versioning',
'view': 'vista',
+'Views': 'Vistas',
'views': 'vistas',
-'web2py Recent Tweets': 'Tweets Recientes de web2py',
'web2py is up to date': 'web2py está actualizado',
+'web2py online debugger': 'web2py online debugger',
+'web2py Recent Tweets': 'Tweets Recientes de web2py',
'web2py upgraded; please restart it': 'web2py actualizado; favor reiniciar',
+'Welcome to web2py': 'Bienvenido a web2py',
+'YES': 'SI',
+'You need to set up and reach a': 'You need to set up and reach a',
+'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)',
+'Your can inspect variables using the console below': 'Your can inspect variables using the console below',
}
diff --git a/applications/admin/static/codemirror/README.md b/applications/admin/static/codemirror/README.md
index 8ed9871a..3e87272f 100644
--- a/applications/admin/static/codemirror/README.md
+++ b/applications/admin/static/codemirror/README.md
@@ -4,5 +4,6 @@ CodeMirror is a JavaScript component that provides a code editor in
the browser. When a mode is available for the language you are coding
in, it will color your code, and optionally help with indentation.
-The project page is http://codemirror.net
-The manual is at http://codemirror.net/doc/manual.html
+The project page is http://codemirror.net
+The manual is at http://codemirror.net/doc/manual.html
+The contributing guidelines are in the CONTRIBUTING.md file
diff --git a/applications/admin/static/codemirror/emmet.min.js b/applications/admin/static/codemirror/emmet.min.js
index 9c84ddcb..96de30b9 100644
--- a/applications/admin/static/codemirror/emmet.min.js
+++ b/applications/admin/static/codemirror/emmet.min.js
@@ -1,284 +1,304 @@
-/* from http://code.google.com/p/zen-coding/ MIT license */
-var _=function(){function h(a,b,d){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a._chain)a=a._wrapped;if(b._chain)b=b._wrapped;if(a.isEqual&&k.isFunction(a.isEqual))return a.isEqual(b);if(b.isEqual&&k.isFunction(b.isEqual))return b.isEqual(a);var c=i.call(a);if(c!=i.call(b))return!1;switch(c){case "[object String]":return a==String(b);case "[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case "[object Date]":case "[object Boolean]":return+a==+b;case "[object RegExp]":return a.source==
-b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return!1;for(var e=d.length;e--;)if(d[e]==a)return!0;d.push(a);var e=0,f=!0;if(c=="[object Array]"){if(e=a.length,f=e==b.length)for(;e--;)if(!(f=e in a==e in b&&h(a[e],b[e],d)))break}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return!1;for(var j in a)if(k.has(a,j)&&(e++,!(f=k.has(b,j)&&h(a[j],b[j],d))))break;if(f){for(j in b)if(k.has(b,j)&&!e--)break;
-f=!e}}d.pop();return f}var e=this,g=e._,f={},c=Array.prototype,b=Object.prototype,a=c.slice,d=c.unshift,i=b.toString,j=b.hasOwnProperty,l=c.forEach,n=c.map,m=c.reduce,o=c.reduceRight,q=c.filter,r=c.every,t=c.some,x=c.indexOf,u=c.lastIndexOf,b=Array.isArray,z=Object.keys,A=Function.prototype.bind,k=function(a){return new B(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=k;exports._=k}else e._=k;k.VERSION="1.3.3";var v=k.each=k.forEach=function(a,
-b,d){if(a!=null)if(l&&a.forEach===l)a.forEach(b,d);else if(a.length===+a.length)for(var c=0,e=a.length;c JavaScript mode supports a single configuration
- option,
+ JavaScript mode supports a two configuration
+ options:
+ \\n\\t in this preference.");
-g.add("insert_formatted_line_break_only",function(c){var b=h("utils"),a=h("resources"),d=h("editorUtils").outputInfo(c),g=c.getCaretPos(),j=b.getNewline();if(e.include(["html","xml","xsl"],d.syntax)){if(a=a.getVariable("indentation"),d=h("html_matcher").getTags(d.content,g,d.profile),d[0]&&d[1]&&d[0].type=="tag"&&d[0].end==g&&d[1].start==g)return c.replaceContent(j+a+b.getCaretPlaceholder()+j,g),!0}else if(d.syntax=="css"&&(d=d.content,g&&d.charAt(g-1)=="{")){var l=f.get("css.closeBraceIndentation"),
-a=a.getVariable("indentation"),n=d.charAt(g)=="}";if(!n)for(var m=g,o=d.length,q;m-bxsh). With this option enabled, you don\u2019t need dashes before abbreviations: Emmet will produce vendor-prefixed properties for you.");
-var r=e.template("A comma-separated list of CSS properties that may have <%= vendor %> vendor prefix. This list is used to generate a list of prefixed properties when expanding -property abbreviations. Empty list means that all possible CSS values may have <%= vendor %> prefix.");e.each({webkit:"animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow",
-moz:"animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow",
-ms:"accelerator, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, overflow-x, overflow-y, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, word-wrap, wrap-flow, wrap-margin, wrap-through, writing-mode, zoom",
+var _=function(){function h(a,b,c){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a._chain)a=a._wrapped;if(b._chain)b=b._wrapped;if(a.isEqual&&k.isFunction(a.isEqual))return a.isEqual(b);if(b.isEqual&&k.isFunction(b.isEqual))return b.isEqual(a);var e=g.call(a);if(e!=g.call(b))return!1;switch(e){case "[object String]":return a==String(b);case "[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case "[object Date]":case "[object Boolean]":return+a==+b;case "[object RegExp]":return a.source==
+b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return!1;for(var d=c.length;d--;)if(c[d]==a)return!0;c.push(a);var d=0,j=!0;if(e=="[object Array]"){if(d=a.length,j=d==b.length)for(;d--;)if(!(j=d in a==d in b&&h(a[d],b[d],c)))break}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return!1;for(var f in a)if(k.has(a,f)&&(d++,!(j=k.has(b,f)&&h(a[f],b[f],c))))break;if(j){for(f in b)if(k.has(b,f)&&!d--)break;
+j=!d}}c.pop();return j}var d=this,f=d._,i={},b=Array.prototype,c=Object.prototype,a=b.slice,e=b.unshift,g=c.toString,j=c.hasOwnProperty,l=b.forEach,m=b.map,n=b.reduce,o=b.reduceRight,q=b.filter,s=b.every,r=b.some,u=b.indexOf,p=b.lastIndexOf,c=Array.isArray,v=Object.keys,w=Function.prototype.bind,k=function(a){return new y(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=k;exports._=k}else d._=k;k.VERSION="1.3.3";var t=k.each=k.forEach=function(a,
+b,c){if(a!=null)if(l&&a.forEach===l)a.forEach(b,c);else if(a.length===+a.length)for(var g=0,e=a.length;g\\n\\t in this preference.");
+f.add("insert_formatted_line_break_only",function(b){var c=h("utils"),a=h("resources"),e=h("editorUtils").outputInfo(b),g=b.getCaretPos(),f=c.getNewline();if(d.include(["html","xml","xsl"],e.syntax)){if(a=a.getVariable("indentation"),(e=h("htmlMatcher").tag(e.content,g))&&!e.innerRange.length())return b.replaceContent(f+a+c.getCaretPlaceholder()+f,g),!0}else if(e.syntax=="css"&&(e=e.content,g&&e.charAt(g-1)=="{")){var l=i.get("css.closeBraceIndentation"),a=a.getVariable("indentation"),m=e.charAt(g)==
+"}";if(!m)for(var n=g,o=e.length,q;n-bxsh). With this option enabled, you don\u2019t need dashes before abbreviations: Emmet will produce vendor-prefixed properties for you.");var v=d.template("A comma-separated list of CSS properties that may have <%= vendor %> vendor prefix. This list is used to generate a list of prefixed properties when expanding -property abbreviations. Empty list means that all possible CSS values may have <%= vendor %> prefix."),
+w=d.template("A comma-separated list of additional CSS properties for css.<%= vendor %>Preperties preference. You should use this list if you want to add or remove a few CSS properties to original set. To add a new property, simply write its name, to remove it, precede property with hyphen.
For example, to add foo property and remove border-radius one, the preference value will look like this: foo, -border-radius.");d.each({webkit:"animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow, box-sizing, border-radius",
+moz:"animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow, background-clip, border-radius",
+ms:"accelerator, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, word-wrap, wrap-flow, wrap-margin, wrap-through, writing-mode",
o:"dashboard-region, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, border-image, link, link-source, object-fit, object-position, tab-size, table-baseline, transform, transform-origin, transition, transition-delay, transition-duration, transition-property, transition-timing-function, accesskey, input-format, input-required, marquee-dir, marquee-loop, marquee-speed, marquee-style"},
-function(a,b){q.define("css."+b+"Properties",a,r({vendor:b}))});q.define("css.unitlessProperties","z-index, line-height, opacity, font-weight","The list of properties whose values \u200b\u200bmust not contain units.");d("w",{prefix:"webkit",supports:q.getArray("css.webkitProperties")});d("m",{prefix:"moz",supports:q.getArray("css.mozProperties")});d("s",{prefix:"ms",supports:q.getArray("css.msProperties")});d("o",{prefix:"o",supports:q.getArray("css.oProperties")});var t=q.getArray("css.unitlessProperties"),
-x=["css","less","sass","scss"];h("resources").addResolver(function(a,b){return e.include(x,b)&&a.isElement()?j.expandToSnippet(a.abbreviation):null});var u=h("expandAbbreviation");u.addHandler(function(a,b,c){if(!e.include(x,b))return!1;var d=a.getSelectionRange().end,f=u.findAbbreviation(a);return f&&(b=emmet.expandAbbreviation(f,b,c))?(f=d-f.length,c=d,a.getContent().charAt(d)==";"&&c++,a.replaceContent(b,f,c),!0):!1});return j={addPrefix:d,supportsPrefix:b,prefixed:function(a,c){return b(a,c)?
-"-"+c+"-"+a:a},listPrefixes:function(){return e.map(n,function(a){return a.prefix})},getPrefix:function(a){return n[a]},removePrefix:function(a){a in n&&delete n[a]},addUnitAlias:function(a,b){m[a]=b},getUnitAlias:function(a){return m[a]},removeUnitAlias:function(a){a in m&&delete m[a]},extractPrefixes:function(a){if(a.charAt(0)!="-")return{property:a,prefixes:null};for(var b=1,c=a.length,d,e=[];bcomment filter is applied. This definition is an ERB-style template passed to _.template() function (see Underscore.js docs for details). In template context, the following properties and functions are availabe:\n
");
-c.define("filter.commentBefore","","A definition of comment that should be placed before matched element when attr(name, before, after) \u2013 a function that outputsspecified attribute value concatenated with before and after strings. If attribute doesn't exists, the empty string will be returned.node \u2013 current node (instance of AbbreviationNode)name \u2013 name of current tagpadding \u2013 current string padding, can be used for formattingcomment filter is applied. For more info, read description of filter.commentAfter property");c.define("filter.commentTrigger","id, class","A comma-separated list of attribute names that should exist in abbreviatoin where comment should be added. If you wish to add comment for every element, set this option to *");h("filters").add("c",function(b){var a=
-e.template(c.get("filter.commentBefore")),d=e.template(c.get("filter.commentAfter"));return f(b,a,d)})});emmet.exec(function(h,e){function g(c){return c.replace(/([<>&])/g,function(b,a){return f[a]})}var f={"<":"<",">":">","&":"&"};h("filters").add("e",function b(a){e.each(a.children,function(a){a.start=g(a.start);a.end=g(a.end);a.content=g(a.content);b(a)});return a})});
-emmet.exec(function(h,e){function g(){return h("resources").getVariable("indentation")}function f(b){return b.parent&&!b.parent.parent&&!b.index()}function c(b,a){var c=h("abbreviationUtils");if(a.tag_nl===!0||c.isBlock(b))return!0;if(!b.parent||!a.inline_break)return!1;var f=0;return!!e.find(b.parent.children,function(b){b.isTextNode()||!c.isInline(b)?f=0:c.isInline(b)&&f++;if(f>=a.inline_break)return!0})}h("filters").add("_format",function a(d,i,j){var j=j||0,l=h("abbreviationUtils");e.each(d.children,
-function(d){if(l.isSnippet(d)){if(!f(d))d.start=h("utils").getNewline()+d.start}else{d.start=d.end="%s";var e=h("utils"),o=h("abbreviationUtils"),q=o.isUnary(d),e=e.getNewline();if(i.tag_nl!==!1){var r=i.tag_nl===!0&&(i.tag_nl_leaf||d.children.length);if(!d.isTextNode()){if(c(d,i)){if(!f(d)&&(!o.isSnippet(d.parent)||d.index()))d.start=e+d.start;if(o.hasBlockChildren(d)||d.children.length&&c(d.children[0],i)||r&&!q)d.end=e+d.end;if(o.hasTagsInContent(d)||r&&!d.children.length&&!q)d.start+=e+g()}else if(o.isInline(d)&&
-d.parent&&h("abbreviationUtils").hasBlockChildren(d.parent)&&!f(d))d.start=e+d.start;else if(o.isInline(d)&&o.hasBlockChildren(d))d.end=e+d.end;d.padding=g()}}}a(d,i,j+1)});return d})});
-emmet.exec(function(h,e){function g(f,c){var b="",a=[],d=c.attributeQuote(),g=c.cursor();e.each(f.attributeList(),function(e){var f=c.attributeName(e.name);switch(f.toLowerCase()){case "id":b+="#"+(e.value||g);break;case "class":b+="."+h("utils").trim(e.value||g).replace(/\s+/g,".");break;default:a.push(":"+f+" => "+d+(e.value||g)+d)}});a.length&&(b+="{"+a.join(", ")+"}");return b}h("filters").add("haml",function c(b,a,d){var d=d||0,i=h("abbreviationUtils");d||(b=h("filters").apply(b,"_format",a));
-e.each(b.children,function(b){if(!i.isSnippet(b)&&b.parent){var e=h("abbreviationUtils"),n=h("utils"),m=g(b,a),o=a.cursor(),e=e.isUnary(b),q=a.self_closing_tag&&e?"/":"",r="",r="%"+a.tagName(b.name());r.toLowerCase()=="%div"&&m&&m.indexOf("{")==-1&&(r="");b.end="";b.start=n.replaceSubstring(b.start,r+m+q+" ",b.start.indexOf("%s"),"%s");!b.children.length&&!e&&(b.start+=o)}c(b,a,d+1)});return b})});
-emmet.exec(function(h,e){function g(f,c){var b=c.attributeQuote(),a=c.cursor();return e.map(f.attributeList(),function(d){return" "+c.attributeName(d.name)+"="+b+(d.value||a)+b}).join("")}h("filters").add("html",function c(b,a,d){var d=d||0,i=h("abbreviationUtils");d||(b=h("filters").apply(b,"_format",a));e.each(b.children,function(b){if(!i.isSnippet(b)&&b.parent){var e=h("abbreviationUtils"),n=h("utils"),m=g(b,a),o=a.cursor(),e=e.isUnary(b),q="",r="";if(!b.isTextNode()){var t=a.tagName(b.name());
-e?(q="<"+t+m+a.selfClosing()+">",b.end=""):(q="<"+t+m+">",r=""+t+">")}b.start=n.replaceSubstring(b.start,q,b.start.indexOf("%s"),"%s");b.end=n.replaceSubstring(b.end,r,b.end.indexOf("%s"),"%s");!b.children.length&&!e&&b.content.indexOf(o)==-1&&(b.start+=o)}c(b,a,d+1)});return b})});
-emmet.exec(function(h,e){var g=/^\s+/,f=/[\n\r]/g;h("filters").add("s",function b(a){var d=h("abbreviationUtils");e.each(a.children,function(a){if(!d.isSnippet(a))a.start=a.start.replace(g,""),a.end=a.end.replace(g,"");a.start=a.start.replace(f,"");a.end=a.end.replace(f,"");a.content=a.content.replace(f,"");b(a)});return a})});
-emmet.exec(function(h,e){function g(f,c){e.each(f.children,function(b){if(b.content)b.content=b.content.replace(c,"");g(b,c)});return f}h("preferences").define("filter.trimRegexp","[\\s|\\u00a0]*[\\d|#|\\-|*|\\u2022]+\\.?\\s*","Regular expression used to remove list markers (numbers, dashes, bullets, etc.) in t (trim) filter. The trim filter is useful for wrapping with abbreviation lists, pased from other documents (for example, Word documents).");h("filters").add("t",function(e){var c=
-RegExp(h("preferences").get("filter.trimRegexp"));return g(e,c)})});emmet.exec(function(h,e){var g={"xsl:variable":1,"xsl:with-param":1};h("filters").add("xsl",function c(b){var a=h("abbreviationUtils");e.each(b.children,function(b){if(!a.isSnippet(b)&&(b.name()||"").toLowerCase()in g&&b.children.length)b.start=b.start.replace(/\s+select\s*=\s*(['"]).*?\1/,"");c(b)});return b})});
-emmet.exec(function(h,e){function g(a,b){return Math.round(Math.random()*(b-a)+a)}function f(a,b){for(var c=a.length,d=Math.min(c,b),f=[];f.lengthalias:unit_value.");p.define("css.color.short",!0,"Should color values like #ffffff be shortened to #fff after abbreviation with color was expanded.");
+p.define("css.color.case","keep","Letter case of color values generated by abbreviations with color (like c#0). Possible values are upper, lower and keep.");p.define("css.fuzzySearch",!0,"Enable fuzzy search among CSS snippet names. When enabled, every unknown snippet will be scored against available snippet names (not values or CSS properties!). The match with best score will be used to resolve snippet value. For example, with this preference enabled, the following abbreviations are equal: ov:h == ov-h == o-h == oh");
+p.define("css.fuzzySearchMinScore",0.3,"The minium score (from 0 to 1) that fuzzy-matched abbreviation should achive. Lower values may produce many false-positive matches, higher values may reduce possible matches.");l("w",{prefix:"webkit"});l("m",{prefix:"moz"});l("s",{prefix:"ms"});l("o",{prefix:"o"});var k=["css","less","sass","scss","stylus"];h("resources").addResolver(function(a,b){return d.include(k,b)&&a.isElement()?q.expandToSnippet(a.abbreviation,b):null});var t=h("expandAbbreviation");t.addHandler(function(a,
+b,c){if(!d.include(k,b))return!1;var e=a.getSelectionRange().end,g=t.findAbbreviation(a);return g&&(b=emmet.expandAbbreviation(g,b,c))?(g=e-g.length,c=e,a.getContent().charAt(e)==";"&&b.charAt(b.length-1)==";"&&c++,a.replaceContent(b,g,c),!0):!1});return q={addPrefix:l,supportsPrefix:g,prefixed:function(a,b){return g(a,b)?"-"+b+"-"+a:a},listPrefixes:function(){return d.map(r,function(a){return a.prefix})},getPrefix:function(a){return r[a]},removePrefix:function(a){a in r&&delete r[a]},extractPrefixes:function(a){if(a.charAt(0)!=
+"-")return{property:a,prefixes:null};for(var b=1,c=a.length,d,e=[];bcomment filter is applied. This definition is an ERB-style template passed to _.template() function (see Underscore.js docs for details). In template context, the following properties and functions are availabe:\n
");
+b.define("filter.commentBefore","","A definition of comment that should be placed before matched element when attr(name, before, after) \u2013 a function that outputsspecified attribute value concatenated with before and after strings. If attribute doesn't exists, the empty string will be returned.node \u2013 current node (instance of AbbreviationNode)name \u2013 name of current tagpadding \u2013 current string padding, can be used for formattingcomment filter is applied. For more info, read description of filter.commentAfter property");b.define("filter.commentTrigger","id, class","A comma-separated list of attribute names that should exist in abbreviatoin where comment should be added. If you wish to add comment for every element, set this option to *");h("filters").add("c",function(c){var a=
+d.template(b.get("filter.commentBefore")),e=d.template(b.get("filter.commentAfter"));return i(c,a,e)})});emmet.exec(function(h,d){function f(b){return b.replace(/([<>&])/g,function(b,a){return i[a]})}var i={"<":"<",">":">","&":"&"};h("filters").add("e",function c(a){d.each(a.children,function(a){a.start=f(a.start);a.end=f(a.end);a.content=f(a.content);c(a)});return a})});
+emmet.exec(function(h,d){function f(){return h("resources").getVariable("indentation")}function i(a){return a.parent&&!a.parent.parent&&!a.index()}function b(a,b){var d=h("abbreviationUtils");return b.tag_nl===!0||d.isBlock(a)?!0:!a.parent||!b.inline_break?!1:c(a.parent,b)}function c(a,b){var c=0,f=h("abbreviationUtils");return!!d.find(a.children,function(a){a.isTextNode()||!f.isInline(a)?c=0:f.isInline(a)&&c++;if(c>=b.inline_break)return!0})}function a(a,b){var f=h("abbreviationUtils");return!d.any(a.children,
+function(a){return f.isSnippet(a)?!1:!f.isInline(a)})?c(a,b):!0}h("filters").add("_format",function g(c,l,m){var m=m||0,n=h("abbreviationUtils");d.each(c.children,function(c){if(n.isSnippet(c)){if(c.start=c.end="",!i(c)&&l.tag_nl!==!1&&b(c,l)&&!h("abbreviationUtils").isInline(c.parent))c.start=h("utils").getNewline()+c.start}else{c.start=c.end="%s";var d=h("utils"),j=h("abbreviationUtils"),r=j.isUnary(c),d=d.getNewline();if(l.tag_nl!==!1){var u=l.tag_nl===!0&&(l.tag_nl_leaf||c.children.length);if(!c.isTextNode()){if(b(c,
+l)){if(!i(c)&&(!j.isSnippet(c.parent)||c.index()))c.start=d+c.start;if(j.hasBlockChildren(c)||c.children.length&&b(c.children[0],l)||u&&!r)c.end=d+c.end;if(j.hasTagsInContent(c)||u&&!c.children.length&&!r)c.start+=d+f()}else if(j.isInline(c)&&c.parent&&h("abbreviationUtils").hasBlockChildren(c.parent)&&!i(c))c.start=d+c.start;else if(j.isInline(c)&&a(c,l))c.end=d+c.end;c.padding=f()}}}g(c,l,m+1)});return c})});
+emmet.exec(function(h,d){function f(f,b){var c="",a=[],e=b.attributeQuote(),g=b.cursor();d.each(f.attributeList(),function(d){var f=b.attributeName(d.name);switch(f.toLowerCase()){case "id":c+="#"+(d.value||g);break;case "class":c+="."+h("utils").trim(d.value||g).replace(/\s+/g,".");break;default:a.push(":"+f+" => "+e+(d.value||g)+e)}});a.length&&(c+="{"+a.join(", ")+"}");return c}h("filters").add("haml",function b(c,a,e){var e=e||0,g=h("abbreviationUtils");e||(c=h("filters").apply(c,"_format",a));
+d.each(c.children,function(c){if(!g.isSnippet(c)&&c.parent){var d=h("abbreviationUtils"),m=h("utils"),n=f(c,a),o=a.cursor(),d=d.isUnary(c),q=a.self_closing_tag&&d?"/":"",s="",s="%"+a.tagName(c.name());s.toLowerCase()=="%div"&&n&&n.indexOf("{")==-1&&(s="");c.end="";c.start=m.replaceSubstring(c.start,s+n+q+" ",c.start.indexOf("%s"),"%s");!c.children.length&&!d&&(c.start+=o)}b(c,a,e+1)});return c})});
+emmet.exec(function(h,d){function f(f,b){var c=b.attributeQuote(),a=b.cursor();return d.map(f.attributeList(),function(d){return" "+b.attributeName(d.name)+"="+c+(d.value||a)+c}).join("")}h("filters").add("html",function b(c,a,e){var e=e||0,g=h("abbreviationUtils");e||(c=h("filters").apply(c,"_format",a));d.each(c.children,function(c){if(!g.isSnippet(c)&&c.parent){var d=h("abbreviationUtils"),m=h("utils"),n=f(c,a),o=a.cursor(),d=d.isUnary(c),q="",s="";if(!c.isTextNode()){var r=a.tagName(c.name());
+d?(q="<"+r+n+a.selfClosing()+">",c.end=""):(q="<"+r+n+">",s=""+r+">")}c.start=m.replaceSubstring(c.start,q,c.start.indexOf("%s"),"%s");c.end=m.replaceSubstring(c.end,s,c.end.indexOf("%s"),"%s");!c.children.length&&!d&&c.content.indexOf(o)==-1&&(c.start+=o)}b(c,a,e+1)});return c})});
+emmet.exec(function(h,d){var f=/^\s+/,i=/[\n\r]/g;h("filters").add("s",function c(a){var e=h("abbreviationUtils");d.each(a.children,function(a){if(!e.isSnippet(a))a.start=a.start.replace(f,""),a.end=a.end.replace(f,"");a.start=a.start.replace(i,"");a.end=a.end.replace(i,"");a.content=a.content.replace(i,"");c(a)});return a})});
+emmet.exec(function(h,d){function f(h,b){d.each(h.children,function(c){if(c.content)c.content=c.content.replace(b,"");f(c,b)});return h}h("preferences").define("filter.trimRegexp","[\\s|\\u00a0]*[\\d|#|\\-|*|\\u2022]+\\.?\\s*","Regular expression used to remove list markers (numbers, dashes, bullets, etc.) in t (trim) filter. The trim filter is useful for wrapping with abbreviation lists, pased from other documents (for example, Word documents).");h("filters").add("t",function(d){var b=
+RegExp(h("preferences").get("filter.trimRegexp"));return f(d,b)})});emmet.exec(function(h,d){var f={"xsl:variable":1,"xsl:with-param":1};h("filters").add("xsl",function b(c){var a=h("abbreviationUtils");d.each(c.children,function(c){if(!a.isSnippet(c)&&(c.name()||"").toLowerCase()in f&&c.children.length)c.start=c.start.replace(/\s+select\s*=\s*(['"]).*?\1/,"");b(c)});return c})});
+emmet.exec(function(h,d){function f(a,b){return Math.round(Math.random()*(b-a)+a)}function i(a,b){for(var c=a.length,e=Math.min(c,b),h=[];h.length
");
+ node.appendChild(document.createElement("br"));
col = 0;
return;
}
- var escaped = "";
- // HTML-escape and replace tabs
+ var content = "";
+ // replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
- escaped += esc(text.slice(pos));
+ content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
- escaped += esc(text.slice(pos, idx));
+ content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
- for (var i = 0; i < size; ++i) escaped += " ";
+ for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
- if (style)
- accum.push("" + escaped + "");
- else
- accum.push(escaped);
+ if (style) {
+ var sp = node.appendChild(document.createElement("span"));
+ sp.className = "cm-" + style.replace(/ +/g, " cm-");
+ sp.appendChild(document.createTextNode(content));
+ } else {
+ node.appendChild(document.createTextNode(content));
+ }
};
}
+
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
@@ -48,6 +49,4 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
stream.start = stream.pos;
}
}
- if (isNode)
- node.innerHTML = accum.join("");
};
diff --git a/applications/admin/static/codemirror/lib/util/search.js b/applications/admin/static/codemirror/lib/util/search.js
index 356283ab..266b2c92 100644
--- a/applications/admin/static/codemirror/lib/util/search.js
+++ b/applications/admin/static/codemirror/lib/util/search.js
@@ -41,7 +41,8 @@
state.query = parseQuery(query);
if (cm.lineCount() < 2000) { // This is too expensive on big documents.
for (var cursor = getSearchCursor(cm, state.query); cursor.findNext();)
- state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching"));
+ state.marked.push(cm.markText(cursor.from(), cursor.to(),
+ {className: "CodeMirror-searching"}));
}
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
@@ -76,14 +77,14 @@
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
if (all) {
- cm.compoundChange(function() { cm.operation(function() {
+ cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
- cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
+ cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
- });});
+ });
} else {
clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor());
@@ -100,7 +101,7 @@
}
function doReplace(match) {
cursor.replace(typeof query == "string" ? text :
- text.replace(/\$(\d)/, function(w, i) {return match[i];}));
+ text.replace(/\$(\d)/, function(_, i) {return match[i];}));
advance();
}
advance();
diff --git a/applications/admin/static/codemirror/lib/util/searchcursor.js b/applications/admin/static/codemirror/lib/util/searchcursor.js
index 970af899..58fed74d 100644
--- a/applications/admin/static/codemirror/lib/util/searchcursor.js
+++ b/applications/admin/static/codemirror/lib/util/searchcursor.js
@@ -17,14 +17,14 @@
query.lastIndex = 0;
var line = cm.getLine(pos.line).slice(0, pos.ch), match = query.exec(line), start = 0;
while (match) {
- start += match.index;
- line = line.slice(match.index);
+ start += match.index + 1;
+ line = line.slice(start);
query.lastIndex = 0;
var newmatch = query.exec(line);
if (newmatch) match = newmatch;
else break;
- start++;
}
+ start--;
} else {
query.lastIndex = pos.ch;
var line = cm.getLine(pos.line), match = query.exec(line),
diff --git a/applications/admin/static/codemirror/lib/util/simple-hint.js b/applications/admin/static/codemirror/lib/util/simple-hint.js
index 8e481c37..1565bd47 100644
--- a/applications/admin/static/codemirror/lib/util/simple-hint.js
+++ b/applications/admin/static/codemirror/lib/util/simple-hint.js
@@ -14,18 +14,21 @@
// Don't show completions if token has changed and the option is set.
if (options.closeOnTokenChange && previousToken != null &&
- (tempToken.start != previousToken.start || tempToken.className != previousToken.className)) {
+ (tempToken.start != previousToken.start || tempToken.type != previousToken.type)) {
return;
}
- var result = getHints(editor);
+ var result = getHints(editor, givenOptions);
if (!result || !result.list.length) return;
var completions = result.list;
function insert(str) {
editor.replaceRange(str, result.from, result.to);
}
// When there is only one completion, use it directly.
- if (completions.length == 1) {insert(completions[0]); return true;}
+ if (options.completeSingle && completions.length == 1) {
+ insert(completions[0]);
+ return true;
+ }
// Build the select widget
var complete = document.createElement("div");
@@ -41,14 +44,14 @@
}
sel.firstChild.selected = true;
sel.size = Math.min(10, completions.length);
- var pos = editor.cursorCoords();
- complete.style.left = pos.x + "px";
- complete.style.top = pos.yBot + "px";
+ var pos = editor.cursorCoords(options.alignWithWord ? result.from : null);
+ complete.style.left = pos.left + "px";
+ complete.style.top = pos.bottom + "px";
document.body.appendChild(complete);
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
- if(winW - pos.x < sel.clientWidth)
- complete.style.left = (pos.x - sel.clientWidth) + "px";
+ if(winW - pos.left < sel.clientWidth)
+ complete.style.left = (pos.left - sel.clientWidth) + "px";
// Hack to hide the scrollbar.
if (completions.length <= 10)
complete.style.width = (sel.clientWidth - 1) + "px";
@@ -64,14 +67,14 @@
close();
setTimeout(function(){editor.focus();}, 50);
}
- CodeMirror.connect(sel, "blur", close);
- CodeMirror.connect(sel, "keydown", function(event) {
+ CodeMirror.on(sel, "blur", close);
+ CodeMirror.on(sel, "keydown", function(event) {
var code = event.keyCode;
// Enter
if (code == 13) {CodeMirror.e_stop(event); pick();}
// Escape
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
- else if (code != 38 && code != 40) {
+ else if (code != 38 && code != 40 && code != 33 && code != 34 && !CodeMirror.isModifierKey(event)) {
close(); editor.focus();
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
editor.triggerOnKeyDown(event);
@@ -81,7 +84,7 @@
}
}
});
- CodeMirror.connect(sel, "dblclick", pick);
+ CodeMirror.on(sel, "dblclick", pick);
sel.focus();
// Opera sometimes ignores focusing a freshly created node
@@ -92,6 +95,8 @@
};
CodeMirror.simpleHint.defaults = {
closeOnBackspace: true,
- closeOnTokenChange: false
+ closeOnTokenChange: false,
+ completeSingle: true,
+ alignWithWord: true
};
})();
diff --git a/applications/admin/static/codemirror/lib/util/xml-hint.js b/applications/admin/static/codemirror/lib/util/xml-hint.js
index 816e3b4a..e9ec6b7f 100644
--- a/applications/admin/static/codemirror/lib/util/xml-hint.js
+++ b/applications/admin/static/codemirror/lib/util/xml-hint.js
@@ -12,13 +12,7 @@
cm.setCursor(cursor);
}
- // dirty hack for simple-hint to receive getHint event on space
- var getTokenAt = editor.getTokenAt;
-
- editor.getTokenAt = function() { return 'disabled'; };
CodeMirror.simpleHint(cm, getHint);
-
- editor.getTokenAt = getTokenAt;
};
var getHint = function(cm) {
@@ -42,7 +36,7 @@
text = text.slice(0, text.length - typed.length);
- var path = getActiveElement(cm, text) + simbol;
+ var path = getActiveElement(text) + simbol;
var hints = CodeMirror.xmlHints[path];
if(typeof hints === 'undefined')
@@ -63,7 +57,7 @@
};
};
- var getActiveElement = function(codeMirror, text) {
+ var getActiveElement = function(text) {
var element = '';
diff --git a/applications/admin/static/codemirror/mode/clike/clike.js b/applications/admin/static/codemirror/mode/clike/clike.js
index 59555e94..4d1484a7 100644
--- a/applications/admin/static/codemirror/mode/clike/clike.js
+++ b/applications/admin/static/codemirror/mode/clike/clike.js
@@ -1,5 +1,6 @@
CodeMirror.defineMode("clike", function(config, parserConfig) {
var indentUnit = config.indentUnit,
+ statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
keywords = parserConfig.keywords || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
@@ -89,7 +90,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
this.prev = prev;
}
function pushContext(state, col, type) {
- return state.context = new Context(state.indented, col, type, null, state.context);
+ var indent = state.indented;
+ if (state.context && state.context.type == "statement")
+ indent = state.context.indented;
+ return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
@@ -123,7 +127,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
- if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
+ if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
@@ -133,18 +137,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
- else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
+ else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},
indent: function(state, textAfter) {
- if (state.tokenize != tokenBase && state.tokenize != null) return 0;
+ if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
- if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
+ if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},
@@ -165,7 +169,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
function cppHook(stream, state) {
if (!state.startOfLine) return false;
- stream.skipToEnd();
+ for (;;) {
+ if (stream.skipTo("\\")) {
+ stream.next();
+ if (stream.eol()) {
+ state.tokenize = cppHook;
+ break;
+ }
+ } else {
+ stream.skipToEnd();
+ state.tokenize = null;
+ break;
+ }
+ }
return "meta";
}
@@ -212,7 +228,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
blockKeywords: words("catch class do else finally for if switch try while"),
atoms: words("true false null"),
hooks: {
- "@": function(stream, state) {
+ "@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}
@@ -275,7 +291,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
blockKeywords: words("catch class do else finally for forSome if match switch try while"),
atoms: words("true false null"),
hooks: {
- "@": function(stream, state) {
+ "@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}
diff --git a/applications/admin/static/codemirror/mode/clike/index.html b/applications/admin/static/codemirror/mode/clike/index.html
index 90a5fc10..ca10c4bc 100644
--- a/applications/admin/static/codemirror/mode/clike/index.html
+++ b/applications/admin/static/codemirror/mode/clike/index.html
@@ -5,6 +5,7 @@
json, which will set the mode to expect JSON
- data rather than a JavaScript program.
+
+ json which will set the mode to expect JSON data rather than a JavaScript program.typescript which will activate additional syntax highlighting and some other things for TypeScript code (demo).
+
MIME types defined: text/javascript, application/json.
MIME types defined: text/javascript, application/json, text/typescript, application/typescript.